-
Notifications
You must be signed in to change notification settings - Fork 196
Capítulo 14: Registro de N bits con reset síncrono
Ejemplos de este capítulo en github
Los registros son elementos muy usados para hacer circuitos digitales. Aunque su descripción en verilog es muy sencilla, crearemos un registro genérico de N bits que podremos instanciar en nuestros diseños. Esto nos permitirá colocar muchos registros fácilmente. Además, añadiremos una entrada de reset síncrona que cargará el registro con un valor inicial (Por defecto será 0 pero podremos indicar otro valor al instanciar el registro). Como ejemplo haremos un secuenciador con 2 registros, sacándose por los leds los datos almacenados en ellos, alternativamente.
El esquema del registro es el mostrado en la siguiente figura:
Tiene una entrada de datos din de N bits, y su salida dout correspondiente. Los datos se capturan en flanco de subida de la señal de reloj. Dispone de una entrada de reset síncrona activa a nivel bajo: Si se recibe un 0 por esta señal y llega un flanco de reloj, el registro se carga con su valor inicial (INI), que se define al instanciarlo.
Esta manera de inicilizar el registro ya la conocemos del capítulo anterior, pero ahora se ha integrado dentro del propio registro. Su descripción en Verilog es la siguiente:
//-- register.v
module register (rst, clk, din, dout);
//-- Parametros:
parameter N = 4; //-- Número de bits del registro
parameter INI = 0; //-- Valor inicial
//-- Declaración de los puertos
input wire rst;
input wire clk;
input wire [N-1:0] din;
output reg [N-1:0] dout;
//-- Registro
always @(posedge(clk))
if (rst == 0)
dout <= INI; //-- Inicializacion
else
dout <= din; //-- Funcionamiento normal
endmodule
Esto es equivalente a la implementación en el capítulo anterior, donde usábamos dos procesos: uno para el multiplexor y otro para el registro. Aquí están los dos componentes dentro del mismo proceso. Es la forma típica de implementar un registro con inicialización.
Como ejemplo de prueba vamos a implementar un secuenciador de 2 estados, usando 2 registros. Cada uno almacena inicialmente el valor a mostrar en los leds en cada estado. Los registros están encadenados, de manera que la salida de uno se conecta a la entrada del otro. De esta forma, cada vez que llega un flanco de subida de reloj, los registros intercambian sus valores. La salida de uno de ellos está conectada a los leds.
La salida del registro 0 sale al exterior (puerto data) pero también se envía a la entrada del registro 1, cuya salida está conectada a la del registro 0.
En las entradas de reset de los registros se ha colocado un inicializador que general la señal escalón para realizar la carga inicial en el primer flanco de subida del reloj. Los cables de reset han dibujado en rojos en la figura. En el resto de ciclos funcionan como registros normales, cargando lo que les llega por su entradas din.
El reloj (cables en verde) se pasa a través de un prescaler y se introduce tanto en los registros como en el inicializador.
El código Verilog es el siguiente:
//-- regreset.v
module regreset(input wire clk, output wire [3:0] data);
//-- Parametros del secuenciador:
parameter NP = 23; //-- Bits del prescaler
parameter INI0 = 4'b1001; //-- Valor inicial para el registro 0
parameter INI1 = 4'b0111; //-- Valor inicial para el registro 1
//-- Reloj a la salida del presacaler
wire clk_pres;
//-- Salida de los regitros
wire [3:0] dout0;
wire [3:0] dout1;
//-- Señal de inicializacion del reset
reg rst = 0;
//-- Inicializador
always @(posedge(clk_pres))
rst <= 1;
//-- Registro 0
register #(.INI(INI0))
REG0 (
.clk(clk_pres),
.rst(rst),
.din(dout1),
.dout(dout0)
);
//-- Registro 1
register #(.INI(INI1))
REG1 (
.clk(clk_pres),
.rst(rst),
.din(dout0),
.dout(dout1)
);
//-- Sacar la salida del registro 0 por la del componente
assign data = dout0;
//-- Prescaler
prescaler #(.N(NP))
PRES (
.clk_in(clk),
.clk_out(clk_pres)
);
endmodule
Para sintetizarlo en la fpga conectaremos las salidas data a los leds, y la entrada de reloj a la de la placa iCEstick
Sintetizamos con el comando:
$ make sint
Los recursos empleados son:
Recurso | ocupación |
---|---|
PIOs | 5 / 96 |
PLBs | 11 / 160 |
BRAMs | 0 / 16 |
Para cargar en la FPGA ejecutamos:
$ sudo iceprog regreset.bin
Estos son los valores que se visualizan en los leds alternativamente:
Valor 1 | Valor 2 |
---|---|
En este vídeo de Youtube se puede ver la salida de los leds:
El banco de pruebas es uno básico, que instancia el componente regreset, con 1 bit para el prescaler (para que la simulación tarde menos). Tiene un proceso para la señal de reloj y uno para la inicialización de la simulación
El código verilog es:
//-- regreset_tb.v
module regreset_tb();
//-- Registro para generar la señal de reloj
reg clk = 0;
//-- Datos de salida del componente
wire [3:0] data;
//-- Instanciar el componente, con prescaler de 1 bit (para la simulacion)
regreset #(.NP(1))
dut(
.clk(clk),
.data(data)
);
//-- Generador de reloj. Periodo 2 unidades
always #1 clk = ~clk;
//-- Proceso al inicio
initial begin
//-- Fichero donde almacenar los resultados
$dumpfile("regreset_tb.vcd");
$dumpvars(0, regreset_tb);
# 30 $display("FIN de la simulacion");
$finish;
end
endmodule
La simulación se realiza con:
$ make sim
El resultado en gtkwave es:
Se puede ver cómo la secuencia 1001, 0111, 1001, 0111... se va alternando.
- Ejercicio 1: Modificar el diseño para añadir 2 registros más y hacer que el secuenciador tenga 4 estados
TODO
0 You are leaving the privative sector (EN)
1 ¡Hola mundo! (EN) (RU)
2 De un bit a datos (EN)
3 Puerta NOT (EN)
4 Contador de 26 bits (EN)
5 Prescaler de N bits (EN)
6 Múltiples prescalers (EN)
7 Contador de 4 bits con prescaler (EN)
8 Registro de 4 bits (EN)
9 Inicializador (EN)
10 Registro de desplazamiento (EN)
11 Multiplexor de 2 a 1 (EN)
12 Multiplexor de M a 1 (EN)
13 Inicializando registros (EN)
14 Registro de N bits con reset síncrono
15 Divisor de frecuencias
16 Contador de segundos
17 Generando tonos audibles
18 Tocando notas
19 Secuenciando notas
20 Comunicaciones serie asíncronas
21 Baudios y transmisión
22 Reglas de diseño síncrono
23 Controladores y autómatas finitos
24 Unidad de transmisión serie asíncrona
25 Unidad de recepción serie asíncrona
26 Memoria ROM
27 Memoria ROM genérica
28 Memoria RAM
29 Puertas triestado
30 Hacia el microprocesador y más allá