Anda di halaman 1dari 19

Captulo 10

Contadores

10.1.

Introduccin

Un contador no es ms que un circuito secuencial que como su propio nombre indica es capaz de contar. No obstante existen varias formas de contar. La ms natural es empezar en cero y continuar hasta un valor nal, pero si estamos en una plataforma de lanzamiento de cohetes espaciales igual necesitamos un contador que cuente hacia atrs. Adems hay contadores caprichosos, como los de los ascensores de los rascacielos americanos que del 12 pasan al 14 ya que el piso 13 no existe para no herir la sensibilidad de las personas supersticiosas. En este captulo vamos a estudiar todos estos tipos de contadores. Empezaremos por los contadores binarios ascendentes, los cuales cuentan segn la secuencia 0, 1 (2n 1), 0, 1 para a continuacin estudiar los descendentes, que obviamente realizan la secuencia 0, (2n 1), (2n 2) 1, 0, (2n 1) . Veremos tambin cmo fusionar estos contadores en uno que pueda contar hacia arriba o hacia abajo segn le indique una seal de control. A continuacin estudiaremos cmo realizar un contador en BCD y su generalizacin a un contador mdulo n, el cual cuenta de 0 hasta n y despus reinicia la cuenta en 0. Por ltimo estudiaremos los contadores de secuencia arbitraria por si algn da le contratan para disear el ascensor de un rascacielos.

10.2.

Contador binario ascendente

Un contador binario ascendente de n bits es un circuito que realiza la cuenta 0, 1 (2n 1), 0, 1 . Aunque su diseo puede realizarse mediante una mquina de estados, el circuito puede deducirse fcilmente a partir de su diagrama temporal. As, si se ja en el diagrama de tiempos de la gura 10.1 ver que la salida s(0) cambia en cada anco de reloj. Conseguir este comportamiento es fcil: basta con usar un ipop tipo T y conectar permanentemente su salida a 1, que es lo que se ha hecho en el circuito de la gura 10.1. Si se ja ahora en la salida s(1) ver que sta cambia slo en los ancos de reloj 187

188

Contadores

Vcc clk s(0) s(1) s(2) s(3) clk reset_n s(0) s(1) s(2) s(3)
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0

Figura 10.1: Contador binario ascendente.

en los que la salida s(0) vale 1.1 Lo ms fcil para generar la salida s(1) es usar un ipop tipo T y conectar su entrada a s(0). La salida s(2) slo cambia en los ancos en los tanto s(0) como s(1) valen 1. Por ello se ha generado mediante un ipops tipo T en el que se ha conectado a su entrada la AND de s(0) y s(1). Por ltimo, la salida s(3) cambia en los ancos en los que s(0), s(1) y s(2) valen 1. Para generarla, al igual que antes, se ha usado un ipops tipo T en el que se ha conectado a su entrada la AND de s(0), s(1) y s(2). Para implementar esta AND se ha usado el resultado de la AND de s(0) y s(1), al que se le ha hecho la AND con s(2). Si se ja en el circuito es fcil ampliarlo a un nmero mayor de bits. Basta con ir aadiendo un ip-op tipo T y una puerta AND, conectndolos del mismo modo que se ha hecho para el ltimo ipop del circuito de la gura 10.1.

10.2.1.

Descripcin en VHDL

La descripcin del contador es mejor hacerla en alto nivel usando el operador + para incrementar la cuenta en 1 cada anco de reloj. Si se ja en el cdigo es similar al registro paraleloparalelo estudiado en el captulo anterior, slo que ahora en cada anco de reloj se incrementa el valor de la cuenta en 1. Tambin conviene destacar que al igual que los registros de desplazamiento, el valor del contador ha de almacenarse en una seal interna, ya que es necesario leer su valor. Esta seal se copia a la salida s al nal de la arquitectura, de la misma forma que se hizo en el registro de desplazamiento.
1 2 3 4 5 6 7

-- Contador ascendente de 4 bits library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscendente is
1 Fjese que en este caso los retardos juegan a nuestro favor, pues justo cuando llega el anco de reloj s(0) todava vale 1 y ser despus del retardo de propagacin del ipop cuando se ponga a cero.

10 Contadores

189

Vcc clk s(0) s(1) s(2) s(3) clk reset_n s(0) s(1) s(2) s(3)
0 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Figura 10.2: Contador binario descendente.

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

port ( clk : in std_logic ; reset_n : in std_logic ; s : out std_logic_vector (3 downto 0)); end ContadorAscendente ; architecture behavioral of ContadorAscendente is signal contador : std_logic_vector (3 downto 0); begin -- behavioral

-- Salida

process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then contador <= std_logic_vector ( unsigned ( contador ) + 1); end if; end process ; s <= contador ; end behavioral ;

int main(void) { printf("Hola\n"); return 0; }

10.3.

Contador binario descendente

Realice el ejercicio 1

Como puede ver en el circuito de la gura 10.2, el contador descendente es muy similar al ascendente. Lo nico que cambia es que las entradas T de los ipops estn ahora controladas por las salidas Q de los ipops precedentes, en lugar de por las salidas Q. Ello es porque si se ja en el diagrama de tiempos del contador mostrado en la gura 10.2, la salida s(1) cambia slo cuando s(0) es cero, la salida s(2) cambia slo cuando s(0) y s(1) son cero y la salida s(3) slo cambia cuando

190

Contadores

s(0), s(1) y s(2) son cero.

10.3.1.

Descripcin en VHDL

Como es de esperar la descripcin en VHDL del contador descendente es casi igual a la del ascendente. Tan slo se ha sustituido en la lnea 25 el +1 por un -1 para que en cada ciclo de reloj se decremente el contador. Tambin se ha modicado la lnea 23 para que cuando se inicialice el contador lo haga a 1111 en lugar de a 0000.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
int main(void) { printf("Hola\n"); return 0; }

-- Contador descendente de 4 bits library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorDescendente is port ( clk : in std_logic ; reset_n : in std_logic ; s : out std_logic_vector (3 downto 0)); end ContadorDescendente ; architecture behavioral of ContadorDescendente is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 1); elsif clk event and clk = 1 then contador <= std_logic_vector ( unsigned ( contador ) - 1); end if; end process ; s <= contador ; end behavioral ;

-- Salida

28 29 30

Realice el ejercicio 2

10 Contadores

191

Vcc clk a_d s(0) s(1) s(2) s(3)


0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 0

0 1
clk reset_n a_d s(0) s(1)

0 1

0 1

s(2)

s(3)

Figura 10.3: Contador binario ascendente/descendente.

10.4.

Contador ascendente / descendente

En muchas situaciones son necesarios contadores que cuenten hacia arriba y hacia abajo. Por ejemplo, si queremos llevar la cuenta de los coches que hay en un aparcamiento pblico, cada vez que entra un coche es necesario incrementar el contador y cada vez que sale es necesario decrementarlo. A partir de los dos contadores anteriores es fcil crear un contador ascendente/descendente. Lo nico que hay que hacer para ello es conectar las salidas Q a las entradas T de los ipops cuando queramos un contador ascendente y conectar las salidas Q cuando queramos un contador descendente. Para controlar esta conexin se usa un multiplexor, el cual ser controlado por una entrada al circuito. En la gura 10.3 se muestra el diagrama del contador. La seal de control del sentido de cuenta se ha denominado a_d. Como puede observar, cuando a_d valga 0 la cuenta ser ascendente y cuando sea 1 la cuenta ser descendente. En la gura 10.3 tambin se muestra un diagrama de tiempos con un ejemplo de la evolucin temporal del contador. En ella se ha supuesto que la entrada a_d es cero inicialmente, por lo que el contador cuenta hacia arriba. Cuando la cuenta llega a 8 se ha supuesto que la entrada a_d se pone a 1, por lo que el contador cuenta ahora hacia abajo.

10.4.1.

Descripcin en VHDL

Para describir en VHDL el contador ascendente/descendente se ha aadido al contador ascendente un if en la lnea 26 para decidir en cada anco de reloj si se incrementa la cuenta o se decrementa en funcin del valor de la entrada a_d.
1 2 3 4 5 6 7 8

-- Contador ascentente / descendente de 4 bits library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscDesc is

192

Contadores

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

port ( clk reset_n a_d s

: : : :

in std_logic ; in std_logic ; in std_logic ; -- asc (0)/ desc (1) out std_logic_vector (3 downto 0)); -- Salida

end ContadorAscDesc ; architecture behavioral of ContadorAscDesc is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if a_d = 0 then contador <= std_logic_vector ( unsigned ( contador ) + 1); else contador <= std_logic_vector ( unsigned ( contador ) - 1); end if; end if; end process ; s <= contador ; end behavioral ;

10.5.

Contadores con habilitacin de la cuenta

En muchas situaciones los contadores no tienen que contar en cada anco de reloj. Si volvemos al ejemplo del contador de coches del aparcamiento, el contador slo tendr que cambiar su valor cuando entre o salga un coche. No obstante, recuerde que en un circuito sncrono todos los elementos han de estar conectados al mismo reloj, por lo que si se le ha ocurrido poner una puerta AND a la entrada del reloj para que slo cuente cuando le interese ha elegido una psima solucin. Para conseguir que el contador cuente slo cuando nos interese, se aade una seal denominada enable de forma que cuando en un anco de reloj esta seal est a 1 el contador contar y cuando est a 0 el contador mantendr su valor. Para describir este contador en VHDL basta con aadir la nueva seal a la declaracin de puertos del componente (lnea 14) y un nuevo if (linea 28) para que el contador slo cambie su valor cuando la seal enable valga 1.

10 Contadores

193

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

-- Contador ascentente / descendente de 4 bits con habilitacin -- de la cuenta library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscDescEnable is port ( clk reset_n a_d enable s

: : : : :

in in in in out

std_logic ; std_logic ; std_logic ; -- asc (0)/ desc (1) std_logic ; -- 1 cuenta , 0 mant std_logic_vector (3 downto 0)); -- Salida

end ContadorAscDescEnable ; architecture behavioral of ContadorAscDescEnable is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if enable = 1 then if a_d = 0 then contador <= std_logic_vector ( unsigned ( contador )+1); else contador <= std_logic_vector ( unsigned ( contador ) -1); end if; end if; end if; end process ; s <= contador ; end behavioral ;
int main(void) { printf("Hola\n"); return 0; }

Realice el ejercicio 3

194

Contadores

10.6.

Contadores mdulo m

Los contadores expuestos hasta ahora, cuando la cuenta llegan a 2n 1, siendo n el nmero de bits, rebosan y continan la cuenta en cero. No obstante, en ocasiones es conveniente que la cuenta termine en un valor menor a 2n 1. A este tipo de contadores se les denomina contadores mdulo m, siendo m el nmero de valores por los que pasa el contador. As un contador mdulo 10 cuenta 0, 1 9, 0, 1 Si el contador es descendente la cuenta ser obviamente al revs: 9, 8 1, 0, 9 . El diseo de este tipo de contadores aade un comparador a la salida del contador que inicia la cuenta cuando se detecta que el contador ha llegado a su valor nal. Por ejemplo, en el siguiente cdigo se muestra un contador mdulo 10 ascendente con habilitacin de la cuenta.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

-- Contador ascendente mdulo 10 con habilitacin -- de la cuenta library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscModulo10 is port ( clk reset_n enable s

: : : :

in in in out

std_logic ; std_logic ; std_logic ; -- 1 cuenta , 0 mant std_logic_vector (3 downto 0)); -- Salida

end ContadorAscModulo10 ; architecture behavioral of ContadorAscModulo10 is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if enable = 1 then if contador = "1001" then contador <= ( others => 0); else contador <= std_logic_vector ( unsigned ( contador )+1);

10 Contadores

195

Figura 10.4: Contador ascendente mdulo 10.

32 33 34 35 36 37 38

end if; end if; end if; end process ; s <= contador ; end behavioral ;
El circuito sintetizado a partir de la descripcin anterior se muestra en la gura 10.4. A la vista de la gura conviene destacar varias cosas: En las FPGA slo existen ipops tipo D, por lo que el contador se implanta como n ipops tipo D para almacenar los n bits de la cuenta y un sumador para sumar 1. El nal de la cuenta se detecta con un comparador con 9, de forma que cuando la comparacin es cierta, mediante un multiplexor se pone el valor 0 en la entrada D de los ipops. As en el siguiente anco el contador pasar a valer 0. Cuando la cuenta es distinta de 9 el multiplexor conecta a la entrada D la salida del sumador, que contiene el valor de la cuenta mas 1. De esta forma se incrementar el contador en el siguiente anco de reloj. Los ipops tipo D tienen una entrada de habilitacin ENA, la cual cuando vale 0 mantiene el valor almacenado en el ipop aunque llegue un anco de reloj y cuando vale 1 permite la carga de la entrada D en el ipop cuando llega un anco de reloj.

196

Contadores

10.6.1.

Contadores mdulo m descendentes

En el caso de un contador descendente, la descripcin es muy similar, salvo que ahora cuando el contador llega a cero es necesario cargar el valor del mdulo menos 1. As, si queremos describir un contador descendente mdulo 10, basta con cambiar el cdigo dentro del process a:

int main(void) { printf("Hola\n"); return 0; }

if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if enable = 1 then if contador = "0000" then contador <= "1001"; else contador <= std_logic_vector ( unsigned ( contador ) -1); end if; end if; end if; end process ;

Realice el ejercicio 4

10.7.

Conexin de contadores en cascada

Si se disean contadores binarios en VHDL es fcil aumentar el nmero de bits del contador, sobre todo si se disean de forma genrica, tal como se ha propuesto en los ejercicios 1 y 2. No obstante, cuando se disean contadores usando lgica discreta o si se disean contadores en decimal es necesario poder conectarlos en cascada de forma que un contador cuente cuando el contador anterior rebose. Para ilustrar esto nada mejor que poner un ejemplo. Supongamos que queremos disear un contador ascendente que cuente en BCD natural. En la seccin anterior hemos visto cmo disear un contador que cuente de 0 a 9, con lo que tenemos resuelto el cmo hacer un contador de una cifra. Si queremos hacer uno de tres cifras necesitamos tres contadores, uno para las unidades, otro para las decenas y otro para las centenas. El problema est en que el contador de las decenas slo ha de incrementarse cuando rebose el contador de unidades, es decir, cuando ste pase de 9 a 0. De la misma forma, el contador de centenas slo ha de incrementarse cuando rebose el de decenas. En denitiva, para poder conectar contadores en cascada lo nico que hay que aadir a los contadores expuestos hasta ahora es una salida de acarreo que genere un pulso de un ciclo de reloj cuando el contador rebose y conectar dicha salida al enable del contador de la cifra siguiente. Por ejemplo, en la gura 10.5 se muestra el esquema de un contador decimal de tres cifras construido a partir de tres contadores mdulo 10. El contador mdulo 10 con acarreo de salida se describe en VHDL de forma similar al contador mdulo 10 anterior:

10 Contadores

197

Figura 10.5: Contador ascendente decimal de tres cifras.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

-- Contador ascendente mdulo 10 con habilitacin -- de la cuenta y salida de acarreo . library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscMod10Co is port ( clk reset_n enable co s

: : : : :

in in in out out

std_logic ; std_logic ; std_logic ; -- 1 cuenta , 0 mant std_logic ; -- acarreo std_logic_vector (3 downto 0)); -- Salida

end ContadorAscMod10Co ; architecture behavioral of ContadorAscMod10Co is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if enable = 1 then if contador = "1001" then contador <= ( others => 0); else contador <= std_logic_vector ( unsigned ( contador )+1); end if; end if; end if;

198

Contadores

Figura 10.6: Simulacin del contador ascendente decimal de tres cifras.

Figura 10.7: Simulacin del contador ascendente decimal de tres cifras errneo.

36 37 38 39 40 41

end process ; co <= 1 when contador = "1001" and enable = 1 else 0; s <= contador ; end behavioral ;
Si compara ambas descripciones, los nicos cambios han sido el aadir la salida

que justo cuando se de esa condicin, en el siguiente anco de reloj se producir el rebose. As, al valer el acarreo de salida 1 en dicho anco tambin se incrementar el contador siguiente. Para ilustrar este proceso en la gura 10.6 se muestra la simulacin del paso del contador de 99 a 100. Ntese que si slo hubiramos puesto en la condicin de la lnea 38 el que el contador sea 9, la seal co estara activa desde que el contador llega a 90 hasta que llega a 99, con lo que el contador de decenas se incrementara en cada anco. Para ilustrar este comportamiento anmalo en la gura 10.6 se muestra la misma simulacin, pero realizada con un contador mdulo 10 en el que la lnea 38 se ha sustituido por:

co a la declaracin de puertos (lnea 14) y su lgica en la lnea 38. Ntese que la salida se pone a 1 slo cuando el contador valga 9 y se active la seal de enable, ya

co <= 1 when contador = "1001" else 0;


Ntese que en este caso, al estar la seal de enable del contador de centenas habilitada mientras las decenas valen 9, el contador de centenas cuenta 10 veces y vuelve a situarse en 0, con lo cual no conseguiremos contar ninguna centena.

10.7.1.

Generacin del acarreo en contadores descendentes

Si el contador es descendente, el acarreo a la siguiente cifra es necesario generarlo en el paso de 0 a 9, pues es en ese momento en el que la siguiente cifra ha

10 Contadores

199

carga e_p[3..0]

1 0

Figura 10.8: Contador ascendente mdulo 10 con carga paralelo.

de decrementarse. As, si el contador anterior fuese decreciente, la salida co se describira de la siguiente manera:

co <= 1 when contador = "0000" and enable = 1 else 0;

int main(void) { printf("Hola\n"); return 0; }

10.8.

Contadores con carga paralelo

Realice los ejercicios 5, 6y7

En los contadores mostrados hasta ahora existe una seal de reset que los inicializa a cero, pero a partir de este momento el contador slo puede incrementarse o decrementarse. No obstante existen situaciones en las que es preciso poder cambiar el valor de la cuenta de un contador. Por ejemplo piense en un reloj digital. Si queremos ponerlo en hora es necesario poder modicar el valor de la cuenta. Para la realizacin de la carga paralelo basta con aadir un multiplexor a la entrada de los ipops que almacenan el valor de la cuenta, tal como se muestra en la gura 10.8, en la que se ha aadido una carga paralelo al contador ascendente mdulo 10 de la gura 10.4. Dicho multiplexor se controla mediante la seal carga, de forma que cuanto esta seal es cero el contador cuenta en cada anco de reloj y cuando es 1 carga el valor presente en la entrada paralelo e_p en el contador cuando se produzca el anco de reloj.

200

Contadores

Descripcin en VHDL Para describir en VHDL del contador anterior lo nico que hay que hacer es aadir en la descripcin de los puertos las dos nuevas entradas (lnea 14) y dentro del process un if para modelar el multiplexor (lnea 30).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

-- Contador ascendente mdulo 10 con habilitacin -- de la cuenta , salida de acarreo y carga paralelo . library ieee; use ieee. std_logic_1164 .all; use ieee. numeric_std .all; entity ContadorAscMod10Co is port ( clk reset_n enable carga e_p co s

: : : : : : :

in in in in in out out

std_logic ; std_logic ; std_logic ; -- 1 cuenta , 0 mant std_logic ; -- carga paralelo std_logic_vector (3 downto 0); -- e. par. std_logic ; -- acarreo std_logic_vector (3 downto 0)); -- Salida

end ContadorAscMod10Co ; architecture behavioral of ContadorAscMod10Co is signal contador : std_logic_vector (3 downto 0); begin -- behavioral process (clk , reset_n ) begin -- process if reset_n = 0 then contador <= ( others => 0); elsif clk event and clk = 1 then if carga = 1 then contador <= e_p; elsif enable = 1 then if contador = "1001" then contador <= ( others => 0); else contador <= std_logic_vector ( unsigned ( contador )+1); end if; end if; end if;

10 Contadores

201

a_d enable s X0 01 Uno 0001 11 Reset_n=0 11

X0 01 Tres 0011 11

X0 01 Cinco 0101 11

X0 01 01 Siete 0111 11

X0 Nueve 1001

Figura 10.9: Contador de secuencia arbitraria.

40 41 42 43 44 45

end process ; co <= 1 when contador = "1001" and enable = 1 else 0; s <= contador ; end behavioral ;
int main(void) { printf("Hola\n"); return 0; }

10.9.

Contadores de secuencia arbitraria

Realice el ejercicio 8

Hasta ahora, los contadores que hemos diseado cuentan segn una secuencia de nmeros naturales consecutivos. No obstante en algunas situaciones se necesitan contadores que cuenten segn otra secuencia. Por ejemplo en la introduccin se mencion la existencia de contadores que se saltan el 13 para no herir la sensibilidad de las personas supersticiosas. En las secciones anteriores hemos visto que los contadores normales se implantan como una serie de ipops tipo T o como un conjunto de ipops tipo D con un sumador para incrementar (o decrementar) la cuenta. Esto es as precisamente porque estos contadores generan una secuencia de nmeros consecutivos. En los contadores de secuencia arbitraria, la nica alternativa para implementarlos es usar una mquina de estados en la que cada valor de la cuenta se representa por un estado. Por ejemplo, si queremos disear un contador ascendente/descendente que cuente segn la secuencia 1, 3, 5, 7, 9, la mquina de estados quedara como la mostrada en la gura 10.9. Dicha mquina dispone de dos entradas: a_d para seleccionar el sentido de la cuenta (0 ascendente, 1 descendente) y enable para habilitar la cuenta, de forma que cuando esta seal vale cero el contador no cambia de estado y mantiene el valor de la cuenta y cuando vale 1 cambia de estado en sentido ascendente o descendente en funcin de la seal a_d. Para la implantacin fsica de la mquina de la gura 10.9 existen dos alternativas. La primera es codicar los estados de forma independiente al valor de las salidas, al igual que hemos hecho en todas las mquinas de estados diseadas en el captulo 8. En este caso si usamos una codicacin de estados binaria, en general se necesitarn menos ipops para almacenar el estado; pero a cambio ser necesario aadir una lgica para generar las salidas del contador a partir del estado actual.

202

Contadores

La otra alternativa es codicar el estado con el valor de la cuenta asociado a dicho estado. Por ejemplo, si en el contador que nos ocupa codicamos los estados de forma independiente a las salidas se necesitarn 3 bits, ya que tenemos 5 estados. Si por el contrario hacemos que el estado coincida con el valor binario de la salida necesitaremos cuatro bits.2 Descripcin en VHDL En la descripcin que vamos a realizar del contador de secuencia arbitraria se van a codicar los estados para que su valor coincida con las salidas. Se deja como ejercicio el codicarla como una mquina de estados con funcin de salida como las estudiadas en el captulo 8. En primer lugar, tal como se puede ver en la lnea 19, ahora el estado se almacena en un std_logic_vector, que adems ha de tener el mismo tamao que la salida, pues se va a copiar en ella. Aunque no es estrictamente necesario, se han denido tambin una serie de constantes (lneas 2024) para que sea ms cmoda la especicacin de las transiciones entre estados. El resto de la descripcin es similar al de las mquinas de estado que hemos visto hasta ahora salvo que no existe el process o el when--else en el que se especican las salidas, pues ahora stas son una copia del valor del estado actual.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

int main(void) { printf("Hola\n"); return 0; }

Realice el ejercicio 9

-- Contador ascendente / descendente de secuencia arbitraria . La -- secuencia es 1, 3, 5, 7, 9 library ieee; use ieee. std_logic_1164 .all; entity ContadorSecArb is port ( clk reset_n a_d enable s

: : : : :

in in in in out

std_logic ; std_logic ; std_logic ; std_logic ; std_logic_vector (3 downto 0));

end ContadorSecArb ; architecture behavioral of ContadorSecArb is signal estado_act , estado_sig : std_logic_vector (3 downto 0); constant Uno : std_logic_vector (3 downto 0) := "0001"; constant Tres : std_logic_vector (3 downto 0) := "0011";
2 En este caso particular se puede codicar tambin con tres bits, usando un pequeo truco que igual al lector espabilado ya se le ha ocurrido.

10 Contadores

203

22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

constant Cinco : std_logic_vector (3 downto 0) := "0101"; constant Siete : std_logic_vector (3 downto 0) := "0111"; constant Nueve : std_logic_vector (3 downto 0) := "1001"; begin -- behavioral

VarEstado : process (clk , reset_n , estado_sig ) begin if reset_n = 0 then -- Reset asncrono estado_act <= Uno; -- ( activo bajo) elsif clk event and clk = 1 then -- Flanco de subida estado_act <= estado_sig ; end if; end process VarEstado ; TransicionEstados : process (estado_act , a_d , enable ) begin -- Por defecto nos quedamos en el estado actual estado_sig <= estado_act ; case estado_act is when Uno => if enable = 1 then if a_d = 0 then estado_sig <= Tres; else estado_sig <= Nueve; end if; end if; when Tres => if enable = 1 then if a_d = 0 then estado_sig <= Cinco; else estado_sig <= Uno; end if; end if; when Cinco => if enable = 1 then if a_d = 0 then estado_sig <= Siete; else estado_sig <= Tres; end if; end if;

204

Contadores

66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

when Siete => if enable = 1 then if a_d = 0 then estado_sig <= Nueve ; else estado_sig <= Cinco ; end if; end if; when Nueve => if enable = 1 then if a_d = 0 then estado_sig <= Uno; else estado_sig <= Siete ; end if; end if; when others => null; end case; end process ; s <= estado_act ; end behavioral ;

10.10.

Ejercicios

1. Modique el cdigo del contador binario ascendente mostrado en la seccin 10.2 para que el nmero de bits del contador sea un parmetro genrico. 2. Modique el cdigo del contador binario descendente mostrado en la seccin 10.3 para que el nmero de bits del contador sea un parmetro genrico. 3. Sustituya en el contador ascendente descendente con habilitacin de la cuenta de la seccin 10.5 las seales enable y a_d por las seales cuenta_arriba y cuenta_abajo. El funcionamiento del contador con estas nuevas seales ser el siguiente: en cada anco de reloj si est activa la seal cuenta_arriba el contador se incrementar y si est activa la seal cuenta_abajo el contador se decrementar. Cuando ambas seales estn activas a la vez o desactivas, el contador mantendr su valor. 4. Modique el contador ascendente mdulo 10 de la seccin 10.6 para convertirlo en un contador ascendente/descendente mdulo 10. 5. Modique el contador ascendente mdulo 10 con acarreo de la seccin 10.7 para convertirlo en un contador ascendente/descendente. Tenga en cuenta que existir una sola salida de acarreo co que se activar cuando el contador

10 Contadores

205

rebose de 9 a 0 cuando se est contando en sentido ascendente o cuando rebose de 0 a 9 cuando se est contando en sentido descendente. 6. A partir del contador anterior disee un contador ascendente/descendente de tres cifras. Use una descripcin estructural para instanciar los tres contadores de una cifra y conectar sus acarreos. 7. Disee un contador para implementar un reloj. El contador dispondr de 4 cifras: dos para los segundos y dos para los minutos. De estas 4 cifras, dos de ellas estarn formadas por contadores mdulo 10 y las otras dos por contadores mdulo 6. Por tanto, el ejercicio ha de dividirse en dos partes. Disee en primer lugar un contador ascendente mdulo 6. En segundo lugar ha de instanciar los cuatro contadores, dos mdulo 10 y dos mdulo 6, para implantar el contador de minutos y segundos. 8. Disee contador para implementar un temporizador para un microondas. El contador ser similar al del ejercicio anterior pero descendente y con carga paralelo para poder inicializar el contador con el tiempo deseado. 9. Especique el contador de secuencia arbitraria mostrado en la seccin 10.9 usando una descripcin de la mquina de estados en la que en lugar de especicar la codicacin del estado se use una funcin de salida para obtener el valor de la cuenta.

Anda mungkin juga menyukai