Verilog Práctico
Capítulo 3. Prescaler y contadores.
En este capítulo veremos dos elementos muy útiles, el contador y el prescaler. El primer elemento intuimos para qué sirve, el segundo se utiliza para dividir la frecuencia del reloj del sistema en frecuencias menores.
1. Prescaler
1.1 Prescaler de 8 bits.
Tenemos una entrada clk que es el reloj del sistema y un registro de salida de 8 bits que llamamos cont y que declaramos así: output reg [7:0] cont. Podemos hacer el símil de que un registro es un bus de datos.
Cuando declaramos una salida como un registro quiere decir que ese registro almacena bits, sin embargo cuando declaramos con wire lo que hacemos es conectar entradas y salidas; wire no almacena el valor de ningún bit.
El código para el prescaler de 8 bits es el siguiente:
//-- prescaler 8 bits
//-- clk - reloj del sistema
//-- reg [7:0] cont - registro de salida de 8 bits
module prescaler(input clk, output reg [7:0] cont);
wire clk;
//-- con cada flanco de subida del reloj, se incrementa el contador
always @(posedge clk) begin
cont <= cont + 1;
end
endmodule
Asignamos del pin 21 a la señal clk, porque en el pinout de la Alhambra vemos que el reloj del sistema es el pin 21. A cada uno de los 8 bits del registro cont le asignamos un led en la Alhambra. El número entre corchetes cont[X] es cada uno de los bits del registro.
El archivo pcf queda así:
set_io clk 21
set_io cont[7] 95
set_io cont[6] 96
set_io cont[5] 97
set_io cont[4] 98
set_io cont[3] 99
set_io cont[2] 101
set_io cont[1] 102
set_io cont[0] 104
Lo compilamos y subimos a la Alhambra y lo que vemos son los 8 ledes encendidos.
¿Qué ha pasado? Lo que sucede es que como el reloj del sistema es de 12 MHz el contador se incrementa tan deprisa que los ledes aparecen siempre encendidos.
1.2 Prescaler de 24 bits
Para ver la diferencia vamos a hacer un prescaler de 24 bits y sacaremos por los ledes, los 8 bits más significativos.
Declaramos como salidas los 8 ledes de la Alhambra dentro de module prescaler()
output led0, led1, led2, led3, led4, led5, led6, led7
Declaramos un contador de 24 bits
reg [23:0] cont;
Asignamos a cada uno de los ledes, un bit del registro cont
assign ledX = cont [XX];
Lo ponemos todo junto y el código queda así:
//-- prescaler 24 bits
//-- clk - reloj del sistema
module prescaler(input clk, output led0, led1, led2, led3, led4, led5, led6, led7);
wire clk;
wire led0, led1, led2, led3, led4, led5, led6, led7;
reg [23:0] cont;
assign led0 = cont [23];
assign led1 = cont [22];
assign led2 = cont [21];
assign led3 = cont [20];
assign led4 = cont [19];
assign led5 = cont [18];
assign led6 = cont [17];
assign led7 = cont [16];
//-- con cada flanco de subida del reloj, se incrementa el contador
always @(posedge clk) begin
cont <= cont + 1;
end
endmodule
Archivo pcf con asignación de E/S:
set_io clk 21
set_io led0 95
set_io led1 96
set_io led2 97
set_io led3 98
set_io led4 99
set_io led5 101
set_io led6 102
set_io led7 104
Lo subimos a la Alhambra y vemos parpadear los 6 bits más significativos. ¡Hemos dividido las frecuencias hasta hacerlas visibles al ojo humano!
Sigue leyendo para ver un ejemplo de aplicación.
2. Contadores
Como su nombre indica los contadores sirven para contar eventos.
En los siguientes ejemplos veremos dos contadores, el primero de 4 bits que se incrementa de manera manual cada vez que pulsamos el SW1 de la Alhambra. El segundo contador -de 8 bits- se incrementa de manera automática, con una tasa que seleccionamos mediante un prescaler como los que hemos visto más arriba.
2.1 Contador de 4 bits.
// contador manual de 4 bits por flanco de SW1
module counter(input SW1, output reg [3:0] counter);
always @(posedge SW1)
begin
counter <= counter + 1;
end
endmodule
El archivo pcf asociado es:
set_io SW1 10
set_io counter[3] 95
set_io counter[2] 96
set_io counter[1] 97
set_io counter[0] 98
Lo subimos a la Alhambra y con cada pulsación de SW1 vemos como se incrementa el contador. El resultado se muestra en los ledes 0 a 3.
2.2. Contador automático de 8 bits.
Cómo hacer un contador automático de 8 bits. La frecuencia de refresco la seleccionaremos mediante el uso de un prescaler.
Declaramos la entrada de reloj y el contador de 8 bits como salida, para ver su valor en los 8 ledes de la Alhambra.
module counter(input clk, output reg [7:0] counter);
Declaramos los relojes clk y clk_cont y un registro de 24 bits para el prescaler.
wire clk; // reloj del sistema
wire clk_cont; // reloj auxiliar para el contador
reg [23:0] prescaler = 0; // registro prescaler inicializado a 0
Asignamos la frecuencia de refresco al bit 17 del prescaler.
assign clk_cont = prescaler[17];
El registro prescaler se incrementa con cada flanco del reloj del sistema.
always @(posedge clk)
begin
prescaler <= prescaler + 1;
end
Sin embargo el contador se incrementa con cada flanco de clk_cont.
always @(posedge clk_cont)
begin
counter <= counter + 1;
end
endmodule
Lo ponemos todo junto y el código queda así:
// contador automatico de 8 bits con prescaler
module counter(input clk, output reg [7:0] counter);
wire clk;
wire clk_cont; // reloj auxiliar para el contador
reg [24:0] prescaler = 0; // registro prescaler
// asignamos la frecuencia de refresco al bit 17 del prescaler
assign clk_cont = prescaler[17];
// el registro prescaler se incrementa con cada flanco del reloj del sistema
always @(posedge clk)
begin
prescaler <= prescaler + 1;
end
/*
el contador se incrementa con cada flanco de clk_cont
que equivale al bit 17 del prescaler
*/
always @(posedge clk_cont)
begin
counter <= counter + 1;
end
endmodule
El archivo pfc queda así:
set_io clk 21
set_io counter[7] 95
set_io counter[6] 96
set_io counter[5] 97
set_io counter[4] 98
set_io counter[3] 99
set_io counter[2] 101
set_io counter[1] 102
set_io counter[0] 104
Lo compilamos y subimos a la Alhambra. Vemos como el contador se incrementa de manera automática. Podemos seleccionar la velocidad tan solo modificando el bit que asignamos al reloj auxiliar en assign clk_cont = prescaler[17];
Eso es todo, espero que os haya gustado.
¡Hasta la próxima!
Links
Open FPGA Verilog tutorial. Capítulo 5: Prescaler de N bits
Open FPGA Verilog tutorial. Capítulo 4: Contador de 26 bits