Nothing Special   »   [go: up one dir, main page]

Registros y Contadores PDF

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 4

La figura 1 muestra una síntesis posible del registro.

SÍNTESIS DE MÓDULOS SECUENCIALES

La síntesis de módulos secuenciales puede materializarse de forma directa a partir de descripciones RTL o
comportamental de los módulos secuenciales tradicionalmente conocidos, como son registros, registros de
desplazamiento, contadores, monoestables, LFSR, etc.
En este capítulo, a partir de los elementos descriptivos del VHDL ya introducidos en capítulos anteriores se
van a realizar diversas implementaciones de los módulos secuenciales más conocidos. Cada módulo se
modelará mediante una o varias descripciones. Como se observará, la descripción de los modelos a partir del
VHDL simplifica enormemente la síntesis de sistemas digitales.

Registro
El registro es un módulo secuencial capaz de almacenar un conjunto de datos que son cargados a partir de
una señal de carga o load. Los datos que se cargan en el registro provienen del bus externo de datos d. Puesto Figura 1. Registro.
que el registro contiene un conjunto de flip-flops, su estado viene dado directamente por los datos que
La figura 2 muestra la simulación temporal del registro.
almacena y se visualiza al exterior a través del bus de salida q.
El registro suele contener también una señal de reset o preset asíncrona que inicializa el registro a 0 o 1. Por
consiguiente, su tabla de estados puede describirse de la forma siguiente:
Estado actual (q) Próximo estado (Q)
nreset = 0 - 0
load = 0 y ck ↑ q q
load = 1 y ck ↑ q d
Tabla 1. Tabla de estados del registro. Figura 2. Gráfica termporal del registro.
Su funcionamiento es simple y, como tal, puede considerarse como el módulo punto de partida para la
construcción del resto de módulos secuenciales. Registro de desplazamiento.
La descripción VHDL, a nivel comportamental, es trivial a partir de la tabla 3. El registro de desplazamiento, además del almacenamiento de datos propio del registro, es capaz de
establecer comunicación entre los elementos (flip-flops) vecinos permitiendo el transporte de datos (de forma
Library ieee; serie) a derecha e izquierda del registro. Por consiguiente, las operaciones que un registro de desplazamiento
Use ieee.std_logic_1164.ALL; puede contener son: inicialización, carga de datos, desplazamiento a la derecha, desplazamiento a la
Entity Registro is izquierda y no operación.
generic (N:integer := 4);
Todas las operaciones, excepto la de inicialización asíncrona, pueden estar controladas a través de una señal
port ( d: in std_logic_vector(N-1 downto 0);
de control, ctrl, de dos bits.
ck, nreset, load: in std_logic;
q: out std_logic_vector(N-1 downto 0));
La tabla 2 muestra la tabla de estados del registro de desplazamiento. Para los desplazamientos a derecha e
izquierda se necesita, además, una señal de entrada serie por la izquierda, il, y otra por la derecha, ir,
end;
respectivamente.
architecture bhr of Registro is
begin Estado actual (q) Próximo estado
process (ck, nreset) (Q)

begin Inicialización nreset = 0 - 0


if nreset='0' then q <= (others => '0'); No operación ctrl = 00 y ck ↑ q q
else if ck'event and ck='1' then Carga ctrl = 01 y ck ↑ q d
if load = '1' then Desplazamiento a derecha ctrl = 10 y ck ↑ (qn-1, ..., q0) (il, qn-1, ..., q1)
q <= d; Desplazamiento a izquierda ctrl = 11 y ck ↑ (qn-1, ..., q0) (qn-2, ..., q0, ir)
end if; Nota: Se considera qn-1 como el bit más significativo (izquierda) y q0 como el menos significativo (derecha).
end if; Tabla 2. Tabla de estados del registro.
end if;
A partir de la descripción de la tabla de estados del registro de desplazamiento es fácil comprender la
end process; descripción VHDL. La descripción se ha realizado de forma genérica y se ha implementado para n=4 (bus de
end; 4 datos). Se puede observar cuán fácil es implementar los distintos modos de funcionamiento del registro de
desplazamiento utilizando la instrucción case-when. Además se ha aprovechado la intrucción when others
=> NULL para implementar el modo Noop del registro de desplazamiento.
-- Registro de desplazamiento
Library ieee;
Use ieee.std_logic_1164.ALL;
Entity sr is
generic (N:integer := 4);
port ( ck, nreset, ir, il: in std_logic;
ctrl: in std_logic_vector(1 downto 0);
d: in std_logic_vector(N-1 downto 0); Figura 4. Diagrama temporal del registro de desplazamiento.
q: inout std_logic_vector(N-1 downto 0));
end; Contador.
architecture bhr of sr is
Un contador es un circuito secuencial capaz de seguir una secuencia completa de estados y que no pasa por
begin
un mismo estado por segunda vez hasta que se han sucedido todos los demás.
process (ck, nreset)
begin La clasificación de contadores puede realizarse por la forma de contar y por el código que utiliza en el conteo.
if nreset='0' then q <= (others => '0'); Por la forma de contar tenemos los contadores ascendente o up, de estado menor a mayor; descendente o
else if ck'event and ck='1' then down, de estado mayor a menor; y ascendente/descendente o up/down, donde existe un señal que controla si
case ctrl is se cuenta de menor a mayor o de mayor a menor, respectivamente.
when "01" => q <= d; Si se atiende al código de conteo utilizado, se tienen los contadores binarios, BCD (binario decimal, es decir,
when "10" => q(N-1 downto 0) <= il & q(N-1 downto 1); del estado 0 al 9), Johnson, Gray, etc.
when "11" => q(N-1 downto 0) <= q(N-2 downto 0) & ir;
Centrando la discusión en un contador binario ascendente, el contador suele disponer de las entradas:
when others => NULL;
end case; - ck, o señal de reloj
end if; - Load o carga paralela. Los datos a cargar en el contador proviene de un bus de datos d.
end if;
- Enable o capacitación de conteo. El contador sólo contará cuando Enable=1.
end process;
end; - Y reset o preset síncronos o asíncronos.
El contador suele disponer de las salidas:
La figura 3 muestra una posible síntesis, a nivel de componente, del registro de desplazamiento. Es fácil
- q o estado actual.
identificar en ella, los distintos elementos que lo conforman.
- Y la salida terminal, o terminal counter: TC.
La tabla 3 de estados corresponde a la de un contador binario ascendente de 2n estados (n flip-flops) con
reset asíncrono, señal de reloj, carga paralela, enable y con salida terminal.
Estado actual (q) Próximo estado (Q)
Inicialización nreset = 0 - 0
No operación Enable = Load = 0 q q
Carga Load = 1 y ck ↑ q d
Enable = 1 y ck ↑
n
Conteo q q = (q + 1)mod 2
Tabla 3. Tabla de estados de un contador binario ascendente.

La descripción VHDL del contador es inmediata a partir de su tabla de estados:


Library ieee;
Figura 3. Síntesis del registro de desplazamiento. use ieee.std_logic_1164.ALL;
La figura 4 muestra un diagrama temporal del funcionamiento del registro de desplazamiento. El diagrama use ieee.std_logic_unsigned.ALL;
muestra la operatividad para todas las modos de funcionamiento. Entity counter is
generic(N: integer:=4);
port(ck, enable, nreset, load:in std_logic;
d: in std_logic_vector(N-1 downto 0);
tc:out std_logic;
q: out std_logic_vector(N-1 downto 0)); ejemplo siguiente corresponde a un circuito contador con señal nreset síncrona, puesto que la activación está
end counter ; supeditada al evento cambio en flanco de subida en la señal señal de reloj.
Architecture bhr of counter is --EXEMPLE COMPTADOR
signal estado:std_logic_vector(N-1 downto 0); -- Contador divisor per 2^N con señal nreset asíncrona
begin Library ieee;
process(ck, nreset) use ieee.std_logic_1164.ALL;
begin use ieee.std_logic_unsigned.ALL;
if nreset = '0' then estado <= (others => '0'); Entity counter is
else if ck'event and ck = '1' then generic(N: integer:=4);
if load = '1' then estado <= d; port(ck, enable, nreset, load:in std_logic;
else if enable = '1' then estado <= estado +1; d: in std_logic_vector(N-1 downto 0);
end if; tc:out std_logic;
end if; q: out std_logic_vector(N-1 downto 0));
end if; end counter ;
end if; Architecture bhr of counter is
if (estado = 2**N-1) then tc <= '1'; signal estat:std_logic_vector(N-1 downto 0);
else tc <= '0'; begin
end if; proper_estat: process(ck, nreset)
end process; begin
q <= estado; wait until ck='1';
end bhr; if nreset='0' then estat <= (others=>'0');
elsif load = '1' then estat <= d;
En la descripción VHDL del contador se utiliza una señal interna, estado, para mejorar la legibilidad del elsif enable='1' then estat<=estat+1;
código. Por otra parte, el uso de esta variable evita tener que considerar a como señal inout. end if;
La figura 5 muestra el circuito correspondiente al contador en un formato RTL. end process;
sortida: process(estat)
begin
if (estat=2**N-1) then tc<='1';
else tc<='0';
end if;
q<=estat;
end process;
Figura 5. Esquema RTL del circuito contador end bhr;
En la figura 6 se puede observar el resultado de la simulación del contador después de sintetizarlo en el
programable EPM7032. A diferencia del funcionamiento del contador asíncrono (comparar los resultados de simulación de las
figuras 6 y 7), en caso de resolverse una inicialización durante el funcionamiento normal del circuito, el
contador síncrono salta al estado inicial en el momento en que se produce el flanco de reloj, por lo que
siempre los estados mantienen el mismo periodo.

Figura 6. Diagrama temporal del contador binario ascendente.

En un contador la inicialización puede implementarse síncrona o asíncrona. En el ejemplo realizado la señal


nreset inicializa el circuito de forma asíncrona, puesto que la inicialización se lleva a cabo tan pronto la señal Figura 7. Resultado de simulación de un contador con señal nreset síncrona.
nreset se pone a 0-lógico, de acuerdo con la modelización realizada del mismo en la descripción VHDL. El
La figura 8 muestra el resultado de la simulación a nivel temporal. Se comprueba fácilmente que el contador,
El divisor de frecuencia. en cuanto llega al estado 10 reinicializa el circuito, realizando de esta forma un conteo de m = 11 estados.
El divisor de frecuencia no es más que un contador que cuenta un número de estados determinado, no
necesariamente igual a 2^n. En particular, un contador de n flip-flops puede considerarse como un divisor de
frecuencia de 2^n estados.
Un divisor de m estados (m distinto a una potencia de 2) se construye a partir de un contador de 2^n estados,
con 2^n > m, en el que al llegar al estado m-1 se vuelve al estado inicial.
Existen dos formas clásicas de realizar el divisor de frecuencias. La primera es volviendo al estado inicial
por medio de la señal asíncrona reset. El segundo método utiliza la señal síncrona de carga. Siempre que sea
posible, se recomienda utilizar el segundo método en tanto que garantiza un circuito más inmune a glitches. Figura 8. Diagrama temporal del divisor de m = 11 estados.

El código VHDL siguiente corresponde a un divisor de frecuencia por m=11. Para ello se ha tenido que
utilizar un N=4. Para simplificar el ejemplo se ha considerado el mínimo número necesario de señales. Como
entradas sólo son necesarias las señales de reloj y el reset asíncrono. Como salidas se da el estado y la salida
div que corresponde a la salida terminal cuando se llega al estado deseado. Esta misma señal se utiliza para
devolver al divisor al estado inicial.
Library ieee;
use ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.ALL;
Entity divisor is
generic(N: integer:=4;
M: integer:=10); -- M = último estado Æ m = 11.
port( ck, nreset:in std_logic;
div: inout std_logic;
q: inout std_logic_vector(N-1 downto 0));
end divisor;
Architecture bhr of divisor is
begin
process(ck, nreset)
begin
if nreset='0' then q <= (others=>'0');
elsif ck'event and ck='1' then
if div= '1' then q <= (others=>'0');
else q <= q +1;
end if;
end if;
if (q = m) then div <= '1';
else div <= '0';
end if;
end process;
end bhr;

La síntesis realizada contra el circuito de Altera EPM7032, da como resultado el circuito de la figura 7.

Figura 7. Síntesis del divisor por m=10.

También podría gustarte