Skip to content

Capítulo 13: Inicializando registros

Juan Gonzalez-Gomez edited this page Aug 22, 2015 · 24 revisions

Ejemplos de este capítulo en github

Introducción

Ya podemos responder a la pregunta planteada en el capítulo 8 sobre cómo realizar la inicialización de los registros. Los registros sintetizados están a 0. Normalmente necesitamos cargar en ellos un valor inicial, y que luego funcionen para lo que hayan sido diseñados. En este capítulo mostraremos cómo hacerlo, usando las herramientas que ya conocemos: el multiplexor y el inicializador

Inicializando registros

Partimos de un registro genérico de N bits, que ya conocemos, con una entrada din, una salida dout y una señal de reloj

Queremos que se cargue con un valor inicial al principio y que luego funcione normalmente. Para hacerlo colocamos un multiplexor de 2 a 1 en su entrada (para dividir la entrada en 2). Por una entrada del multiplexor ponemos el valor inicial y por la otra la entrada genérica del registro din2.

Es muy importante que el valor inicial se introduzca por la fuente 0 del multiplexor.

Ahora ya simplemente conectamos un inicializador a la entrada de selección del multiplexor.

De esta forma, al arrancar, el inicializador emitirá un 0 y por la entrada din del registro llegará el valor inicial. En el siguiente franco de subida este valor inicial se captura y el inicializador pasa a 1, por lo que ahora se seleccionará la fuente 1, que será por donde vengan los datos del registro en el régimen normal de funcionamiento

reginit.v: Secuenciador de 2 estados con registro

Vamos a reacer el circuito blink4 del capítulo 8. Este circuito hacía parpadear los 4 leds a la vez, produciendo la secuencia: 0000, 1111, 0000 ...

Imagen 3

Ahora lo vamos a mejorar haciendo que se pueda poner cualquier valor inicial en el registro, lográndose la secuencia INI, ~INI, INI ... (valor inicial y su negado alternativamente):

La descripción de este circuito en Verilog es:

//-- reginit.v module reginit(input wire clk, output wire [3:0] data);

//-- Parametros del secuenciador: parameter NP = 23; //-- Bits del prescaler parameter INI = 4'b1100; //-- Valor inicial a cargar en registro

//-- Reloj a la salida del presacaler wire clk_pres;

//-- Salida del regitro reg [3:0] dout;

//-- Entrada del registro wire [3:0] din;

//-- Señal de seleccion del multiplexor reg sel = 0;

//-- Registro always @(posedge(clk_pres)) dout <= din;

//-- Conectar el registro con la salida assign data = dout;

//-- Multiplexor de inicializacion assign din = (sel == 0) ? INI : ~dout;

//-- Inicializador always @(posedge(clk_pres)) sel <= 1;

//-- Prescaler prescaler #(.N(NP)) PRES ( .clk_in(clk), .clk_out(clk_pres) );

endmodule

El multiplexor de 2 a 1 ha implementado usando el operador ? : (similar al del lenguaje C). Es un if-else abreviado:

assign din = (sel == 0) ? INI : ~dout;

Es equivalente a:

always @* if (sel == 0) din <= INI; else din <= ~dout;

pero la primera notación es más compacta

Síntesis en la FPGA

Clone this wiki locally