capitulo 6. bloques y sistemas secuenciales · bits de información, y se denomina un registro de n...
TRANSCRIPT
CAPITULO 6. BLOQUES Y SISTEMAS SECUENCIALES
Introducción
En el capítulo 5 estudiamos los principios y funcionamiento de los circuitos secuenciales
básicos: cerrojos y flip-flops. Presentamos asimismo los principios de análisis y diseño de
circuitos sencillos con flip-flops, y su síntesis y simulación por medio de programas VHDL.
Presentaremos ahora bloques secuenciales, como registros, contadores y memorias RAM, y
el diseño de sistemas secuenciales de mediana complejidad que requieren de controladores
secuenciales.
6.1 Registros.
Un flip-flop tipo D almacena el valor de una señal de entrada I a su terminal D por un período
de reloj. Un conjunto de n flip-flops D disparados por un reloj común almacena por tanto n
bits de información, y se denomina un registro de n bits. Eso es, Qj = Dj = Ij para j=0,1,…n-
1. En la figura 6.1.1 se muestra un registro de 4 bits, conocido como registro con carga en
paralelo.
Figura 6.1.1. Registro con carga en paralelo y su símbolo
Consideramos ahora la posibilidad de controlar la carga de los n bits, por una señal de
habilitación Ld. Si Ld=1, el registro cargará los bits I que se presenten en sus entradas; de lo
contrario, conservará sus valores anteriores (q). Así, para el flip-flop j tenemos
Qj = Ld · Ij + Ld´· qj = Dj (6.1.1)
El circuito de entrada a cada uno de los flip-flops equivale por tanto a un MUX 2 a 1
direccionado por Ld, o bien por las compuertas del MUX como en la figura 6.1.2 para el flip-
flop j. Existe en el mercado una amplia variedad de registros similares, de 4 u 8 bits como CI
MSI; por lo general, incluyen una entrada asíncrona de borrado al menos. En las computadoras
actuales se utilizan extensamente registros de 32 o 64 bits.
Figura 6.1.2. Control de carga del paso j de un registro
En la figura 6.1.3 se muestra el código VHDL para un registro de n bits con borrado asíncrono
clrn activo en bajo. La lógica es similar a la del código del flip-flop D, pero introducimos la
palabra reservada GENERIC, para utilizar como parámetro el número de bits n, al cual le
asignamos en el código el valor 8. Utilizamos la notación rp para el valor presente del registro
en vez de Q, y rs para su valor siguiente (futuro), que se encuentra en la entrada D. Al ocurrir
el flanco del reloj, es claro que ocurre un nuevo valor presente (rp=rs). Cuando clrn=0, el
valor presente será cero, lo que representamos como rp<= (OTHERS=> ‘0’); esta cláusula
permite asignar ceros al registro sin especificar la cadena “000…0” de n bits, ya que el valor
de n es genérico.
Por otro lado el valor siguiente rs es la salida del decodificador de estado siguiente (DES) del
modelo secuencial de la Figura 5.3.1. Lo estipulamos fuera del proceso en forma de MUX
como rs<= i WHEN ld=’1’ ELSE rp;
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY registron IS GENERIC (n: INTEGER:=8); PORT (i: IN STD_LOGIC_VECTOR (n-1 DOWNTO 0); clk, clrn, ld: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR (n-1 DOWNTO 0); END registron; ARCHITECTURE uno OF registron IS BEGIN SIGNAL rs,rp: STD_LOGIC_VECTOR (n-1 DOWNTO 0); PROCESS(clk,clrn)--cambio del registro al flanco del reloj BEGIN IF clrn=’0’ THEN rp<= (OTHERS=> ‘0’); --borrado asíncrono ELSIF clk=’1’ AND clk’EVENT THEN rp<=rs; END IF; END PROCESS; rs<= i WHEN ld=’1’ ELSE rp; -- salida del DES q<=rp; END uno;
Figura 6.1.3. Código de VHDL de un registro genérico de n bits, con n=8.
Registro de desplazamiento. En la figura 6.1.4 se muestra otro tipo de registro, con una sola
entrada I conectada al flip-flop de la izquierda. Las salidas de cada uno de los 3 primeros flip-
flops se conectan a la entrada del que se encuentra a su derecha. Los bits que deben cargarse
arriban en serie por I, y se desplazan como se muestra en la figura hacia la derecha con cada
arribo, que coincide con un pulso del reloj Clk; se ha supuesto que, al inicio del proceso, el
registro ha sido puesto a ceros, y que la secuencia es 110001 a partir de t1.
Figura 6.1.4. Registro de desplazamiento de 4 bits y tabla de secuencia
Es interesante observar las salidas al tiempo t4, al cargarse 4 bits, 1100. Estos se encuentran
almacenados en el registro, pero de derecha a izquierda. Si se monitorean las salidas en
paralelo, tendríamos una función de conversión serie a paralelo. Esta operación es muy
frecuente en sistemas digitales, pues es mucho más económico transmitir bits en serie que en
paralelo; para n bits, se requiere un registro de corrimiento con n flip-flops.
En la figura 6.1.5 se muestra el código VHDL del registro de desplazamiento a la izquierda
de 4 bits, con entrada serial i, mediante un proceso. Notar el uso de la cláusula WAIT UNTIL
(sin lista de sensitividad) en vez de una cláusula IF para el reloj.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY regcorr4 IS PORT(i,clk: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END regcorr4; ARCHITECTURE uno OF regcorr4 IS SIGNAL y: STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN PROCESS BEGIN WAIT UNTIL clk='1' AND clk'EVENT; y(3)<=y(2); y(2)<=y(1); y(1)<=y(0); y(0)<=i; END PROCESS; q<=y; END uno; Figura 6.1.5 Programa VHDL de un registro de desplazamiento a la izquierda
La asignación de valores a las entradas de los flip-flops puede realizarse en forma iterativa
utilizando la cláusula LOOP; el desplazamiento a la derecha de un registro de 4 bits, por
ejemplo, se programa como
FOR j IN 0 TO 2 LOOP y(j)<=y(j+1); END LOOP; y(3)<=i;
El mismo efecto se logra usando el operador de concatenación: y<=i&y(3 DOWNTO 1).
Registro universal. Pensemos ahora en un registro que carga bits en paralelo, desplaza a la
derecha, desplaza a la izquierda o mantiene su estado; son 4 posibilidades, que pueden
controlarse mediante 2 señales s1 y s0. Para establecer la lógica de este control, necesitamos
considerar cuales son las entradas de un flip-flop. Consideremos primero un flip-flop
intermedio j. Para cargar una entrada Ij se requiere que Dj = Ij; para desplazar a la derecha se
requiere que Dj = q(j+1); para desplazar a la izquierda, Dj = q(j-1), y para mantener su estado
se requiere que Dj = qj. Esto es, hay 4 posibles entradas para un destino Dj, por lo que se
requiere un MUX 4 a 1. El MUX se direcciona justamente por s1 y s0, como en la Figura
6.1.6a. En el caso de los flip-flops del extremo izquierdo, no existe q(j+1), y la entrada serial
es Il; el del extremo derecho no tiene consecuente q(j-1), y la entrada serial es Ir. Visto como
un dispositivo (caja negra), un registro de 4 bits puede representarse como en la figura 6.1.6b.
(a) (b)
Figura 6.1.6. Tabla de verdad, lógica y símbolo de un registro universal.
Desplazamientos aritméticos y lógicos.
Cuando el dato es numérico, el desplazamiento a la izquierda representa una multiplicación
por 2 si se agrega un cero por la derecha. Por ejemplo, al desplazar a la izquierda la palabra
00101100 (4210), obtenemos 01011000, que equivale a 8410. Si el número es con signo, ya no
podríamos volver a multiplicar por 2, dado que al desplazar tendríamos un número negativo,
producto del desbordamiento (se rebasa la capacidad de representación del registro que
contiene la palabra).
Si se desplaza la palabra hacia la derecha, el número se divide entre 2, siempre y cuando por
la izquierda se replique el signo en el bit más significativo, y se desplace hacia el bit siguiente
a su derecha; por ejemplo, desplazar a la derecha la palabra 11010110 (-4210), nos da como
resultado 11101011 (-2110). Véase la Figura 6.1.7.
Figura 6.1.7. Desplazamientos aritméticos (a y b), rotación (c y d) y lógicos (e y f)
Una variante consiste en efectuar los desplazamientos al través del bit de acarreo Cn; a esta
operación se le denomina rotación o circulación. Finalmente, para datos no numéricos,
tenemos los desplazamientos lógicos, en los cuales los bits que se introducen por los extremos
son ‘0’.
Para sintetizar circuitos con desplazamientos múltiples con VHDL, podemos recurrir a las
funciones SHIFT_LEFT, SHIFT_RIGHT, ROTATE_LEFT, ROTATE_RIGHT del paquete
NUMERIC.STD, aplicados a señales UNSIGNED o SIGNED con calificador n que indica el
número de bits a desplazar. Por ejemplo, SHIFT_RIGHT(q,3) desplaza al vector q del tipo
UNSIGNED 3 bits a la derecha introduciendo ceros por la izquierda. Este tipo de
desplazamientos se sintetizan por medio de Mux (barrel shifter) como se muestra en la figura
6.1.8 El número de desplazamientos se controla por medio de la dirección sh de 2 bits.
6.2 Contadores
En el capítulo 5 hemos analizado el circuito de un contador binario natural módulo 8, y
diseñado un contador binario módulo 6. El primero efectúa una cuenta completa, esto es, sus
flip-flops toman todos los valores posibles (000 a 111); de ahí el término binario natural, en
contraste con el segundo, que cuenta sólo hasta 5 (101).
Puede demostrarse que el diseño más sencillo de un contador binario natural resulta de utilizar
flip-flops tipo T (J=K); la entrada T de cada flip-flop es el AND de las salidas anteriores. Por
ejemplo, para un contador módulo 32 tenemos que
T0 = 1, T1 = q0, T2 = q0 · q1, T3 =q0 · q1 · q2, T4 = q0 · q1· q2 · q3
En general, la entrada Tj del paso j puede escribirse como
Tj = ∏qk, con k=0,1,…j-1 (6.2.1)
(a) (b)
Figura 6.1.8. Desplazadores combinacionales. (a) izquierda lógico (b) derecha aritmético
Estos contadores actúan con cada pulso del reloj. Sin embargo, existen numerosas
aplicaciones en las cuales se requiere contar la ocurrencia de una señal externa x. Podríamos
entonces sustituir x por el bit 1 del paso 0, y añadir x a cada AND; x actúa como una señal de
habilitación: Si x=1 el contador cuenta; si x=0 se inhibe la cuenta. En la figura 6.2.1 se muestra
el circuito de un contador módulo 16 con entrada x.
Figura 6.2.1. Contador binario MOD 16 con entrada x de habilitación
Contadores asíncronos. Por lo general, la señal x es asíncrona respecto al reloj de un
contador; puede ocurrir en cualquier momento. Cabe preguntarse si es posible utilizar
un contador asíncrono, sin reloj. En la figura 6.2.2 (a) se muestra un contador asíncrono
Módulo 8; incluye 3 flip-flops T permanentemente habilitados (T=1) para cambiar. La salida
Q de cada flip-flop activa la entrada de reloj del paso siguiente; así, se genera un cambio con
cada flanco negativo de cualquier salida Q. La operación del contador se muestra en la Figura
6. 2. 2(b).
El diagrama de tiempo de la Figura 6. 2. 2(b) nos muestra otra aplicación de un contador: la
de división de frecuencia. Si la señal de entrada tiene una frecuencia f, la salida del primer
paso es f/2, la del segundo es f/4, etc. Un reloj digital con alimentación de la toma eléctrica
de 60Hz, por ejemplo, utiliza un contador módulo 60 para lograr la frecuencia de 1 ciclo por
segundo.
Figura 6.2.2. Contador asíncrono MOD 8
Un problema que se presenta con los contadores asíncronos de módulos grandes es el retraso
que sufre la cuenta, por la operación de flip-flops en cascada; como cada flip-flop presenta un
retraso tp, en un contador de n pasos habría que esperar un tiempo tp x n para que el último
flip-flop presente una salida confiable. En los contadores síncronos, en cambio, todos los flip-
flops cambian al unísono.
Figura 6.2.3. Contador asíncrono BCD
Contador BCD. En la figura 6.2.3 se muestra un contador BCD asíncrono. El diseño del
síncrono se deja como ejercicio al lector; el método es similar al del contador módulo 6
expuesto en el ejemplo 5.4.2. Esos contadores se utilizan frecuentemente por la conveniencia
de desplegar dígitos decimales con LEDs de 7 segmentos. En la Figura 6.2.4 se muestra un
diagrama a bloques de 2 contadores asíncronos BCD para el despliegue visual de 2 dígitos
decimales. Cuando la cuenta del primer paso (unidades) vuelve a 0, se arranca el segundo
paso (decenas).
Figura 6.2.4. Conexión en cascada de 2 contadores asíncronos BCD
Contadores comerciales MSI. Existe en el mercado una amplia variedad de contadores
síncronos y asíncronos. Incluyen por lo general una entrada de borrado asíncrono clr activa
en bajo. Otros incluyen una salida para detectar la cuenta máxima o acarreo (por ejemplo, la
cadena 1111 si es de 4 bits), para conectar dicha salida a la entrada de otro paso similar y
formar contadores más grandes. Otro, como el 74xx293, ofrece al usuario varias opciones de
conexión para obtener cuentas de módulos diferentes.
Contadores descendentes. Hasta el momento, hemos considerado contadores binarios que
aumentan su cuenta con cada pulso de reloj o señal externa x; sin embargo, los contadores
descendentes son también de suma utilidad. Existen en el mercado, y pueden diseñarse con la
metodología expuesta.
EJEMPLO 6.2.1 Diseñar un contador ascendente-descendente de 2 bits con flip-flops D.
Solución: Requerimos de una señal de control x tal que, si x=0, la cuenta es ascendente, y si
x=1, es descendente. Tenemos entonces el mapa de transición de la figura 6.2.5.
Figura 6.2.5. Mapa de transición de un contador ascendente-descendente
Considerando la ecuación característica de un flip-flop D, D=Q, obtenemos del mapa D1=x
q1 q0 y D0=q0´. El circuito se muestra en la figura 6.2.6.
Figura 6.2.6. Contador ascendente/descendente de 2 bits
Contador con carga en paralelo. Un dispositivo de suma utilidad es un contador síncrono
que funcione también como registro con carga en paralelo. Se utiliza prácticamente en todas
las computadoras incrementando la dirección de memoria donde se encuentra la siguiente
instrucción por procesar (cuenta), o recibiendo una dirección alterna cuando es necesario
efectuar un brinco o ramificación a otra instrucción o subrutina (carga). Al dispositivo se le
conoce como el PC (del inglés program counter). Como veremos, facilita también el diseño
de un contador binario de módulo distinto a 2n.
Podemos diseñar un PC general con 2 señales de control cnt y Ld, con 3 posibles opciones de
funcionamiento como se muestra en la tabla de la Figura 6.2.7a: Retención si Ld=cnt=0,
cuenta si Ld=0 y cnt=1, y carga si Ld=1. El diagrama esquemático del dispositivo se presenta
en la Figura 7.2.7b
Figura 6.2.7 Tabla de verdad y diagrama a bloques de un contador con carga en paralelo
Para diseñar el circuito, utilizamos flip-flops JK. Consideremos un paso j; para actuar como
contador, requerimos Jj = Kj = =∏qk. Para actuar como registro, el flip-flop debe funcionar
como D, luego Jj = Ij y Kj = Ij´. De acuerdo con la tabla de verdad, tenemos entonces
Jj = ∏qk · Ld´· cnt +Ij · Ld (6.2.2)
Kj = ∏qk · Ld´· cnt + Ij´· Ld
El circuito correspondiente a un paso j del dispositivo se muestra en la Figura 6.2.8.
∏qk k=0,1,…j-1
Figura 6.2.8. Paso j de un contador con carga en paralelo con flip-flops JK.
El diseño de un PC puede efectuarse también con flip-flops D. En este caso se requiere hacer
funcionar a un flip-flop D como T. Esto es posible si recordamos que, si T = 0, el flip-flop
mantiene su estado, y si T = 1, lo complementa. Utilizamos por tanto una compuerta XOR
como inversor selectivo controlado por cnt, y el circuito equivalente de un MUX a la entrada
Dj para seleccionar mediante Ld la entrada Ij como en la figura 6.2.9.
Con un PC es posible implementar un contador binario módulo n, detectando la cuenta n-1
para activar a Ld; el valor de la cuenta inicial (usualmente 0) se cargará entonces al siguiente
pulso de reloj. En el proceso, cnt=1 todo el tiempo.
Figura 6.2.9. Paso j de un contador con carga en paralelo con flip-flops D
EJEMPLO 6.2.2. Diseñar un contador módulo 13 con un PC.
Solución: Del diagrama a bloques, detectamos la cuenta máxima=12 mediante una AND de 4
entradas, y conectamos su salida con la entrada Ld, como en la Figura 6.2.10.
Figura 6.2.10. Contador binario MOD 13 con un contador con carga en paralelo
Borrado síncrono. Otro método para implementar un contador de módulo diferente a 2n,
consiste en detectar la cuenta máxima módulo-1, y aplicarla a una entrada clr síncrona. Así,
al pulso activo de reloj siguiente el contador volverá a cero. Hacemos notar que es posible
usar también un clr asíncrono, pero debe detectarse la condición cuenta = módulo para
accionar a la señal de clr. Esta cuenta aparece momentáneamente y desaparece casi de
inmediato, por lo que las señales de salida q podrán mostrar un pico indeseable.
Contadores de registro de desplazamiento. Este tipo de contadores emplea un registro de
desplazamiento con lógica combinacional para formar un sistema con un diagrama de estado
cíclico; no cuenta en una secuencia binaria, pero es útil en muchas aplicaciones de control. El
más sencillo es el mostrado en la figura 6.2.11a, llamado contador de anillo. Se inicializa
con sólo un bit igual a 1, y dicho bit circula hacia la derecha con cada pulso de reloj formando
la secuencia mostrada en la figura 6.2.11b (para 4 bits). Este circuito sirve para controlar un
proceso secuencial muy sencillo, en el cual cada paso del contador exhibe una señal activa en
cada tiempo. Notar que se puede lograr el mismo efecto con un contador binario ascendente
de log2n bits, y un decodificador log2n a n.
Figura 6.2.11. Contador de anillo de 4 bits
Síntesis y simulación de contadores con código VHDL. En la Figura 6.2.12 se muestra el
programa de un contador binario ascendente de 4 bits con carga en paralelo y borrado
asíncrono. Utilizamos 2 procesos: uno para el cambio de los flip-flops con el flanco del reloj
(rp<=rs) y otro para la lógica del DES. La simulación se muestra en la Figura 6.2.13; se
advierte que la señal ld carga un valor y se reanuda la cuenta. La cuenta se realiza por medio
de una suma (rs<=rp+1) cuando cnt=1, por lo que se utiliza el paquete NUMERIC.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY contpar IS PORT(i: STD_LOGIC_VECTOR(3 DOWNTO 0); clk, clr, ld, cnt: IN STD_LOGIC; q: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END contpar; ARCHITECTURE uno OF contpar IS SIGNAL rs,rp: UNSIGNED(3 DOWNTO 0); SIGNAL ldcnt: STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN PROCESS(clk,clr)—cambio con el flanco del reloj BEGIN IF clr='1' THEN rp<=(OTHERS=>'0'); ELSIF clk='1' AND clk'EVENT THEN rp<=rs; END IF; END PROCESS; ldcnt<=ld&cnt ------------ CÓDIGO DEL DES ----------------------- PROCESS( ldcnt, i, rp) BEGIN CASE ldcnt IS WHEN “00” => rs<=rp; WHEN “01” => rs<=rp+1; WHEN OTHERS => rs<=UNSIGNED(i); END CASE; END PROCESS; q<=STD_LOGIC_VECTOR(rp); END uno;
Figura 6.2.12. Código VHDL para un contador de 4 bits con carga en paralelo
La simulación se muestra en la Figura 6.2.13, y en la figura 6.2.14 se muestra el diagrama
RTL sintetizado (Notar MUX 4 a 1 y sumador).
Figura 6.2.13. Simulación del contador del programa 6.2.12
Otra alternativa para simular un contador consiste en describir las ecuaciones de entrada a
los flip-flops, pero ello implica efectuar antes el diseño de forma manual. Por último, se
puede describir el diagrama de estados, como se estudió en la sección 5.8.
Figura 6.2.14. Diagrama de la síntesis del contador del programa 6.2.12
Cuenta a un módulo m. Si el módulo deseado es menor a 2n donde n es el número de bits,
utilizamos el valor anterior m-1 para condicionar la cuenta; el código dconcurrente del
decodificador de estado siguiente (DES) resulta
rs<= rp+1 when rp<m-1 else (OTHERS=> ‘0’);
Cuenta de horas en un reloj digital. Planteamos a continuación el programa VHDL reloj12
que sintetiza la cuenta de horas en un reloj digital. La salida es un vector de 8 bits, que
corresponde con 2 dígitos BCD para visualizadores de 7 segmentos, y una señal am_pm que
indica am o pm. La señal de reloj clk es de 1 ciclo por hora.
La cuenta se incrementa por 1 con una señal inc. Pero se deben considerar los casos siguientes:
Si son las 12 (00010010), el resultado cambia a 1(00000001); si son las 9 (00001001), el
resultado cambia a 10 en BCD (00010000). Además, si son las 11 se cambia am por pm.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY rel12 IS PORT(clk,inc: IN STD_LOGIC; dout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); am_pm: OUT STD_LOGIC); END rel12; ARCHITECTURE uno OF rel12 IS SIGNAL d0: UNSIGNED(3 DOWNTO 0); SIGNAL d1, ampm: STD_LOGIC; SIGNAL dsal: UNSIGNED(7 DOWNTO 0);
BEGIN PROCESS(clk) BEGIN IF clk'EVENT AND clk='1' THEN IF inc='1' THEN IF d1='1' AND d0="0010" THEN d1<='0'; d0<="0001"; -- CAMBIO DE 12 A 1 ELSIF d0 ="1001" THEN d0<="0000"; d1<='1'; -- CAMBIO DE 9 A 10 ELSE d0<=d0+1; END IF; IF d0="0001" AND d1='1' THEN ampm<=NOT ampm; END IF; END IF; END IF; END PROCESS; dsal<="000"&d1&d0; dout<=STD_LOGIC_VECTOR(dsal); am_pm<=ampm; END uno;
Figura 6.2.15. Programa VHDL de las horas de un reloj
El programa se muestra en la figura 6.2.15. Utilizamos una señal d1 y un vector d0 para los
dígitos, y una señal dout = “000”&d1&d0. La simulación se muestra en la figura 6.2.16. Los
valores 10, 11 y 12 (BCD) aparecen como 16,17 y 18 en decimal.
Figura 6.2.16. Simulación del programa de la Figura 6.2.15
Generador de señales. Supongamos que se requiere una forma de onda irregular, como la de
la Figura 6.2.17; en ésta el período total T consiste de un subperíodo de valor 0 y duración
10T0, y un subperíodo de valor 1 y duración 15T0, donde T0 es el período del reloj básico de
un contador. Para resolver el problema, podemos usar un contador MOD25 con 5 flip-flops
de salidas q4, q3, q2, q1, q0 (q0 es la menos significativa) y un flip-flop D adicional de salida
q. Este flip-flop debe apagarse cuando la salida del contador sea 25 (detectamos entonces la
cuenta 24: q=q4q3q2´q1´q0´), y permanecer apagado hasta que la cuenta sea 10 (detectamos
la cuenta 9: q=q4´q3q2´q1’q0). Al décimo pulso debe encender q, y permanecer encendido
hasta la cuenta 25. La entrada del flip-flop resulta entonces
d= (q4´∙ q3 ∙ q2´∙ q1´∙ q0 + q) ∙ (q4 ∙ q3 ∙ q2´∙ q1´∙ q0´)´.
Figura 6.2.17. Forma de onda por generar
1.3 Programación en VHDL de un sistema FSM con temporizadores
En sistemas digitales complejos se suelen utilizar contadores como temporizadores; se
caracterizan porque el cambio de algún estado no ocurre necesariamente con cada pulso de
reloj, sino con un valor determinado, T, de pulsos. En un sistema pueden requerirse diversos
valores de T en varios estados. Podemos hablar entonces de 3 tipos de transiciones en un
sistema: Puramente condicional, puramente temporal o mixto, como se muestra en la figura
6.3.1.
Figura 6.3.1. Transiciones posibles en un sistema secuencial
Los sistemas estudiados hasta ahora son del tipo condicional (a), pero podemos clasificarlos
también como mixtos si T=1 (1 ciclo de reloj). Las transiciones puramente temporales (b)
pueden clasificarse también como mixtos si las señales x son irrelevantes
(“don´t care”).
En la figura 6.3.2 se muestra un formato para describir el diagrama ASM de un sistema
secuencial mixto. Utilizamos el método de 2 procesos; el del reloj incluye el contador y
habilita la transición de estados cuando la cuenta se iguala con el valor de una señal temp.
Nótese el uso de variables para actualizar cont de inmediato. El segundo proceso indica las
transiciones y establece valores para temp en cada estado (temp.=1 para el tipo puramente
condicional).
-------Proceso del reloj---------------------------------- PROCESS(clk,rst) VARIABLE cnt: INTEGER RANGE 0 TO max; BEGIN IF rst=’1’ THEN estado_presente<=estado_inicial; cont:=0; ELSIF (clk=’1’ AND clk’EVENT) THEN cont:=cont+1; IF cont>=temp. THEN estado_presente<=estado_futuro; cont:=0; END IF; END IF; END PROCESS; PROCESS(estado_presentes,entradas)—proceso de transiciones BEGIN CASE estado_presente IS WHEN A => IF (entrada) THEN estado_futuro<=B; temp<=valor1; ELSE estado_futuro<=A; temp<=valor2; END IF; … WHEN … END CASE; END PROCESS; ----------Instrucciones concurrentes para salidas---------- z0<=’1’ WHEN (estado_presente=A AND x=’0’) ELSE ‘0’; --Mealy z1<=’1’ WHEN estado_presente=C ELSE ‘0’; --Moore
Figura 6.3.2. Plantilla para programar una FSM con temporizadores
Semáforo. Como ejemplo, proponemos sintetizar la operación de un semáforo que controla
la circulación de una avenida principal A y una calle secundaria B. Cada bocacalle posee
sensores pa y pb para detectar la presencia de vehículos en la vía respectiva. Las luces son
verde (V), roja (R) y amarilla (A). La luz verde de A, Va, dura 30 segundos si hay autos
esperando en B; de lo contrario, el verde persiste hasta un valor tmax. de 60 segundos. Por
otro lado, la luz verde de B, Vb, dura 20 segundos, a menos que no hayan autos en A y sí
persistan en B; el valor máximo es también de 60 segundos. El tiempo de duración de las luces
amarillas Aa y Ab es de 10 segundos. Usamos un reloj de 10 segundos, de manera que ta=3,
tb=2, tmax=6. Denominamos los estados como aa (Va), ab(Aa), bb(Vb) y ba(Ab). El diagrama
MDS se muestra en la Figura 6.3.3:
Figura 6.3.3. Diagrama MDS del semáforo
En la Figura 6.3.4 se muestra el programa VHDL semaft, con los valores genéricos ta, tb. y
tmax. Los colores del semáforo y los valores de temp se incluyen en el proceso de transiciones,
para cada estado. Utilizamos ty=0 para el amarillo, para que dure sólo un ciclo de reloj.
ENTITY semaft IS GENERIC(ta: POSITIVE:=4; tb: POSITIVE:=3; ty: NATURAL:=0; tmax: POSITIVE:=6); PORT(pa,pb,clk,rst: IN BIT; Va,Vb,Ra,Rb,Ya,Yb: OUT BIT); END semaft; ARCHITECTURE uno OF semaft IS TYPE estado IS (aa,ab,bb,ba); SIGNAL edop, edof: estado; SIGNAL temp: INTEGER RANGE 0 TO tmax; BEGIN PROCESS(clk,rst) -- cambio de estados con reloj VARIABLE cont: INTEGER RANGE 0 TO tmax; BEGIN IF rst='1' THEN edop<=aa; cont:=0; ELSIF (clk='1' AND clk'EVENT) THEN cont:=cont+1; IF (cont>=temp) THEN edop<=edof; cont:=0; END IF; END IF; END PROCESS; PROCESS(edop, pa, pb)--transiciones BEGIN CASE edop IS WHEN aa => Va<='1'; Ra<='0'; Vb<='0'; Rb<='1'; Ya<='0'; Yb<='0'; IF pb='1' THEN temp<=ta; ELSE temp<=tmax; END IF;
edof<=ab; WHEN ab => Va<='0'; Ra<='1'; Vb<='0'; Rb<='1'; Ya<='1'; Yb<='0'; temp<=ty; edof<=bb; WHEN bb => Va<='0'; Ra<='1'; Vb<='1'; Rb<='0'; Ya<='0'; Yb<='0'; IF (pb='0' OR pa='1') THEN temp<=tb; ELSE temp<=tmax; END IF; edof<=ba; WHEN ba => Va<='0'; Ra<='1'; Vb<='0'; Rb<='0'; Ya<='0'; Yb<='1'; temp<=ty; edof<=aa; END CASE; END PROCESS; END uno;
Figura 6.3.4. Programa VHDL del semáforo
En la Figura 6.3.5 se muestran resultados de la simulación, para varios casos de pa y pb.
Figura 6.3.5. Simulación del programa del semáforo
Una variante de la plantilla actualiza el DES del contador en el proceso de transiciones
(cont<=cont+1), de acuerdo con la carta ASM de la Figura 6.3.6. El código VHDL
correspondiente se muestra en la Figura 6.3.7. La salida del contador se utiliza como señal,
y no como variable; contp indica el valor presente, y conts el valor futuro.
Figura 6.3.6. Diagrama alternativo detallado del controlador de un semáforo
ENTITY semac IS GENERIC(ta: INTEGER:=4; tb: INTEGER:=3; tmax: INTEGER:=6; ty: INTEGER:=1); PORT(CLK, RST, PA, PB: IN BIT; Va, Vb, Ra, Rb, Ya, Yb: OUT BIT); END semac; ARCHITECTURE uno OF semac IS TYPE edo IS (aa, ab, bb, ba); SIGNAL edop, edos: edo; SIGNAL temp,contp,conts: INTEGER RANGE 0 TO tmax; BEGIN PROCESS(clk, rst) -- reloj BEGIN IF rst='1' THEN edop<=aa; contp<=0; ELSIF clk='1' AND clk'EVENT THEN edop<=edos; contp<=conts; END IF; END PROCESS; PROCESS(edop, pa, pb, temp, contp) --transiciones BEGIN CASE edop IS WHEN aa => IF pb='1' THEN temp<=ta; ELSE temp<=tmax; END IF; IF contp<temp-1 THEN conts<=contp+1; edos<=aa; ELSE conts<=0; edos<=ab; END IF; WHEN ab => temp<=ty; IF contp<temp-1 THEN conts<=contp+1; edos<=ab; ELSE conts<=0; edos<=bb; END IF; WHEN bb => IF (pa='1' OR pb='0') THEN temp<=tb; ELSE temp<=tmax; END IF; IF contp<temp-1 THEN conts<=contp+1; edos<=bb; ELSE conts<=0; edos<=ba; END IF; WHEN ba => temp<=ty; IF contp<temp-1 THEN conts<=contp+1; edos<=ba; ELSE conts<=0; edos<=aa; END IF; END CASE; END PROCESS; Va<='1' WHEN edop=aa ELSE '0'; Ra<='1' WHEN (edop=bb OR edop=ba) ELSE '0'; Vb<='1' WHEN edop=bb ELSE '0'; Rb<='1' WHEN (edop=aa OR edop=ab) ELSE '0'; Ya<='1' WHEN edop=ab ELSE '0'; Yb<='1' WHEN edop=ba ELSE '0'; END uno; Figura 6.3.7. Código VHDL alternativo para el semáforo
Diseño manual del semáforo. Los diseños que efectuamos manualmente en el capítulo
anterior (reconocedores de secuencia, contadores) se caracterizan por depender únicamente
del diagrama de estados; el semáforo requiere, además, de un temporizador. Este puede
implementarse por medio de un contador MSI con carga en paralelo (como el de la figura
6.2.8) o por un registro universal de carga y desplazamiento. En cualquiera de los casos,
detectamos las salidas del temporizador ta=4, tb=2, tmax=6, (consideramos que ty=1). Ahora,
denominamos como x1 y x2 a las señales que provocan las transiciones de estados aa→ab y
bb→ ba:
x1= tmax + (pb ∙ ta)
x2= tmax + tb ∙ (pa + pb´)
Denominamos a las variables de estado como q1 y q0; si codificamos los estados como
aa=00, ab=01, bb=11, ba=10, tenemos la tabla de transición 7.3.1 para el diseño por
MUXes:
Estado Presente Estado Futuro Condición Salidas
aa 00 00 x1’ Va, Rb, cnt
01 x1 Va, Rb, ld
ab 01 11 1 Aa, Rb
bb 11 11 x2’ Ra, Vb, cnt
10 x2 Ra, Vb, ld
ba 10 00 1 Ab, Ra
Tabla 6.3.1. Transiciones de la FSM del semáforo
De la tabla, se tiene
MUX1(0,2) = 0, MUX1(1,3) = 1
MUX0(0) = x1, MUX0(1) = 1, MUX0(2) = 1, MUX0(3) = x2’
Al inicio de aa y bb se activa la cuenta del contados (cnt=1); al final de dichos estados se
limpia el contador (Ld=1, se cargan ceros en el temporizador). Las salidas resultan entonces
Va = q1’∙ q0’, Vb = q1 ∙ q0, Ra = q1 ∙ q0 + q1 ∙ q0’= q1, Rb = q1’∙ q0’+ q1’∙ q0 = q1’
cnt = q1’∙ q0’∙ x1’+ q1 ∙ q0 ∙ x2’, Ld = q1’∙ q0’∙ x1 + q1 ∙ q0 ∙ x2
Aa = q1´ ∙ q0, Ab = q1 ∙ q0´
La lógica puede simplificarse si se utiliza un decodificador 2 a 4 excitado por las salidas q0
y q1 de los MUXes. Se dispone así de señales para los 4 estados, y no es necesario usar
compuertas AND para q1 y q0.
6.4. Síntesis de bancos de registros y memorias RAM (de lectura y escritura).
Un banco de registros contiene un número relativamente pequeño de registros (8,16,32); se
utiliza para guardar (escribir) información y recuperarla con facilidad. La escritura requiere
de una dirección aplicada a un decodificador del tamaño adecuado. En una computadora es
parte de la unidad central de proceso; una de sus funciones es la de proveer 2 operandos para
el procesador, por lo que posee 2 puertos de lectura; la información se lee mediante bits de
selección aplicados a sendos multiplexores.
En la figura 6.4.1 se muestra un banco de 8 registros de 16 bits cada uno, con 2 puertos de
salida. A un conjunto de señales de datos se le denomina un bus de datos, así que tenemos 2
buses de datos de salida (BusA y BusB), y uno de entrada al registro (Rin). La escritura se
realiza bajo el control de una señal RW de habilitación de escritura, y la dirección RDir que
proviene de un bus de direcciones; dicha dirección activa sólo un registro por medio del
decodificador.
Figura 6.4.1. Banco de registros de 2 puertos de salida y su símbolo
En la figura 6.4.2 se muestra un programa que sintetiza el banco. Para la escritura, se
direcciona el banco con la señal de tipo INTEGER intdir. Para el direccionamiento de los
registros de salida utilizamos el código clásico de los MUX con la cláusula WITH…SELECT.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC.STD.ALL; ENTITY bancoreg16 IS PORT(rw,clk: IN STD_LOGIC; rin: IN STD_LOGIC_VECTOR(15 DOWNTO 0); rdir,rra,rrb: IN STD_LOGIC_VECTOR(2 DOWNTO 0); busa,busb:OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); END bancoreg16; ARCHITECTURE uno OF bancoreg16 IS TYPE regis IS ARRAY (0 TO 7) OF STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL reg: regis:= (OTHERS => (OTHERS =>'0')); -- inicializa a ceros SIGNAL intdir: INTEGER RANGE 0 TO 7; BEGIN intdir<= TO_INTEGER(UNSIGNED(rdir)); -- dirección entera PROCESS(clk, rw, ld) -- escritura BEGIN IF clk='1' AND clk'EVENT THEN IF rw='1' THEN reg(intdir)<=rin; END IF; END IF; END PROCESS;
WITH rra SELECT busa<=reg(0) WHEN "000", reg(1) WHEN "001", reg(2) WHEN "010", reg(3) WHEN "011", reg(4) WHEN "100", reg(5) WHEN "101", reg(6) WHEN "110", reg(7) WHEN "111"; WITH rrb SELECT busb<=reg(0) WHEN "000", reg(1) WHEN "001", reg(2) WHEN "010", reg(3) WHEN "011", reg(4) WHEN "100", reg(5) WHEN "101", reg(6) WHEN "110", reg(7) WHEN "111"; END uno;
Figura 6.4.2. Programa VHDL del banco de registros.
Memoria RAM. Una memoria RAM opera en forma similar al banco de registros; permite el
acceso a un registro por medio de un sistema de decodificación a partir de una dirección dir,
y posee uno o 2 puertos de salida para la lectura. A diferencia de una memoria tipo ROM, la
RAM es volátil; no conserva su información al suspender la alimentación eléctrica.
En una memoria estática (SRAM) los registros están conformados por flip-flops tipo D. Las
memoria dinámicas, en cambio, utilizan capacitores para almacenar la información en vez de
flip-flops; los capacitores utilizan un área mucho menor de fabricación que los flip-flops, por
lo que las memorias dinámicas son las de mayor capacidad, aunque las estáticas operan con
mayor velocidad.
En la Figura 6.4.3 se muestra el programa VHDL de una pequeña memoria RAM de 16
palabras de 16 bits. Utiliza una sola dirección para lectura y escritura; la escritura se habilita
mediante la señal we (“write enable”), y opera en forma síncrona. La lectura es asíncrona.
Observe que en vez de simular un decodificador, direccionamos la palabra con un índice,
convirtiendo dir a entero usando la función TO_INTEGER.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY mema IS PORT(clk,we: IN STD_LOGIC; dir: IN STD_LOGIC_VECTOR(3 DOWNTO 0); min: IN STD_LOGIC_VECTOR(16 DOWNTO 0); mout: OUT STD_LOGIC_VECTOR(16 DOWNTO 0)); END mema; ARCHITECTURE uno OF mema IS TYPE memtype IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(16 DOWNTO 0); SIGNAL mem: memtype; BEGIN PROCESS(clk) BEGIN IF clk='1' AND clk'EVENT THEN IF we='1' THEN mem(TO_INTEGER(UNSIGNED(dir)))<=min; END IF; END IF; END PROCESS; mout<=mem(TO_INTEGER(UNSIGNED(dir))); END uno;
Figura 6.4.3. Modelo VHDL de una memoria RAM de un puerto y escritura síncrona
El compilador de Quartus II reconoce por el estilo del código que se describe una memoria
RAM de un puerto, una sola dirección para lectura y escritura, con entrada síncrona; esto es,
difiere de un banco de registros. Puede utilizar parte de la memoria incluida en un FPGA (ver
capítulo 8). Su diagrama RTL se muestra en la figura 6.4.4. El diagrama corresponde con un
modelo general parametrizable de una memoria RAM, con posibilidades de direcciones
diferentes de lectura y escritura, así como doble reloj.
Figura 6.4.4. Diagrama RTL del programa 6.4.3
En la figura 6.4.5 se muestra el programa de una memoria con un bus de salida implementado
con compuertas de 3 estados, de manera que el bus mout requiere de habilitación re para
escritura; de lo contrario la salida es de alta impedancia. La salida, además, se guarda en un
registro mdr.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; ENTITY memb IS PORT(clk,we,re: IN STD_LOGIC; dir: IN STD_LOGIC_VECTOR(3 DOWNTO 0); min: IN STD_LOGIC_VECTOR(16 DOWNTO 0); mdr: OUT STD_LOGIC_VECTOR(16 DOWNTO 0)); END memb; ARCHITECTURE uno OF memb IS TYPE memtype IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(16 DOWNTO 0); SIGNAL mem: memtype; SIGNAL mout: STD_LOGIC_VECTOR(16 DOWNTO 0); BEGIN PROCESS(clk) BEGIN IF clk='1' AND clk'EVENT THEN IF we='1' THEN mem(TO_INTEGER(UNSIGNED(dir)))<=min; END IF; mdr<=mout; END IF; END PROCESS; mout<=mem(TO_INTEGER(UNSIGNED(dir))) WHEN re='1' ELSE (OTHERS=>'Z'); END UNO;
Figura 6.4.5. Programa VHDL de una memoria SRAM con bus de salida de 3 estados
Figura 6.4.6. Diagrama RTL de la memoria del programa 7.4.5
6.5. Sistemas secuenciales Controladores.
La mayoría de los sistemas digitales de mediana a alta complejidad incluyen componentes
que deben ser controladas de alguna manera; el controlador es una máquina de estados finita,
o FSM. Modelamos entonces a un sistema secuencial como en la figura 6.5.1.
El controlador controla a un subsistema, como el procesador de una computadora, por
ejemplo, y recibe del subsistema la información necesaria para emitir las señales de control
adecuadas. Ejemplos de estas señales de control son: La señal Ld para cargar un registro, la
señal cnt para activar la cuenta de un contador, o las señales s de selección de un MUX.
Ejemplos de la información proporcionada por el sistema controlado son: La clave de la
operación que debe efectuar un procesador, una condición de desbordamiento, etc.
Denominamos z a las señales de control, y x a las del sistema controlado, que actúan como
entradas del controlador, como en la Figura 7.5.1. Al sistema controlado se le llama
frecuentemente la ruta de datos (del inglés “datapath”), o arquitectura. Al sistema completo
se le conoce también como una FSMD.
Figura 6.5.1. Modelo general de un sistema secuencial con controlador (FSMD)
El diseño de un sistema requiere entonces de la especificación de la ruta de datos, que incluye
componentes combinacionales y secuenciales como los que hemos estudiado, además del
diseño del autómata. Describimos a continuación los pasos fundamentales para el diseño.
Pasos del diseño de un sistema completo FSMD.
1) Comprender el problema y sus especificaciones. Este paso es obvio, y no requiere más
explicación.
2) Establecer un diagrama a bloques, identificando las entradas y salidas. De ser necesario,
elaborar un diagrama de tiempo de la respuesta esperada.
3) Definir la ruta de datos. Identificar todas las señales que deben controlarse.
Los pasos siguientes se refieren al controlador:
4) Establecer el diagrama de estados del autómata, y su tabla o mapa correspondiente.
5) Eliminar estados redundantes, si existen.
6) Asignar claves binarias a los estados, con el objetivo de simplificar el diseño y eliminar
riesgos.
7) Establecer el mapa o tabla de transición de estados con los estados codificados.
8) Seleccionar el tipo de elementos de memoria (Flip-flops)
9) Establecer las tablas o mapas de entrada a los elementos de memoria, para obtener sus
ecuaciones simplificadas (diseño del decodificador de estados siguiente, DES)
10) Establecer las tablas o mapas de salida (diseño del decodificador de salidas, DS).
11) Simulación y pruebas del controlador y del sistema completo.
Suponiendo que el problema ha sido comprendido, y que están debidamente identificadas las
entradas y salidas, comentaremos brevemente los pasos subsecuentes:
Ruta de datos: Este es un paso fundamental. Cada sistema tiene distintos requerimientos;
puede necesitarse de un sumador, o de cierta cantidad de registros, de comparadores, etc. Es
posible que la arquitectura se modifique posteriormente para simplificar el controlador; el
proceso suele ser iterativo. Antes de presentar los diseños específicos de este capítulo,
trataremos algunos temas relacionados con la arquitectura, como el flujo de datos y el manejo
de señales asíncronas.
Diagrama de estados. Hemos estudiado ya ejemplos sencillos de este paso. El proceso es
similar al de programación de una computadora, y condensa la parte más creativa del diseño.
Se presentarán varios ejemplos más que ilustran el proceso.
Eliminación de estados redundantes. Existe la posibilidad de que, al elaborar un diagrama
con muchos estados, se propongan más de los necesarios; algunos pueden ser equivalentes, si
para cada secuencia de entrada posible se produce la misma secuencia de salida posible. Dos
estados equivalentes pueden representarse por un solo estado.
Asignación de claves binarias. La asignación de claves a los estados afecta al diseño final
del autómata. No existe una teoría para una asignación óptima, pero sí un par de reglas
pragmáticas que dan lugar a circuitos simplificados. La primera regla consiste en asignar
claves contiguas (que difieren sólo por una variable) a estados que tienen un sucesor común.
La segunda regla consiste en asignar claves contiguas a estados que suceden a otro estado
común. Esta regla fue aplicada para los estados b, c, d y e del ejemplo 5.4.1. Por otro lado, es
claro que al estado inicial del autómata le corresponde la clave “00...0” pues suele resultar de
un borrado inicial.
Selección de flip-flops. Hay casos en los cuales sabemos cuál de los tipos de flip-flops es el
más conveniente para un diseño sencillo; por ejemplo, el T en contadores binarios naturales.
Pero cuando utilizamos PLDs, la síntesis se realiza con los flip-flops D de las macroceldas.
Los flip-flops D, además, son más económicos al diseñar con CI MSI, pues están disponibles
como registros con varios flip-flops. Por otro lado, los de tipo T o JK se prestan perfectamente
para guardar variables que indiquen una condición lógica (banderas) para la ruta de datos.
Diseño del DES y del DS. La síntesis de las funciones obtenidas de los mapas o tablas puede
realizarse por medio de CI SSI o MSI (compuertas, MUX), o por medio de PLD
combinacionales (PROM, PLA, PAL). Si se utilizan PLD secuenciales, entonces el diseño
completo, incluyendo la arquitectura, puede realizarse en un solo circuito integrado (si su
capacidad lo permite). El diseño puede incluir incluso la arquitectura o sistema controlado.
Simulación y pruebas. La simulación de un sistema es invaluable; permite observar el
comportamiento de los circuitos diseñados sin necesidad de utilizar un solo dispositivo.
Hemos mencionado anteriormente que los fabricantes más importantes de PLD incluyen en
sus herramientas programáticas simuladores para estudiar la respuesta de un circuito digital.
Además, proveen el hardware necesario para programar y probar totalmente el PLD. Aún
cuando el diseño se implemente con CI SSI y MSI, se recomienda el uso de un simulador.
6.6. Microoperaciones y flujo de datos.
Esta sección se incluye para complementar el tema de la trayectoria de datos; introducimos el
concepto de microoperación, utilizado en sistemas de cómputo, y el de Bus.
Definimos una microoperación como la operación que se realiza en un solo período de reloj.
Salvo en casos especiales, en los que se espera la ocurrencia de un evento externo, existe
alguna actividad en un sistema secuencial síncrono al ocurrir un pulso de reloj: Un cambio de
estado (o el incremento de la cuenta de un contador), con la posible aparición de una o varias
señales de control que activan a uno o varios dispositivos.
La mayoría de microoperaciones en un sistema complejo como una computadora se
relacionan con la transferencia de información entre diferentes registros. En la figura 7.6.1 se
muestra la conexión de 2 registros A y B, donde la salida de B alimenta a A. Usamos líneas
llenas para distinguir señales de n bits de señales de 1 sólo bit. Se pretende que A acepte la
carga de B cuando sólo cuando ocurra una condición, como cond = x · t1. Esto indica cuando
debe activarse la señal Ld de carga; podemos representar la microoperación como x · t1: A
B. En código VHDL, podemos escribir cualquiera de las 2 instrucciones secuenciales
siguientes: IF cond=(x AND t1) THEN A<=B
IF cond=(x AND t1) THEN Ld<=’1’; ELSE Ld<=’0’.
Figura 6.6.1 Transferencia controlada de información de un registro a otro
Al diseñar con circuitos SSI o MSI se requiere hacer referencia a la señal de control Ld. Al
realizar la misma función en un PLD complejo con VHDL, basta la asignación A<=B para
que exista una señal de control de carga, sin hacer referencia a ella. Esto es similar a
programar una suma utilizando el paquete numérico; x<=A+B implica la inclusión de un
sumador sin definirlo explícitamente.
Cuando la señal que debe recibir el registro A proviene de varias fuentes, las canalizamos al
través de MUX (1 MUX por bit). En la figura 7.6.2 presentamos 2 registros fuente: B y C,
con las microoperaciones x ∙ t1: AB, t2: AC. La señal Ld debe activarse entonces como
Ld = x · t1 + t2; por otro lado, si conectamos C a la entrada 1 de los MUXES, tenemos que s1
= t2. Mientras no ocurra t2, la señal de entrada a A será B, pero A se cargará con dicha señal
sólo si se activa Ld, cuando ocurre x · t1. La instrucción VHDL secuencial correspondiente
puede escribirse con una cláusula CASE s IS, que ya hemos estudiado al caracterizar a un
MUX. Una instrucción concurrente podría ser Ld<=’1’ WHEN cond= ((x and t1) OR t2) ELSE ‘0’;
Pensemos ahora en el problema inverso: La información de un registro R4 debe canalizarse a
uno de varios destinos: R0, R1, R2 o R3. Tenemos ahora la necesidad de un decodificador que
seleccione la señal Ld correspondiente como en la figura 7.6.3. Las condiciones de la
transferencia se reflejan directamente en la dirección d1 y d2.
Figura 6.6.2. Selección de 2 registros fuente mediante un juego de MUXes
Bus. Consideramos ahora el mismo conjunto de 4 registros, donde cada registro puede ser
fuente y destino; tenemos entonces el sistema de la figura 6.6.4
. Al conjunto de cables de salida del grupo de MUXes que seleccionan al registro fuente se le
conoce como un Bus de datos. La información del Bus se carga de nuevo al registro que se
seleccione por el decodificador. La transferencia, vista como una microoperación, puede
escribirse como
Cond: Rj Ri, donde Rj es el registro destino y Ri el registro fuente.
Figura 6.6.3. Selección de múltiples destinos mediante un decodificador
En muchos sistemas se utilizan dispositivos triestado en vez de MUXes para seleccionar una
fuente, como se muestra en la figura 6.6.4. Recordemos que un triestado sin activar representa
un circuito abierto (estado de alta impedancia Z), y no presenta carga alguna por tanto a los
alambres del Bus. Para asegurar que sólo un registro active al bus, requerimos de nuevo
decodificadores para activar al conjunto de dispositivos triestado correcto.
Figura 6.6.4. Banco de registros con un bus de datos usando MUXes
Figura 6.6.5. Banco de registros con bus de datos usando compuertas triestado
6.7. Señales externas asíncronas y problemas temporales.
Las señales x que recibe el controlador del exterior o del subsistema controlado pueden ser
asíncronas respecto del reloj del controlador. Recordemos que, para que sean aceptadas
confiablemente por los flip-flops del controlador, deben cumplir con los tiempos de
establecimiento ts y retención th. Una primera solución a este problema consiste en
sincronizar una señal asíncrona x* para obtener una señal sincronizada x, mediante un flip-
flop D, como se muestra en la Figura 6.7.1.
Figura 6.7.1 Sistema sencillo para sincronizar una señal asíncrona x*
Sesgo de reloj. Otro problema que puede presentarse proviene de utilizar el reloj para realizar
operaciones lógicas; por ejemplo, si pretendemos inhibir la carga de un registro cuando ocurre
una condición cond, se podría utilizar una compuerta AND para obtener cond·clk. Esta
compuerta introduce un retraso en el disparo del registro, que no actuaría en forma síncrona
respecto a los demás dispositivos secuenciales del sistema. Por tanto, no se recomienda
introducir lógica en el reloj, sino utilizar un registro con habilitación de carga Ld.
Tiempos de espera. Por lo general, un subsistema controlado, o un operador humano que
introduce datos, presentan velocidades de operación y reacción muy distintas a la del
controlador. Un operador humano, por ejemplo, tarda fracciones de segundo o algunos
segundos en teclear un caracter, o en accionar interruptores. Una impresora puede tardar hasta
varios minutos en ejecutar una impresión, mientras la computadora ya está solicitando otra.
Tenemos entonces un problema de acoplamiento temporal, que se resuelve mediante un
protocolo de comunicación.
Un protocolo básico, denominado handshake (apretón de manos), se muestra en la figura
6.7.2a. El subsistema A pretende enviar un dato a B mediante la señal de control tomadato;
B puede no haber terminado una tarea previa, y A espera hasta que B
confirme la recepción con la señal ya. Finalmente, A confirma a B que ha recibido ya con
otra señal gracias, y cada subsistema queda liberado de responsabilidades hasta una nueva
solicitud. Antes, ningún proceso pudo avanzar en tanto no recibiera comunicación del otro
subsistema. En la figura 6.7.2b se muestra la relación causa-efecto de las señales. La notación
de las señales con doble flecha (hacia arriba y hacia abajo) significa pulso completo; flecha
hacia arriba indica señal que enciende, y queda encendida en tanto no se presente otra instancia
con flecha hacia abajo.
Figura 6.7.2. Protocolo de comunicación asíncrono entre 2 subsistemas
Ejemplo: Un sistema solicita a un operador humano con la señal hit (luminosa o audible) que
suministre datos x* mediante interruptores o un teclado, y debe esperarlos. El operador
notifica al sistema que están listos mediante un botón pulsador con la señal ry (equivalente al
ENTER de un teclado). El sistema confirma la recepción mediante una señal ok, y
supuestamente podría continuar con su proceso. Pero se puede presentar el problema siguiente
si el sistema es de alta velocidad: El operador mantiene aún oprimido el pulsador (esto toma
fracciones de un segundo), y el sistema vuelve a solicitar más datos; ¡recibiría entonces
duplicados los anteriores! Este problema puede resolverse de 2 formas: La primera consiste
en completar el “handshake” por medio de la señal ry´ (esperando que el operador levante su
dedo), como se muestra en la figura 6.7.3. Una segunda solución consiste en utilizar un
monopulsador, mostrado en la figura 6.7.4.
Figura 6.7.3. Protocolo asíncrono entre un operador humano y un sistema rápido
El circuito incluye un primer flip-flop para sincronizar a x* (el asterisco indica asincronía)
para obtener xs a partir del primer pulso del reloj del sistema; entretanto q´=1, por lo que xp
= xs. Al segundo ciclo de reloj q = xs = 1, y xp = 0. El pulso xp dura, entonces, sólo un período
de reloj. Por tanto, se hace innecesaria la espera de ry´para que el sistema cambie de estado,
a costa de un flip-flop adicional del monopulsador.
Figura 6.7.4. Sistema monopulsador
Restricciones temporales. Consideramos ahora la velocidad de operación de un sistema
secuencial, relacionado con la frecuencia f del reloj. Denominamos Tc= 1/f al período del
reloj, tp al tiempo de propagación total del registro R1 y del circuito combinacional CC de la
figura 6.7.5, y ts al tiempo de establecimiento del registro R2. De la figura, es posible apreciar
claramente que el período debe cumplir con la condición
Tc≥ tp + ts
de donde se infiere la máxima frecuencia permisible del reloj. Si tp = ts= 5ns, por ejemplo, la
máxima frecuencia de operación del circuito es de 200Mhz.
Figura 6.7.5. Retardos
Picos ruidosos (del inglés glitches). La salida de un circuito combinacional puede presentar
ruido en forma de picos resultantes de señales que arriban a destiempo. Una solución para que
una salida esté libre de estos picos es la de cargar la salida combinacional a un registro D. El
reloj del registro puede tomarse con la fase opuesta del reloj general del sistema para
minimizar el retardo (Figura 6.7.6).
Figura 6.7.6. Eliminación de picos ruidosos por medio de un registro de salidas
6.8. Candado electrónico flexible con entrada serial.
Nuestro primer ejemplo es sencillo, pero ilustrativo. Se pretende que el dueño del candado
pueda ajustar la secuencia de n bits que representa la combinación correcta, así como el
número n de bits de la combinación, mediante interruptores, con n≤8. Cualquier usuario que
pretenda abrir el candado ingresará cada bit x en serie, mediante un interruptor y un pulsador
ry; cuando considere que la secuencia es la correcta, pulsará un botón pulsador abre. Si la
secuencia es efectivamente la correcta, se activa la salida ok que acciona al solenoide del
pestillo. De lo contrario, el sistema debe establecerse en un estado de error; sólo el dueño
podrá destrabar el mecanismo mediante un borrado asíncrono que cierra el candado y
establece el estado inicial. Se aclara que el estado de error se produce al primer bit incorrecto
del usuario.
Como primer paso, identificamos las entradas y salidas externas: tenemos el bit x, la señal ry
y la señal abre como entradas, y ok como única salida. Adicionalmente, el sistema requiere el
reloj clk y la señal de borrado asíncrono rst. Estas serían, por cierto, las señales a declarar en
la entidad si se sintetiza el sistema con VHDL.
La arquitectura correspondiente a la interfaz con el usuario se muestra en la Figura 6.8.1.
Incluye 2 botones pulsadores con circuitos monopulsadores MP para ry y abre, y un
interruptor simple SW que proporciona voltaje alto o bajo para x. Se muestra un botón
pulsador adicional PB para el borrado asíncrono rst.
Figura 6.8.1. Circuitos de interfaz de usuario del candado serial
Pensemos ahora en la arquitectura requerida para detectar la secuencia correcta. Esta es
establecida mediante interruptores por el dueño, y debe compararse bit por bit con la señal x
del usuario. Una solución sencilla y elegante consiste en utilizar un MUX 3 a 8 como
convertidor paralelo a serie, direccionado por un contador ascendente módulo 8. El contador
aumenta su cuenta cnt con cada bit que ingresa el usuario, por su señal de control inc. El
contador sirve también para comparar el número de bits (numbits) de la combinación que fija
el dueño con cnt; se propone por tanto un comparador de 3 bits (sería de 4 si se emplea un CI
MSI), y denominamos Y a la salida correspondiente a la igualdad. La salida del MUX se
compara con el bit x, mediante una compuerta XNOR, de salida W. Si W=1, el bit es correcto.
(Véase la figura 6.8.2).
Figura 6.8.2. Arquitectura del candado serial
Nos concentramos ahora en el controlador. Visto como una caja negra, recibe las entradas ry
y abre del usuario, W, Y del sistema controlado; debe generar las salidas inc para el contador,
y ok para el cerrojo. Un sistema de 4 entradas y 2 salidas.
Procedemos ahora a describir el proceso creativo requerido para programar el controlador.
Podemos representarlo por una tabla, o directamente por un diagrama. Pensemos
primeramente en un estado inicial, S0, resultante del borrado asíncrono rst. Este estado nos
conduce a un segundo estado S1, en el cual esperamos alguna señal del usuario (abre o ry).
Si se presenta abre´· ry, pasamos al estado S6 para verificar que W=1; si la prueba falla,
vamos al estado de error S5. De lo contrario, debemos verificar si el usuario no ha introducido
más bits de los necesarios, probando la variable Y. Si Y=0, esperamos más bits; pasamos
entonces al estado S3 en el cual activamos inc, y regresamos a S1. Si Y=1, la secuencia es
correcta hasta ahora, y esperaríamos la señal abre. Esto lo verificamos en el estado S2. Si el
usuario pulsa ry, ha introducido un bit de más, y pasamos al estado de error. Si pulsa abre,
¡felicidades! El candado se abre en el estado S4.
El diagrama MDS se muestra en la figura 6.8.3. Antes de proceder a la implementación del
controlador, es conveniente resaltar algunos aspectos del mismo. Primeramente, notamos que
hay 6 estados. Si la implementación se realizara sin codificación, eliminaríamos S0, ya que
podemos empezar mediante rst directamente en S1. De lo contrario, el único efecto de
conservar S0 es utilizar un ciclo del reloj, que, en este problema, no es relevante. Usar 6
estados o 5 estados requiere del mismo número de flip-flops: tres.
Observemos ahora la conveniencia de haber utilizado monopulsadores. Al ocurrir un ry,
tenemos la secuencia de estados S1→S6→S3, y volvemos a S1 si Y=0. Esto es, empleamos
3 pulsos de reloj para reiniciar la espera de un bit. El tiempo total de estos períodos del reloj
es mucho menor que el que permanecería activado ry si no utilizáramos un monopulsador,
por lo que se registraría el mismo bit anterior. De no utilizar un monopulsador, requeriríamos
un estado adicional para esperar que se apague ry (handshake completo). Por último,
observamos una falla del controlador, que se relaciona con la señal Y del comparador. Como
el contador se incrementa después de cada bit, cuando el usuario introduce el último bit
válido, Y vale aún 0, y no se produciría la transición correcta al estado S2. Esto puede
corregirse definiendo numbits no por el número total n de bits, sino como n-1.
Figura 6.8.3. Diagrama MDS del controlador del candado serial
Para la implementación, asignamos las claves numéricas k correspondientes a los índices
utilizados para nombrar a los estados, Sk. Esto es, S0 = 000, S1 = 001, etc. La clave 111 es
irrelevante. La tabla de transición es la 6.8.1. Si sintetizamos el controlador por MUX,
asignando 0 a las condiciones irrelevantes, tenemos
MUX2(0,3,7) = 0, MUX2(4,5) = 1, MUX2(1,2) = abre + ry, MUX2(6) = W´
MUX1(0,3,4,5,7) = 0, MUXC1(1) = ry · abre´, MUX1(2) = ry´· abre´, MUX1(6) = W
MUX0(4,7) = 0, MUX0(0,3,5) = 1, MUX0(1) = abre + ry´, MUX0(2) = ry,
MUX0(6) = W´+ Y´ inc=q2’q1q0 ok=q2q1’q0’
ESTADO PRESENTE ESTADO FUTURO CONDICION SALIDAS
q2q1q0 Q2Q1Q0
000 001 1 -
001 110 ry·abre´ -
001 ry´·abre´ -
101 abre -
010 010 ry´·abre´ -
100 ry´·abre -
101 ry -
011 001 1 inc
100 100 1 ok
101 101 1 -
110 101 W´ -
011 W·Y´ -
010 W·Y -
111 irrelevante
Tabla 6.8.1. Tabla de transición de estados del controlador del candado serial
En la figura 6.8.4 se muestra el programa VHDL para la síntesis del candado mediante un
PLD (salvo la interfaz del usuario). No se incluye el código de los monopulsadores, pues el
simulador nos permite especificar la duración de las señales ry y abre por un solo ciclo. Se ha
usado una clave de pocos bits (011) por el elevado número de ciclos que ocurren en el proceso,
y poder visualizar confortablemente la simulación. Tanto el contador como los estados se han
declarado como enteros.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY candado IS
PORT(rst,clk, ry, abre, x: IN STD_LOGIC; ok: OUT STD_LOGIC); END candado; ARCHITECTURE uno OF candado IS SIGNAL w, y, incr: STD_LOGIC; SIGNAL ep,es: INTEGER RANGE 0 TO 6; -- estados SIGNAL cont: INTEGER RANGE 0 TO 7; CONSTANT clave: STD_LOGIC_VECTOR(0 TO 2):="011"; -- clave CONSTANT numbits: INTEGER:=2; -- uno menos que n BEGIN PROCESS (ep, ry,abre,w,y)-- transiciones BEGIN es<=ep; CASE ep IS WHEN 0=> es<=1; WHEN 1=> IF (abre='0' AND ry<='0') THEN es<=1; ELSIF abre='1' THEN es<=5; ELSE es<=6; END IF; WHEN 2=> IF ry='1' THEN es<=5; ELSIF (ry='0' AND abre='1') THEN es<=4; ELSE es<=2; END IF; WHEN 3=> es<=1; WHEN 4=> WHEN 5=> WHEN 6=> IF w='0' THEN es<=5; ELSIF (w='1' AND y<='0') THEN es<=3; ELSE es<=2; END IF; END CASE; END PROCESS; PROCESS(rst, clk)—cambios con el reloj (estado y contador) BEGIN IF rst='1' THEN cont<=0; ep<=0; ELSIF (clk'event and clk='1') THEN ep<=es; IF incr='1' THEN cont <=cont+1;END IF; END IF; END PROCESS; -- señales de control y<='1' WHEN cont=numbits ELSE '0'; w<='1' WHEN clave (cont)=x ELSE '0'; incr <='1' WHEN ep=3 ELSE '0'; ok <='1' WHEN ep=4 ELSE '0'; END uno;
Figura 6.8.4. Programa de VHDL del candado serial
6.9 Simulador de un juego profesional de dados
Simulamos la tirada de dados como sigue: Un operador humano suministra mediante
interruptores o teclado un conjunto de 2 números del 1 a 6, que representan los posibles
valores de arrojar 2 dados, d1 y d2. Los valores ingresan al sistema mediante la señal ry de un
monopulsador (o ENTER en el caso de teclado). Para comenzar el juego, pulsar un borrado
asíncono rst.
Las reglas del juego son: Gana si la suma es igual a 7 u 11; pierde si la suma es igual a 2, 3
o 12. Si la suma es diferente a dichos valores, se guarda el resultado suma1 y se proporciona
un nuevo par de valores. En esta segunda fase, gana sólo si la nueva suma, suma2, es igual a
suma1; pierde sólo si suma2 = 7. En caso de que suma2 sea diferente a 7 o suma1, se repite
el proceso cuantas veces sea necesario, hasta que pierda o gane.
Definida ya la interfaz del operador, queda por determinar el resto de la arquitectura: se
requiere desde luego de un sumador y un registro R para guardar suma1; además, un
comparador con entradas suma1 y suma2. Es necesaria también la lógica para detectar los
valores 2, 3, 7, 11 y 12, y cualquier valor p fuera del rango, lo que se logra con un
decodificador a la salida del sumador, como se muestra en la figura 7.9.1.
Figura 6.9.1. Arquitectura del simulador del juego de dados
Pensemos ahora en el controlador, que recibe las señales siguientes: ry del operador, así como
los valores detectados por el comparador v7-11, v2-3-12, v7 y p, así como el valor = del
comparador. Las salidas de control son: Ld (carga del registro R) y tira, solicitud al operador.
Las salidas externas son gana y pierde. En total, 5 entradas y 4 salidas; añadimos un borrado
asíncrono rst para todo el sistema, y, desde luego, el reloj clk.
Figura 6.9.2. Diagrama MDS del simulador del juego de dados
Pasamos ahora al diagrama de estados: En S0 esperamos datos del operador, emitiendo la
señal tira. Al recibir los datos, estos se suman por un sumador combinacional, de manera que
suma1 está disponible casi de inmediato, y guardamos su valor en R. De S1 pasamos a S2
si se afirma v7-11, o a S3 si se afirma v2-3-12, emitiendo las señales de salida gana o pierde
respectivamente. Si ocurre p, pasamos a un nuevo estado de espera S5 hasta recibir nuevos
datos. De acuerdo con estos datos, de S4 pasamos ya sea a S2, a S3 o a S5 de nuevo si se
requiere otra tirada. En el diagrama MDS que se muestra en la figura 6.9.2, añadimos un
estado S6 para retornar a S5 en vez de efectuar la transición desde S4. No se aumenta el
número de flip-flops necesarios (3), y el período adicional del reloj no es relevante para este
problema. Si codificamos los estados con números binarios correspondientes a los índices
(S0=000, S1=001, etc.), tenemos las transiciones siguientes de la tabla 6.9.1:
ESTADO PRESENTE ESTADO SIGUIENTE CONDICION SALIDAS
q2q1q0 Q2Q1Q0 000 001 ry tira
000 ry´ tira
001 010 v7-11 Ld
011 v2-3-12 Ld
101 p
010 010 1 gana
011 011 1 pierde
100 010 =
011 v7
110 (=´.v7´)
101 101 ry´ tira
100 ry tira
110 101 1
111 irrelevante
Tabla 6.9.1. Tabla de transición del controlador del juego de dados
La síntesis por MUXes conduce a los resultados siguientes:
MUX2(0,2,3,7) = 0, MUX2(5,6) = 1, MUX2(4) = (=´.v7´), MUX2(1)=p
MUX1(0,5,6,7) = 0, MUX1(2,3,4) = 1, MUX1(1) = v7-11+v2-3-12 = p´
MUX0(2,7) = 0, MUX0(5) = ry´, MUX0(1) = v2-3-12 + p = v7-11, MUX0(3,6) = 1
MUX0(4) = v7 MUX0(0) = ry
Las salidas resultan:
tira = q2´·q1´· q0´+ q2 · q1´· q0 Ld = q2´· q1´· q0
gana=q2´· q1 · q0´ pierde = q2´· q1· q0
La síntesis de todo el sistema puede realizarse por medio un FPGA o un CPLD, mediante el
código VHDL siguiente, en el cual separamos el proceso del reloj, que incluye la carga del
registro, del proceso de las transiciones de estados. Estos se han definido como enteros.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY dados2 IS PORT (d1,d2: IN INTEGER RANGE 0 TO 6; clk, rst, ry: IN STD_LOGIC; gana, pierde: OUT STD_LOGIC); END dados2; ARCHITECTURE uno OF dados2 IS SIGNAL suma1, suma2: INTEGER RANGE 0 TO 12; SIGNAL ld: STD_LOGIC; SIGNAL ep,es: INTEGER RANGE 0 TO 6; BEGIN PROCESS (ry, rst, ep, suma1, suma2) --transiciones de estados BEGIN CASE ep IS WHEN 0 => IF ry='1' THEN es<=1; ELSE es<=0; END IF;
WHEN 1=> IF (suma1=7 OR suma1=11) THEN es<=2; ELSIF (suma1=2 OR suma1=3 OR suma1=12) THEN es<=3; ELSE es<=5; END IF; WHEN 2=> IF rst='1' THEN es<=0; ELSE es<=2; END IF; WHEN 3=> IF rst='1' THEN es<= 0; ELSE es<=3; END IF; WHEN 4=> IF suma1=suma2 THEN es<=2; ELSIF suma1=7 THEN es<=3; ELSE es<=6; END IF; WHEN 5=> IF ry='1' THEN es<=4; ELSE es<=5; END IF; WHEN 6 => es<=5; END CASE; END PROCESS; PROCESS (clk, rst, suma1,ld) -- eventos síncronos BEGIN IF rst='1' THEN ep<=0; ELSIF (clk='1' AND clk'EVENT) THEN ep<= es; IF ld='1' THEN suma2<=suma1; END IF; END IF; END PROCESS; -- señales de control y suma ld<='1' WHEN ep<=1 ELSE '0'; suma1<=d1+d2; gana<='1' WHEN ep=2 ELSE '0'; pierde<='1'WHEN ep=3 ELSE '0'; END uno;
Figura 6.9.3. Programa VHDL del simulador de un juego de dados.
6.10 Sistema de control de una máquina surtidora de café.
Consideremos una máquina que surte café en vaso, por un precio de $7.00. Acepta monedas
de $1, $2, $5 y $10 pesos. Consiste de 3 subsistemas electromecánicos:
1. Receptor de monedas (RM). Determina el valor de una moneda de acuerdo con su
peso y tamaño, y proporciona al sistema de control una señal de moneda presente, MP,
y una señal w de 4 bits que indica su valor. Recibe del controlador una señal clr para
limpiar el mecanismo y recolectar las monedas en un receptáculo interior.
2. Unidad de cambio (UC). Proporciona el cambio requerido en monedas de $1.00,
bajo el comando de una señal SP (suelta peso); indica con YA que ha entregado
una moneda.
3. Servidora de café (SC). Suelta el vaso y regula el flujo del líquido; actúa bajo el
comando SL (suelta líquido), sólo cuando el monto en pesos es exacto, o se ha
proporcionado el cambio correspondiente. Notifica al sistema de control con OK la
terminación del proceso.
Figura 6.10.1. Diagrama a bloques de la máquina surtidora de café
Todas las señales de salida de estos subsistemas son compatibles eléctricamente con TTL y
CMOS, y tienen una duración aproximada de 200ms. Son claramente asíncronas respecto al
sistema de control que pretendemos diseñar. En la figura 6.10.1 se muestra un diagrama a
bloques de la máquina, y en la figura 6.10.2 el algoritmo por implementar. Notar que la
variable Sum acumula el valor de las monedas, y se decrementa con cada moneda devuelta
hasta que sea igual al costo de $7 pesos.
Pensemos ahora en el hardware necesario para el proceso descrito. Primeramente, se requiere
de un acumulador, para determinar el monto sum. Un acumulador, como su nombre lo indica,
consiste de un sumador que alimenta a un registro; recibe un dato externo, y el dato del propio
registro.
Figura 6.10.2. Algoritmo para el controlador
La salida del acumulador debe compararse con el costo de $7 pesos, por lo que se impone el
uso de un comparador. Por último, si se excede en el acumulador el costo, hay que
proporcionar cambio; requerimos entonces que el acumulador sea capaz también de restar, o
bien utilizar un contador decreciente con carga en paralelo. Adoptaremos esta alternativa, y
denominamos q a la salida del contador. Proponemos entonces la ruta de datos de la figura
6.10.3.
El sumador recibe el valor de la moneda w y el monto acumulado sum, y lo carga en un primer
registro R1 con el flanco positivo de MP. Denominamos suma1 a esta señal. . Esta suma se
carga en un registro R2 de salida sum al cesar la señal MP; notar que MP y MP´ están
aplicadas a las entradas de reloj de R1 y R2 (operación asíncrona).
Figura 6.10.3. Arquitectura de acumulación del controlador
La señal sum se transfiere al contador, de salida q, con el reloj clk, bajo el control de su
entrada de habilitación Ld; el contador es el único dispositivo con reloj, pues se requiere para
su correcto funcionamiento. Cuando se devuelve cambio, el contador se decrementa con la
señal dec, sin afectar al acumulador, ya que ha cesado la señal MP, y es la señal q la que se
compara con el precio para determinar si es mayor, menor o igual.
MPacumula
sum<7 sum=7 SL
SP
SUM=SUM-1
V
V
F V
F
Nos avocamos ahora al diseño del controlador. Pensemos en un estado inicial a con un reset
asíncrono rst de mantenimiento e inicialización (adicional a la señal síncrona clr de borrado).
La máquina se encuentra siempre en dicho estado en espera de un cliente, hasta que aparezca
la señal MP. Pasamos entonces a un estado b en el cual esperamos que cese MP (handshake);
para entonces tenemos ya un valor de sum. Pasamos al estado h, en el cual se carga sum al
contador (señal Ld). Seguimos al estado c, en el cual se toman las decisiones: si la señal del
comparador es menor, regresamos al estado a por más monedas. Si es igual, procedemos al
estado d, y si mayor, al estado f. En d se emite SL, y esperamos la respuesta OK, pasando al
estado d en el cual se emite clr, y regresamos al estado a.
Si el comparador presenta la señal mayor, pasamos de c a f, emitiendo la señal SP, y esperamos
la respuesta asíncrona YA; en el estado g se genera la señal dec, con lo cual se decrementa el
contador, y volvemos al estado c para una nueva comparación. Este ciclo se repite hasta
obtener igual, y pasar a d. El diagrama MDS se presenta en la figura 6.10.4, y la tabla de
transición en la tabla 6.10.1, con la siguiente asignación de estados: a=000, b=001, h=010,
c=011, d=110, e=111, f=110, g=101 para las variables de estado q2q1q0. ESTADO PRESENTE ESTADO SIGUIENTE CONDICION SALIDAS
q2q1q0 Q2Q1Q0 000 000 MP´
001 MP
001 001 MP
010 MP´
010 011 1 Ld
011 000 <
100 >
110 =
100 101 YA SP
100 YA´
101 011 1 DEC
110 111 OK SL
110 OK´
111 000 1 clr
Tabla 6.10.1. Transiciones de estados del controlador de la máquina de café.
Figura 6.10.4. Diagrama MDS del controlador de la máquina de café
Dejamos como ejercicio al lector la implementación del controlador por MUX o diseño
tradicional para la síntesis con compuertas, PAL o PLA. Para la síntesis por CPLD o FPGA
del controlador, tenemos el programa VHDL de la figura 7.10.5. La simulación se muestra en
la figura 6.10.6, con una entrada de $10.00.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY cafe1 IS
PORT(w: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
clk, mp, ya, ok,rst : IN STD_LOGIC;
sp,sl: OUT STD_LOGIC);
END cafe1;
ARCHITECTURE uno OF cafe1 IS
TYPE estado IS (a,b,c,d,e,f,g,h);
SIGNAL suma1s, suma1p, qs, qp: UNSIGNED(3 DOWNTO 0);
SIGNAl menor, igual, mayor,clr,ld,dec: STD_LOGIC;
SIGNAL ep,es: ESTADO;
CONSTANT precio: INTEGER:=7;
BEGIN
PROCESS(mp, clr, rst) -- carga valor de moneda cuando se presenta mp
BEGIN
IF rst='1' THEN suma1p<=(OTHERS=>'0');
ELSIF (mp='1' AND mp'EVENT) THEN suma1p<=suma1s;
END IF;
END PROCESS;
suma1s<=UNSIGNED(w)+qs;
PROCESS(mp,clr,rst) -- pasa valor suma1 a sum al finalizar mp
BEGIN
IF clr='1' OR rst='1' THEN qs<=(OTHERS=>'0');
ELSIF (mp='0' AND mp'EVENT) THEN qs<=suma1p;
END IF;
END PROCESS;
PROCESS(clk, clr, ld) -- registro y contador descendente, síncrono
BEGIN
IF clr='1' THEN qp<=(OTHERS=>'0');
ELSIF clk='1' AND clk'EVENT THEN
IF ld='1' THEN qp<=qs;
ELSIF dec='1' THEN qp<=qp-1;
END IF; END IF;
END PROCESS;
PROCESS(clk,rst) -- cambio de estado con reloj
BEGIN
IF rst='1' THEN ep<=a;
ELSIF clk='1' AND clk'event THEN ep<=es;
END IF;
END PROCESS;
PROCESS(ep,mp,menor,igual,ok,ya) -- transiciones de estados
BEGIN
es<=ep; sp<='0'; sl<='0'; dec<='0'; ld<='0'; clr<='0'; dec<='0';
CASE ep IS
WHEN a=> IF mp='1' THEN es<=b; END IF;
WHEN b=> IFmp='0' THEN es<=h; END IF;
WHEN c=> IF menor='1' THEN es<=a; ELSIF igual='1' THEN es<=d; ELSE es<=f;
END IF;
WHEN d=> sl<='1'; IF ok='1' THEN es<=e; END IF;
WHEN e=> clr<='1'; es<=a;
WHEN f=> sp<='1'; IF ya='1' THEN es<=g; END IF;
WHEN g=> dec<='1'; es<=c;
WHEN h=> ld<='1';es<=c;
END CASE;
END PROCESS;
-- comparador y señales de control
menor<='1' WHEN qp<precio ELSE '0';
igual<='1' WHEN qp=precio ELSE '0';
mayor<='1' WHEN qp>precio ELSE '0';
END uno;
Figura 6.10.5. Programa VHDL del controlador de la máquina surtidora de café.
Figura 6.10.6. Simulación del programa café1, con una entrada de $10.00
6.11 Simulador de una entrada del juego de Beis-Bol.
Un operador humano indica mediante interruptores o teclado la clave numérica del batazo de
un pelotero, con las opciones siguientes.
Clave
0 O Out fácil (Ponche, rola o elevado corto, etc.) Ningún corredor que ocupe
alguna base avanza.
1 S Hit sencillo. Los corredores avanzan una base(Anota carrera el que esté en
tercera base). El bateador ocupa la primera base.
2 D Hit doble. Los corredores avanzan 2 bases(Anotan corredores de segunda
y tercera base). El bateador ocupa la segunda base.
3 T Hit triple. Los corredores avanzan 3 bases (Anotan todos los corredores).
El bateador ocupa la tercera base
4 H Home-Run. Anotan todos los corredores, incluyendo el bateador.
5 R Rola difícil. Es Out, pero avanzan los corredores 1 base si hay menos de 2
Outs
6 E Elevado difícil. Es Out, pero anota corredor de la tercera base si hay menos
de 2 outs (Pisa y corre)
7 B Base por bolas. Bateador pasa a primera base. Si estaba ocupada por un
corredor, éste pasa a segunda base, y si ésta está ocupada, el corredor
correspondiente pasa a tercera base; de ser este el caso, anota el corredor
que pudiera estar en tercera base (carrera de caballito)
Con estos datos, el simulador determina el total de carreras NUMCARR al completarse 3
Outs.
Arquitectura. Para indicar la ocupación de las bases utilizamos flip-flops J-K. La lógica de
entrada a cada flip-flop es como sigue:
Primera base: J1 = B + S K1 = R + D + T + H
Segunda base: J2 = D + B1 · (B + S + R · M) K2= T + H + B1´· (S + R)
Tercera base: J3 = T + B2· (S + R · M) + B1· (B2 · B + D) K3 = H + E + B2´· (R + S) + B1´· D
Hemos denominado como M a la condición de menos de 2 outs previa a un batazo de out, o
menos de 3 outs si se contabiliza el nuevo batazo de out (actual). Esto es,M<=2.
Para recibir los datos del operador, conviene utilizar un decodificador con salidas w= 0, 1, 2,
etc, de acuerdo con el significado de la tabla de arriba, y un monopulsador de salida ry o el
Enter del teclado para que sean recibidos por el sistema. Utilizamos un contador incremental
de 2 bits con control INCO para contar los outs (OUTS). Requerimos también un contador
incremental para contabilizar las carreras, con control INCC (cuenta limitada a 15 carreras, 4
bits). Notar que con un solo dato pueden generarse hasta 4 carreras, requiriéndose un pulso
por carrera, por lo que conviene separar los casos como sigue, de acuerdo con cada base
ocupada. La notación Ck indica carrera desde la base k:
a) Con Hits o base por bolas: C1 = B1r · (T + H), C2 = B2r · (T + H + D), C3a = B3r · (T + H + D + S + B1r · B2r ·B), C4=H
b) Con Out: C3b = B3r · M · (R + E).
Sea C3 = C3a + C3b, y C = C1 + C2 + C3 + H. La condición Out equivale a Out = O + R + E
En estas expresiones se usa el subíndice r de las banderas de bases para indicar que se
considera la ocupación de bases del batazo anterior, para distinguirlas de la generada por el
batazo actual. Los valores de B1r, B2r, B3r se obtienen de un registro que captura los valores
de cada B al ocurrir ry. Estas condiciones, así como las entradas J y K de los flip-flops de las
bases, se realizan por lógica combinatoria; el diagrama a bloques de la arquitectura se muestra
en la figura 6.11.1.
Figura 6.11.1. Componentes de la arquitectura del simulador del juego de beis-bol
Controlador: Para controlar la operación, notamos que tenemos las entradas x (dato de 0 a
7), Out, C, C1, C2, C3a, C3b, C4, M. Las salidas INCO e INCC accionan a los contadores
con salidas OUTS Y NUMCARR. El diagrama MDS del controlador queda como en la figura
6.10.2.
El estado 0 inicial es de espera, hasta que ocurra ry, cuando pasamos al estado 1. En este
estado se distingue si hay OUT, en cuyo caso pasamos al estado 2, con salida INCO para
contabilizar el OUT. Si antes había menos de 2 outs, condición que denominamos como
M2, pasamos al estado 3, donde se determina si hay carrera. En caso afirmativo, pasamos al
estado 4 con salida INCC, y, en ambos casos, retornamos al estado 0 por un nuevo batazo. Si
al llegar al estado 2 tenemos 2 Outs, se genera el tercer Out y pasamos al estado 15 generando
FIN. Usamos la condición M2=2.
Examinamos ahora el caso en que no hay out a partir del estado1. Pasamos al estado 5, y se
distingue si hay carrera: En caso negativo regresamos al estado 0, y, si hay carrera, pasamos
al estado 6. A partir de este estado se determina si hay carrera desde la primera base, la
segunda, etc. generando INCC en cada caso afirmativo, hasta el estado 14, del cual regresamos
al estado 0.
Figura 6.11.2. Diagrama MDS del controlador del juego de beis-bol
Hay 2 aspectos a resaltar en este diseño: El diagrama resulta sencillo por haber separado los
casos en que hay carreras con o sin Outs. El segundo aspecto se refiere al uso de banderas
lógicas, que equivalen a variables booleanas en un programa.
El diseño del sistema completo resultaría muy costoso si se implementa por circuitos de baja
integración. Es preferible utilizar un CPLD o FPGA, que puede sintetizarse por el programa
VHDL de la figura 6.11.3.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY beisbol IS
PORT (o, s,d, t,h,e,r,b: IN STD_LOGIC;
rst, clk,ry: IN STD_LOGIC;
outs: OUT INTEGER RANGE 0 TO 3;
numcarr: OUT INTEGER RANGE 0 TO 15;
fin: OUT STD_LOGIC);
END BEISBOL;
ARCHITECTURE uno OF beisbol IS
TYPE edo IS (e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15);
SIGNAL ep,es: edo;
SIGNAL m,m2, inco, incc, j1,k1,j2,k2,j3,k3,c1,c2,c3,c3a,c3b,c,outt: STD_LOGIC;
SIGNAL b1,b2,b3,b1r,b2r,b3r: STD_LOGIC;
SIGNAL outss: INTEGER RANGE 0 TO 3;
SIGNAL carr: INTEGER RANGE 0 TO 15;
BEGIN
-- DEFINICIONES LÓGICAS PARA FLIP-FLOPS J-K DE BASES
j1<=s OR b; k1<=d OR t OR h OR r;
j2<=d OR (b1 AND (s OR b OR (r AND m)));
k2<=t OR h OR (NOT b1 AND (s OR r));
j3<=t OR (d AND b1) OR (b2 AND (s OR (r AND m) OR (b1 AND b)));
k3<=h OR (NOT b2 AND (s OR r)) OR (NOT b1 AND d) OR e;
-- DEFINICIONES DE OUTS Y CARRERAS
c1<=b1r AND (t OR h); c2<=b2r AND (d OR t OR h);
c3a<=b3r AND(s OR d OR t OR h OR (b1r AND b2r AND b));
c3b<= b3r AND (e OR r) AND m; c3<=c3a OR c3b; c<=c1 OR c2 OR c3 OR h;
outt<= o OR e OR r;
-- RETARDOS DE BASES HASTA EL SIGUIENTE BATAZO
PROCESS(clk)
BEGIN IF clk='1' AND clk'EVENT THEN
IF ry='1' THEN b1r<=b1; b2r<=b2; b3r<=b3;
END IF; END IF;
END PROCESS;
PROCESS( rst, clk, inco) --CONTADORES
BEGIN IF rst='1' THEN outss<=0; ELSIF clk='1' AND clk'EVENT THEN
IF inco='1' THEN outss<=outss+1; END IF; END IF;
END PROCESS;
PROCESS( rst, clk, incc)
BEGIN IF rst='1' THEN carr<=0; ELSIF clk='1' AND clk'EVENT THEN
IF incc='1' THEN carr<=carr+1; END IF; END IF;
END PROCESS;
m<='1' WHEN outss<=2 ELSE '0';
m2<='1' WHEN outss=2 ELSE '0';
PROCESS(rst,clk)
BEGIN IF rst='1' THEN ep<=e0; ELSIF clk='1' AND clk'EVENT THEN
ep<=es; END IF;
END PROCESS;
-- ESTADOS
PROCESS (ep, ry, c, c1,m, c2, outt, c3,h,m2)
BEGIN
CASE ep IS
WHEN e0=> IF ry='1' THEN es<=e1; ELSE es<=e0; END IF;
WHEN e1=> IF outt='1' THEN es<=e2; ELSE es<=e5; END IF;
WHEN e2=> IF m2='0' THEN es<=e3; ELSE es<=e15; END IF;
WHEN e3=> IF c='1' THEN es<=e4; ELSE es<=e0; END IF;
WHEN e4=> es<=e0;
WHEN e5=> IF c='1' THEN es<=e6; ELSE es<=e0; END IF;
WHEN e6=> IF c1='1' THEN es<=e7; ELSE es<=e8; END IF;
WHEN e7=> es<=e8;
WHEN e8=> IF c2='1' THEN es<=e9; ELSE es<=e10; END IF;
WHEN e9=> es<=e10;
WHEN e10=> IF c3='1' THEN es<=e11; ELSE es<=e12; END IF;
WHEN e11=> es<=e12;
WHEN e12=> IF h='1' THEN es<=e13; ELSE es<=e14; END IF;
WHEN e13=> es<=e14;
WHEN e14=> es<=e0;
WHEN e15=> es<=e15;
END CASE;
END PROCESS;
PROCESS (clk, rst, j1,k1) -- FLIP-FLOPS DE BANDERAS DE BASES
BEGIN IF rst='1' THEN b1<='0'; ELSIF clk='1' AND clk'EVENT THEN
IF ry='1' THEN
b1<= (b1 AND NOT k1) OR (NOT b1 AND j1);
END IF; END IF;
END PROCESS;
PROCESS (clk, rst, j2,k2)
BEGIN IF rst='1' THEN b2<='0'; ELSIF clk='1' AND clk'EVENT THEN
IF ry='1' THEN
b2<= (b2 AND NOT k2) OR (NOT b2 and j2);
END IF; END IF;
END PROCESS;
PROCESS (clk, rst, j3,k3)
BEGIN IF rst='1' THEN b3<='0'; ELSIF clk='1' AND clk'EVENT THEN
IF ry='1' THEN
b3<= (b3 AND NOT k3) OR (NOT b3 AND j3);
END IF; END IF;
END PROCESS;
-- SALIDAS DE CONTROL
inco<='1' WHEN ep=e2 ELSE '0';
incc<='1' WHEN (ep=e4 OR ep=e7 OR ep=e9 OR ep=e11 OR ep=e13) ELSE '0';
fin<='1' WHEN ep=e15 ELSE '0'; numcarr<=carr;
END uno;
Figura 6.11.3 Programa VHDL del simulador de una entrada de beis-bol
En las figuras 6.11.4 y 6.11.5 se presentan 2 simulaciones: En la primera se anota una carrera
por pisa y corre, y en la segunda se anota por un triple seguido por un doble.
Figura 6.11.4. Simulación del programa béisbol (pisa y corre)
Figura 6.11.5. Simulación del programa béisbol (triple+doble)
6.12 Multiplicador secuencial
Se presenta a continuación un ejemplo de diseño más sencillo que los anteriores, que ilustra
el uso de registros de desplazamiento. Se pretende obtener el resultado de multiplicar 2
números binarios sin signo de 8 bits, por el método de suma y desplazamiento, como lo
efectuamos cotidianamente. El método se ilustra a continuación, con el producto de 19x11 en
binario: Se multiplica cada bit del multiplicador por el multiplicando, colocando el resultado
a la izquierda del resultado anterior. Se suman todo los productos parciales para el resultado
final.
10011 multiplicando
1011 multiplicador
10011 producto x1
10011 producto x1
00000 producto x0
10011 producto x1
11010001 RESULTADO
Para implementar el método, recordamos primeramente que un sumador binario acepta sólo
2 operandos, por lo que utilizaremos un acumulador para sumar cada producto parcial con la
suma de los anteriores. Por otro lado, en vez de correr cada suma parcial a la izquierda, la
desplazamos hacia la derecha. A esta suma parcial se le agrega el producto parcial siguiente
sólo si el bit correspondiente del multiplicador es 1; en caso contrario, el producto es nulo, y
efectuamos sólo un desplazamiento, como se muestra a continuación:
10011
1011
00000 Valor inicial 0
10011 Primer producto. Bit=1
10011 Primera suma parcial
010011 Desplazamiento a la derecha
10011 Segundo producto. Bit=1
111001 Segunda suma parcial
0111001 Desplazamiento a la derecha
00111001 Desplazamiento a la derecha, ya que Bit=0
10011 Cuarto producto parcial
11010001 Suma y producto final
Dado que el producto final contiene más bits que los operandos originales, podemos formarlo
concatenando 2 registros: A y Q. Q contiene originalmente el multiplicador, que no necesita
guardarse indefinidamente. A contiene las sumas parciales, y desplaza su bit menos
significativo al más significativo de Q; Q(0) resulta así siempre el bit por examinar (si vale 1
ó 0). Contamos cada desplazamiento con un contador cont, y el proceso se termina cuando se
rebasa el número de bits.
En la figura 6.12.1 se muestra la arquitectura requerida para números de 4 bits. El acumulador
consiste de un sumador alimentado por los registros A y B; A guarda las sumas parciales y B
el multiplicando. A y Q son registros de desplazamiento con carga en paralelo como los que
estudiamos anteriormente, con señales de control Ld y shft. El contador cont se controla
mediante la señal inc para incrementar su cuenta. El sistema empieza a operar con una señal
de inicio s, para cargar el multiplicando en B y el multiplicador en Q. Dado que la suma
produce un acarreo que puede ocupar 1 bit adicional, los registros A y B, así como el sumador
son de 5 bits.
Figura 6.12.1. Arquitectura para el multiplicador binario
Proponemos el diagrama de estados de la figura 6.12.2. Del estado inicial 0 pasamos al 1 con
s . En el estado 1 probamos Q(0), pasando a 2 ó 3 si Q(0)= 1 ó 0 respectivamente; en el estado
1 incrementamos también el contador. La suma se carga en A en el estado 2, y se desplaza en
el estado 3 si no hemos terminado ( cont ≤ 4). Usamos una sola señal Ld de control para B y
Q.
Figura 6.12.2. Diagrama MDS del controlador del multiplicador binario
En la Figura 6.12.3 se muestra el código VHDL mult; nótese que se incluyen varios procesos:
uno para el registro de estados y el contador; otro para las transiciones; un registro para la
carga de B y otro para la carga (y desplazamiento) de A y Q.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY mult IS
PORT (clk, rst, s: IN STD_LOGIC;
mando, mdor: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
res: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
edo: OUT INTEGER RANGE 0 TO 3);
end mult;
ARCHITECTURE arch_mult OF mult IS
SIGNAL inc, lda, ld, shft: STD_LOGIC;
SIGNAL ep,es: INTEGER RANGE 0 TO 3;
SIGNAL a,sum,b: UNSIGNED(4 DOWNTO 0);
SIGNAL q: UNSIGNED (3 DOWNTO 0);
SIGNAL contp,conts: INTEGER RANGE 0 TO 4;
SIGNAL ress: UNSIGNED(7 DOWNTO 0);
SIGNAL ldash,ldbsh: STD_LOGIC_VECTOR(1 DOWNTO 0);
BEGIN
PROCESS(s,q(0),ep,contp) –TRANSICIONES DE ESTADOS
BEGIN
es<=ep;
CASE ep IS
WHEN 0=> IF s='1' THEN es<=1; END IF;
WHEN 1=> IF q(0)='1' THEN es<=2; ELSE es<=3; END IF;
WHEN 2=> es<=3;
WHEN 3=> IF (contp<=3) THEN es<=1; ELSE es<=0; END IF;
END CASE;
END PROCESS;
PROCESS (clk, rst) --CONTADOR Y CAMBIO DE ESTADO CON EL RELOJ
BEGIN
IF rst='1' THEN contp<=0; ep<=0;
ELSIF clk'EVENT AND clk='1' THEN
contp<=conts; ep<=es;
END IF;
END PROCESS;
conts<=contp+1 WHEN inc='1' ELSE contp;
PROCESS (clk, rst, ld) -- CARGA DE b
BEGIN
IF rst='1' THEN b<=(OTHERS=>'0');
ELSIF clk'EVENT AND clk='1' THEN
IF ld='1' THEN b<=UNSIGNED('0'&mando);
END IF;
END IF;
END PROCESS;
sum<=a+b;
ldash<=lda&shft;
ldbsh<=ld&shft;
PROCESS (clk, rst, ldash) -- SUMA O DESPLAZAMIENTO
BEGIN
IF rst='1' THEN a<=(OTHERS=>'0'); q<=(OTHERS=>'0');
ELSIF clk'EVENT AND clk='1' THEN
CASE ldash IS
WHEN "00" =>
WHEN "01" => a<='0'& a(4 DOWNTO 1);
WHEN OTHERS => a<=sum;
END CASE;
CASE ldbsh IS
WHEN "00" =>
WHEN "01" => q<=a(0)&q(3 DOWNTO 1);
WHEN OTHERS => q<=UNSIGNED(mdor);
END CASE;
END IF;
END PROCESS;
-- SALIDAS Y SEÑALES DE CONTROL
ress(7 DOWNTO 4)<=a(3 DOWNTO 0); ress(3 DOWNTO 0)<=q(3 DOWNTO 0);
res<=STD_LOGIC_VECTOR(ress);
lda<='1' WHEN ep=2 ELSE '0'; inc<='1' WHEN ep=1 ELSE '0';
ld<='1' WHEN (s='1' AND ep=0) ELSE '0';
shft<='1' WHEN (ep=3) ELSE '0';
edo<=ep;
END arch_mult;
Figura 6.12.3. Programa VHDL del multiplicador secuencial
En la Figura 6.12.4 se muestra la simulación del producto 10x8.
Figura 6.12.4. Simulación del programa mult
6.13. Principios de control microprogramado
La microprogramación se utiliza para la síntesis de autómatas muy complejos (Como el
sistema de control de los procesadores Pentium, por ejemplo). También se presta para sistemas
que pueden sintetizarse en un microcontrolador o un secuenciador programable. Para su
comprensión, partimos de una idea muy básica: La transición de un estado a otro tiene una de
las 3 equivalencias siguientes: Retención (mismo estado), Cuenta (el estado siguiente es el
sucesor inmediato), o Ramificación (el estado siguiente posee una clave diferente de la
inmediata superior). Para mayor sencillez, se puede restringir a 2 el número de transiciones a
partir de cualquier estado, como se muestra en la Figura 6.13.1; esto implica que, si existe una
ramificación, ésta se efectúe a un solo estado, por lo que no se admite más de una sola variable
de entrada (condición) por estado. Las posiblidades de transiciones de la Figura son: RCC
(retención o cuenta condicional), RRC (retención o ramificación condicional), CI (cuenta
incondicional), RI (ramificación incondicional), CRC (cuenta o ramificación condicional); en
este último caso, la ramificación ocurre si la condición se cumple [7,9].
Un principio de implementación consiste en utilizar un contador con carga en paralelo (un
contador de programa) en vez de registros simples de estado. Como sabemos, el PC puede
contar, cargar un dato o dirección (ramificación), o retener su valor, de acuerdo con sus señales
de control Ld y Cnt; recordemos que Ld tiene más peso que Cnt. La salida del PC es el estado
Q, que se utiliza como dirección de un ROM que almacena el programa del autómata.
Figura 6.13.1. Transiciones para un sistema microprogramado
Las condiciones que generan una cuenta o una carga del PC provienen de las variables de
entrada, que pueden capturarse por uno o 2 MUXes. Cada palabra del ROM, que corresponde
con un estado del autómata, contiene la información siguiente:
1. Dirección (es) del (los) MUX (es). (DMC y DMR para el caso de 2 MUXes).
2. Dirección de la ramificación, en su caso (dr)
3. Salidas del estado (Moore) (z)
Figura 6.13.2. Sistema de control programado con 2 MUXes
Un sistema programable con 2 MUXes se muestra en la Figura 6.13.2. Las variables que
provocan una cuenta se agrupan en el MUX MC, y las que provocan una ramificación en el
MUX MR. Si se utiliza sólo un MUX, éste selecciona todas las variables; su salida w conecta
con Ld, y w´con Cnt.
Proponemos un arreglo aún más flexible. Añadimos un MUX para las entradas, con salida
COND, y alambramos los 2 MUXes originales para responder a claves de operación (OPC)
de acuerdo con la tabla siguiente, en la que utilizamos 5 claves binarias (000 a 100) de
operación. Las restantes (101 a 111) son condiciones irrelevantes.
MNEM CLAVE OPC FUNCION CNT LD
RCC 000 Retención o cuenta condicional COND 0
RRC 001 Retención o ramificación condicional 0 COND
CI 010 Cuenta incondicional 1 0
RI 011 Ramificación incondicional x 1
CRC 100 Cuenta o ramificación condicional 1 COND
Tabla 6.13.1. Tabla de claves de operación para un microcontrolador simple MC
En la tabla, MNEM es un mnemónico que designa a cada operación. Si la clave OPC, de bits
OPC0, OPC1 y OPC2 selecciona directamente las entradas de los MUX, y tomamos las claves
irrelevantes como ceros, las salidas CNT y LD resultan, del método de MUX:
MUXMC(1,3,5,6,7)=0 MUXMC(0)=COND MUXMC(2,4)=1
MUXMR(0,2,5,6,7)=0 MUXMR(1,4)=COND MUXMR(3)=1
Figura 6.13.3. Secuenciador programable MP1
El subsistema, mostrado en la Figura 6.13.3, consiste de los 2 MUXes y el PC. Actúa como
un secuenciador MP1, y puede utilizarse para cualquier autómata de acuerdo con el número
de bits del PC (4, 8, etc.). Las entradas se seleccionan mediante el MUX de entrada ME con
la dirección DME, y el programa reside en un ROM del tamaño adecuado. Recordemos que
la salida Q del PC es la dirección del ROM: para 4 bits, se requiere un ROM de 16 palabras.
El tamaño de la palabra depende del número de estados y de salidas. En la Figura 6.13.4 se
muestra el secuenciador, y su conexión al MUX ME así como al ROM. La palabra del ROM
contiene la información siguiente: OPC, DME, DR, z.
Para ejemplificar el uso del secuenciador, sintetizaremos el controlador del simulador de una
entrada de beis-bol (Figura 6.11.2). El autómata tiene 16 estados, luego se requieren 4 bits
para DR y Q. Las entradas a capturar son: ry, out´, m2, C´, C1´, C2´, C3´, h´, que agrupamos
en un MUX ME 8 a 1. El programa se muestra en la Figura 6.13.5.
Figura 6.13.4. Sistema microprogramable con el programa en ROM
Estado Función OPC DME DR INCC INCO
0000 RCC(ry) 000 000 xxxx 0 0
0001 CRC(out´) 100 001 0101 0 0
0010 CRC(M2´) 100 010 1111 0 1
0011 CRC(C´) 100 011 0000 0 0
0100 RI 011 xxx 0000 1 0
0101 CRC(C´) 100 011 0000 0 0
0110 CRC(C1´) 100 100 1000 0 0
0111 CI 010 xxx xxxx 1 0
1000 CRC(C2´) 100 101 1010 0 0
1001 CI 010 xxx xxxx 1 0
1010 CRC(C3´) 100 110 1100 0 0
1011 CI 010 xxx xxxx 1 0
1100 CRC(h´ ) 100 111 1110 0 0
1101 CI 010 xxx xxxx 1 0
1110 RI 011 xxx 0000 0 0
1111 RI 011 xxx 1111 0 0
Figura 6.13.5 Microprograma del autómata del simulador de una entrada de beis-bol
En la Figura 6.13.6 presentamos el programa mp1 en VHDL que implementa al secuencidador
de 4 bits. Este se utilizará posteriormente como componente compilado para simular cualquier
autómata de 16 estados o menos.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD..ALL;
ENTITY mp1 IS
PORT(opc: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
cond, clk, rst: IN STD_LOGIC;
dr: IN STD_LOGIC_VECTOR(3 DOWNTO 0)
y: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END mp1;
ARCHITECTURE uno OF mp1 IS
SIGNAL ld, cnt: STD_LOGIC;
SIGNAL q: UNSIGNED(3 DOWNTO 0);
BEGIN
PROCESS(rst, clk) --CONTADOR CON CARGA EN PARALELO
BEGIN IF rst='1' THEN q<="0000";
ELSIF (clk='1' AND clk'EVENT) THEN
IF ld='1' THEN q<=UNSIGNED(dr);
ELSIF cnt='1' THEN q<=q+1;
END IF; END IF;
END PROCESS;
WITH opc SELECT – CODIGO DE OPERACION
cnt<=cond WHEN "000", '0' WHEN "001", '1' WHEN "010",
'0' WHEN "011", '1' WHEN "100", '0' WHEN OTHERS;
WITH opc SELECT
ld<='0' WHEN "000", cond WHEN "001", '0' WHEN "010",
'1' WHEN "011", cond WHEN "100", '0' WHEN OTHERS;
y<=STD_LOGIC_VECTOR(q);
END uno;
Figura 6.13.6 Programa VHDL del secuenciador MP1
Simulación de un ROM.
Podemos modelar un ROM como un arreglo de n palabras de m bits cada una. Declaramos
entonces en VHDL un tipo ROM de 16x12 como
TYPE rom IS ARRAY (0 TO 15) of STD_LOGIC_VECTOR (11 DOWNTO 0);
El contenido de la ROM es una constante del tipo ROM, que equivale a 16 cadenas de 12 bits,
tal como CONSTANT tabla: rom:=(“000000000000”, “100001010100”, …);
Para recuperar el valor de una palabra, necesitamos direccionar al ROM por un entero, tal
como tabla (k), con k=1,2,…etc. Si nuestra dirección es un vector de bits, requerimos
entonces de una conversión de los bits a un entero decimal. Utilizamos la función
TO_INTEGER del paquete NUMERIC: valor<=tabla(TO_INTEGER(UNSIGNED(dir)).
Entonces OPC<=valor (11 DOWNTO 9), DME<=valor(8 DOWNTO 5), etc.
Presentamos a continuación el programa VHDL para simular el controlador de la entrada de
beis-bol por el secuenciador, y los resultados de la simulación:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
ENTITY beismp1 IS
PORT (clk, rst,ry,outt,m2,c,c1,c2,c3,h: IN STD_LOGIC;
dme,opc: OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
dr: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
incc, inco, z: OUT STD_LOGIC;
y: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END beismp1;
ARCHITECTURE uno OF beismp1 IS
TYPE rom IS ARRAY (0 TO 15) OF STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL edo,drr: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL v: STD_LOGIC;
SIGNAL dmee, opcc: STD_LOGIC_VECTOR(2 DOWNTO 0);
-- microprograma
CONSTANT tabla: rom:=("000000000000", "100001010100","100010111101",
"100011000000", "011000000010","100011000000",
"100100100000", "010000000010","100101101000",
"010000000010", "100110110000","010000000010",
"100111111000", "010000000010","011000000000",
"011000111100");
-- máquina mp1
COMPONENT mp1 IS
PORT(opc: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
cond,clk,rst: IN STD_LOGIC;
ba: IN STD_LOGIC_VECTOR(3 DOWNTO 0);
y: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
BEGIN
PROCESS (edo) –lectura del rom
VARIABLE valor: STD_LOGIC_VECTOR(11 DOWNTO 0);
BEGIN
valor:=tabla(TO_INTEGER(UNSIGNED(edo)));
opcc<=valor(11 DOWNTO 9); dmee<=valor(8 DOWNTO 6); drr<=valor(5 DOWNTO 2);
incc<=valor(1); inco<=valor(0);
END PROCESS;
PROCESS (dmee,ry,outt,m2,c,c1,c2,c3,h) -- mux selector de entradas
BEGIN
CASE dmee IS
WHEN "000" => v<=ry;
WHEN "001" => v<=not outt;
WHEN "010" => v<= m2;
WHEN "011" => v<=not c;
WHEN "100" => v<=not c1;
WHEN "101" => v<=not c2 ;
WHEN "110" => v<=not c3;
WHEN OTHERS => v<=not h;
END CASE;
END PROCESS;
mpc: mp1 PORT MAP(opcc,v,clk,rst,drr,edo);
y<=edo; dr<=drr; opc<=opcc; dme<=dmee; z<=v;
END uno; Figura 6.13.7. Programa VHDL del controlador de la entrada de beis-bol
Figura 6.13.8. Simulación del programa del controlador de la entrada de beis-bol.
6.14 Marcador de un juego de boliche
El juego de boliche, también llamado bolos, tiene por objeto derribar el mayor número de
pinos (palos) posible en 10 entradas. En cada entrada se lanzan 1 ó 2 bolas hacia un grupo de
10 pinos. Si se derriban todos con la primera bola, lo que se conoce como una chuza, la
puntuación del jugador es de 10 mas los pinos que derribe en sus siguientes 2 tiros (un máximo
de 30). En caso contrario, se lanza una segunda bola; si se derriban todos los que quedaron
parados, lo que se conoce como spare, la puntuación del jugador es de 10 más los pinos que
derribe en su siguiente tiro (un máximo de 20). En caso de obtener spare o chuza en la décima
entrada, se le otorgan al jugador 1 o 2 tiros adicionales para cumplir con las reglas descritas.
La puntuación es acumulativa por las 10 entradas. Cuando el jugador no obtiene ni chuza ni
spare, se habla de una “caída”, y sólo se acumulan los pinos derribados.
Nuestro objetivo es el de automatizar el marcador, con base en el número de pinos derribados
en cada tiro. En la práctica, existe una máquina que recoge los pinos no derribados para
colocarlos de nuevo después de barrer los que sí fueron derribados; por medio de sensores se
detecta su número automáticamente. En nuestro sistema, introducimos por switches o teclado
el número de pinos derribados en cada tiro, con una señal ry de un monopulsador (o Enter de
un teclado).
Arquitectura. Determinemos las necesidades de almacenamiento de información ante todo.
El acumulador final debe poder almacenar la puntuación máxima: 300 pinos, equivalente a un
juego perfecto de 12 chuzas; hablamos de 9 bits. Por otro lado, requerimos un acumulador
inicial para la suma de 2 tiros, con valor máximo de 10 (4 bits). El valor de cada tiro se
almacena en un registro x, y la suma se acumula en el registro sum, que incluye un borrado
síncrono.
La acumulación final se guarda en un registro tot; los operandos del sumador, además de tot,
provienen de MUXes 4 a 1 con entradas sum, 10 y 20, y salida t. Se requieren 2 ciclos para
sumar tot, 10 y sum en el caso de un spare o chuza simple, o para sumar tot, 20 y sum, en el
caso de chuzas consecutivas (cuando se agrega 20+sum a tot). El circuito con los 2
acumuladores se muestra en la Figura 6.14.1.
Figura 6.14.1. Arquitectura de acumulación del marcador de boliche
El sistema requiere un comparador con 10, tanto para detectar si ocurrió una chuza o un spare,
como para detectar el fin del juego, pues consiste de 10 entradas; usamos un solo comparador,
cuya entrada se selecciona por MUXes 2 a 1 con entradas sum y cont. La señal cont proviene
de un contador ascendente que se incrementa cada vez que se anota en una entrada (no
coincide necesariamente con la entrada en turno).
Figura 6.14.2. Componentes adicionales de la arquitectura del marcador de boliche
Por último, se requieren banderas lógicas para denotar que hay un spare, una chuza o una
doble chuza. Si se sintetiza el marcador con componentes MSI, usaríamos flip-flops J-K o T
para cada señal (spare,chuz, dchuz); toda esta arquitectura adicional a la de acumulación se
muestra en la Figura 6.14.2.
Controlador. Identificamos primeramente las entradas y salidas para el autómata:
Entradas: d, ry, spare, chuz, dchuz, =10 (salida del comparador), cont, y rst (asíncrono).
Salidas: Ldx, Ldsum, clr, Ldtot, s1, s0 (selección de los MUXes), inc, ap, jch, kch, jsp, ksp,
jdch, kdchz.
En la Figura 6.14.3 se muestra el diagrama ASM del controlador; tiene 26 estados, debido a
que se ha limitado a 1 el número de variables de entrada que controlan cada iteración, con
salidas tipo Moore; esto para microprogramarse con facilidad.
Los estados INIT, RD y AC ocurren 3 veces, para el proceso de recepción del dato de en x, y
la primera acumulación en Sum: primera bola, segunda bola normal y segunda bola después
de una chuza (en este caso hay acumulación del total). Notar que las banderas se encienden al
detectar una chuza, una doble chuza o un spare, y se apagan después de procesar cada uno de
dichos eventos. Los estados se han codificado para un control microprogramado.
6.14.3. Diagrama ASM del controlador del juego de boliche
El microprograma se muestra en la Figura 6.14.4 con las entradas conectadas al MUX ME en
el orden (ry,spare, chuz, =10, ≠10, dchuz), y las salidas en el orden (hit, ldx, ldsum, clr, ldtot,
s1, s0, ap, inc, jch, kch, jdch, kdch, jsp, ksp).
Estado Función OPC DME DR SALIDAS
00000 RCC (ry) 000 000 xxxxx 100000000000000
00001 CI 010 xxx xxxxx 010000000000000
00010 CRC (spare) 100 001 01110 001000000000000
00011 CRC (chuz) 100 010 10000 000000000000000
00100 CRC (=10) 100 011 00110 000000000000000
00101 RRC (ry) 001 000 00111 100000000000000
00110 RI 011 xxx 01000 000000000100000
00111 CI 010 xxx xxxxx 010000000000000
01000 CI 010 xxx xxxxx 001000000000000
01001 CRC (=10) 100 011 01011 000000000000000
01010 RI 011 xxx 01100 000010001000000
01011 RI 011 xxx 01100 000000000000010
01100 CRC (≠10) 100 100 00000 000100010000000
01101 RI 011 xxx 01101 000000000000000
01110 CI 010 xxx xxxxx 000010100000000
01111 RI 011 xxx 00100 000010001000001
10000 CRC (dchz) 100 101 10111 000000000000000
10001 CRC (=10) 100 011 11001 000000000000000
10010 RCC (ry) 000 000 xxxxx 100000000000000
10011 CI 010 xxx xxxxx 010000000000000
10100 CI 010 xxx xxxxx 001000000000000
10101 CI 010 xxx xxxxx 000010100000000
10110 RI 011 xxx 01001 000010001010000
10111 CI 010 xxx xxxxx 000011000000000
11000 RI 011 xxx 10001 000010001000100
11001 RI 011 xxx 01100 000000000001000 Figura 6.14.4. Microprograma del controlador del juego de boliche
El códigoVHDL para implementar el marcador completo se muestra en la Figura 6.14.5.
Notar que las banderas se implementan como flip-flops D en el proceso de cambios con el
reloj. Hemos utilizado el tipo INTEGER para los estados, los registros de acumulación y el
contador.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY bol1 IS
PORT(rst, clk, ry: IN STD_LOGIC; d: IN INTEGER RANGE 0 TO 10;
total: OUT INTEGER RANGE 0 TO 300;
hit: OUT STD_LOGIC);
END bol1;
ARCHITECTURE uno OF bol1 IS
SIGNAL sp, chuz, dchuz, inc, ldx, ldsum, ldtot,clr: STD_LOGIC;
SIGNAL s: STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL ep, es: INTEGER RANGE 0 TO 25;
SIGNAL contp,conts, xp,xs,x1,sum: INTEGER RANGE 0 TO 10;
SIGNAL t: INTEGER RANGE 0 TO 20;
SIGNAL q,totp,tots: INTEGER RANGE 0 TO 300;
BEGIN
PROCESS(clk, rst)-- CAMBIOS CON EL RELOJ
BEGIN
IF rst='1' THEN ep<=0; contp<=0; xp<=0;totp<=0;
sp<='0'; chuz<='0'; dchuz<='0';
ELSIF (clk='1' AND clk'EVENT) THEN
ep<=es;xp<=xs;totp<=tots; contp<=conts;
----- BANDERAS -------
IF ep=11 THEN sp<='1'; END IF;
IF ep=15 THEN sp<='0'; END IF;
IF ep=6 THEN chuz<='1'; END IF;
IF ep=22 THEN chuz<='0'; END IF;
IF ep=25 THEN dchuz<='1'; END IF;
IF ep=24 THEN dchuz<='0'; END IF;
END IF;
END PROCESS;
----- FSM ----------------------------------
PROCESS(ep, ry, sp, chuz, dchuz, sum, contp)
BEGIN es<=ep;
CASE ep IS
WHEN 0 => IF ry='1' THEN es<=1; END IF;
WHEN 1=> es<=2;
WHEN 2=> IF sp='1' THEN es<= 14; ELSE es<= 3; END IF;
WHEN 3=> IF chuz='1' THEN es<=16; ELSE es<= 4; END IF;
WHEN 4=> IF sum=10 THEN es<=6; ELSE es<=5; END IF;
WHEN 5=> IF ry='1' THEN es<=7; END IF;
WHEN 6=> es<=12;
WHEN 7=> es<=8;
WHEN 8=> es<=9;
WHEN 9=> IF sum=10 THEN es<=11; ELSE es<=10; END IF;
WHEN 10=> es<=12;
WHEN 11=> es<=12;
WHEN 12=> if contp<10 then es<=0; else es<=13; end if;
WHEN 13=> es<=13;
WHEN 14=> es<=15;
WHEN 15=> es<=4;
WHEN 16=> IF dchuz='1' THEN es<=23; ELSE es<=17; END IF;
WHEN 17=> IF sum=10 THEN es<=25; ELSE es<= 18; END IF;
WHEN 18=> IF ry='1' THEN es<=19; ELSE es<=18; END IF;
WHEN 19=> es<= 20;
WHEN 20=> es<=21;
WHEN 21=> es<=22;
WHEN 22=> es<= 9;
WHEN 23=> es<=24;
WHEN 24=> es<=17;
WHEN 25=> es<=12;
END CASE;
END PROCESS;
---- LOGICA DE REGISTROS Y CONTADORES -------
conts<=contp+1 WHEN inc='1' ELSE contp; ---CONTADOR
xs<=d WHEN ldx='1' ELSE xp; --- CARGA DEL VALOR DEL TIRO
x1<=xp+sum; --SUMA DE 2 TIROS
PROCESS(clk, rst)-- CARGA Y LIMPIA DEL ACUMULADOR DE SUMA
BEGIN
IF rst='1' THEN sum<=0;
ELSIF (clk='1' AND clk'EVENT) THEN
IF (ldsum='1' AND clr='0') THEN sum<=x1;
ELSIF clr='1' THEN sum<=0;
END IF; END IF;
END PROCESS;
q<=t+totp; --SUMA ACUMULADOR FINAL
tots<=q WHEN ldtot='1' ELSE totp; -- CARGA DEL ACUMULADOR FINAL
--- MUX PARA EL ACUMULADOR FINAL ---
WITH s SELECT
t<=sum WHEN "00", 10 WHEN "01", 20 WHEN "10", 0 WHEN OTHERS;
-- SALIDAS Y SEÑALES DE CONTROL ---
ldx<='1' WHEN (ep=1 OR ep=7 OR ep=19) ELSE '0';
ldsum<='1' WHEN (ep=2 OR ep=8 OR ep=20) ELSE '0';
inc<='1' WHEN (ep=10 OR ep=15 OR ep=24) ELSE '0';
ldtot<='1' WHEN (ep=10 OR ep=15 OR ep=24 OR ep=14 OR ep=23) ELSE '0';
s(0)<='1' WHEN (ep=21 OR ep=14) ELSE '0'; s(1)<='1' WHEN ep=23 ELSE '0';
clr<='1' WHEN ep=12 ELSE '0';
hit<='1' WHEN (ep=0 OR ep=5 OR ep=18) ELSE '0';
total<=totp;
END uno;
Figura 6.14.5. Programa VHDL para el marcador del juego de boliche.
El autómata puede realizarse con sólo 16 estado usando más de 1 variable de entrada en
algunos estados, y generando algunas salidas tipo Mealy. Queda como ejercicio para el lector
su realización.
6.15. Problema de fin de capítulo
6.15.1. Presentamos el diseño del controlador simplificado de la máquina surtidora de café,
con un reloj suficientemente lento para evitar problemas de sincronía. Suponemos que se
aceptan sólo monedas de $1, $2 y $5.00. El costo es de $7.00. Denominamos m1, m2 y m5 a
monedas presentes de 1,2 y 5 pesos, y d1, d2 a monedas devueltas de $1 y $2.00
respectivamente. Consideramos que, antes de acumular $7.00, el usuario puede equivocarse
e insertar una moneda de $5.00. Tenemos entonces el diagrama FSM de la Figura 7.15.1, que
incluye todas las posibilidades a partir de un estado. Por ejemplo, desde el estado 6 se permite
m1, m2 y m5.
Figura 6.15.1. Diagrama FSM simplificado de la máquina surtidora de café
El diseño manual puede realizarse por el método de 1 flip-flop por estado (3 registro de 4
bits). Así:
D0=Q7
D1=Q0∙m1
D2=Q1∙m1+Q0∙m2
D3=Q2∙m1+Q1∙m2
D4=Q3∙m1+Q2∙m2
D5=Q4∙m1+Q3∙m2+Q0∙m5
D6=Q5∙m1+Q4∙m2+Q1∙m5
D7=Q6∙m1+Q5∙m2+Q2∙m5
D8=Q6∙m2+Q3∙m5
D9=Q4∙m5
D10=Q5∙m5
D11=Q6∙m5
Las salidas resultan
sl=Q7 (suelta líquido)
d1=Q8+Q10 (devuelve $1.00)
d2=Q11+Q9 (devuelve $2.00)
6.15.2. Convertidor paralelo-serial continuo con PLL. En circuitos de comunicación se
estila transmitir bits en serie, por razones de costo principalmente, aunque estos bits estén
presentes en paralelo. Se requiere entonces un circuito convertidor paralelo-serial, capaz de
recibir bits en paralelo y transmitirlos en forma continua. Si la recepción de n bits en
paralelo está controlada por un reloj clk, la transmisión de los bits seriales debe efectuarse
con un reloj sclk de frecuencia n veces mayor.
La operación del circuito es más conveniente si el reloj sclk se genera a partir de clk, a fin de
que ambos relojes estén sincronizados. Un circuito que efectúa el producto por n (entre otras
funciones) se conoce como un PLL (del inglés “phased locked loop” traducido como “lazo
de seguimiento de fase”). No es nuestro propósito explicar la teoría de funcionamiento de
un PLL, pero los principales fabricantes de PLDs como Xilinx y Altera proveen su función
en lenguajes VHDL y Verilog, de manera que podamos emplear un PLL en cualquier diseño
que lo requiera instanciando su código como componente.
La función de conversión puede lograrse por medio de un Multiplexor direccionado por un
contador con frecuencia sclk. Otra solución incluye un registro de desplazamiento con carga
en paralelo, como el de la Figura 6.15.2a. La carga ocurre cada n ciclos de sclk, por medio
de la señal Ld generada a la salida de un contador módulo n; los muxes de entrada
seleccionan así la señal din. El desplazamiento ocurre con cada ciclo. La salida dout
consiste de la secuencia din(0) a din(n-1). Esto se ilustra mediante las formas de onda de la
Figura 6.15.2b, con n=4.El contador se acciona con cualquiera de las fases de sclk (se
muestra el flanco posterior en la Figura).
En la Figura 6.15.3 se muestra la simulación del circuito de la Figura 6.15.2, sintetizado por
el programa de la Figura 6.15.4. Notar en la simulación que el reloj producido por el PLL
tarda algunos ciclos de clk en aparecer, hasta que se logre un “enganche” del PLL. Una vez
logrado, el circuito transmite los bits d(0) a d(3) en serie a través de dout.
Figura 6.15.2. Circuito convertidor paralelo-serial continuo con PLL
Figura 6.15.3. Simulación del convertidor paralelo-serial
El programa fasteser1 incluye la salida sclkp para observar su comportamiento en la
simulación. Notar que utiliza una variable cont para el contador; como se actualiza de
inmediato, la instrucción cont:=n equivale a cont:=0 y se reinicia la cuenta. La palabra
reservada OPEN se utiliza al instanciar una componente, e indica que un puerto no está
conectado.
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY fasteser1 IS
GENERIC (n: INTEGER:=4);
PORT(clk: IN STD_LOGIC;
din: IN STD_LOGIC_VECTOR(n-1 DOWNTO 0);
dout,sclkp: OUT STD_LOGIC);
END fasteser1;
ARCHITECTURE uno OF fasteser1 IS
SIGNALl sclk,ld: STD_LOGIC;
SIGNAl d,q: STD_LOGIC_VECTOR(n-1 DOWNTO 0);
COMPONENT pll IS-- función proporcionada por Altera
PORT(areset: IN STD_LOGIC:='0';
inclk0: IN STD_LOGIC:='0';
c0,locked: OUT STD_LOGIC);
END COMPONENT;
BEGIN
pllcirc: pll PORT MAP('0',clk,sclk,open);-- instanciación de la PLL
sclkp<=sclk;
d<=din WHEN ld='1' ELSE "X"&q(3 downto 1);
PROCESS(sclk)
VARIABLE cont: INTEGER RANGE 0 TO n;
BEGIN
IF sclk='1' AND sclk'EVENT THEN --contador módulo n
cont:=cont+1;
IF (cont=n-1) THEN ld<='1'; ELSE ld<='0'; END IF;
IF cont=n THEN cont:=0; END IF;
q<=d;
END IF;
END PROCESS;
dout<=q(0);
END uno;
Figura 6.15.4. Programa VHDL para la síntesis del convertidor paralelo-serial.
RESUMEN
1. En la sección 6.1 se presentaron diversos tipos de registros: con carga en paralelo, serial,
(desplazamienmto), universal.
2. En la sección 6.2 se han presentado los circuitos que realizan conteo, tanto síncronos como síncronos.
Se incluyen dispositivos integrados que cuentan y almacenan información, y su uso para obtener
contadores de módulo arbitrario.
3. En la sección 6.3 se ha presentado un par de métodos para la programación VHDL de diagramas de
estado que incluyen temporizadores, y el control de un semáforo.
4. En la sección 6.4 se presentó la organización y generación un banco de registros y de una memoria
SRAM por medio de código VHDL.
5. En las secciones 6.5 as 6.7 se ha presentado el modelo de un sistema secuencial, destacando la ruta de
datos y el controlador. Se describen los pasos del diseño del sistema, el control del flujo de información,
los problemas que generan las señales asíncronas y técnicas para sincronizarlas. Se emplea el concepto
de microinstrucción para describir lo que ocurre en cada ciclo de reloj.
6. En las secciones 6.8 a 6.12 se presentan diversos problemas resueltos: un candado flexible, un
simulador del juego profesional de dados, el controlador de una máquina surtidora de café, el simulador
de una entrada de beisbol y un multiplicador secuencial.
7. En la sección 6.13 se presenta el método de microprogramación para diseñar controladores, y se aplica
para el diseño de la máquina surtidora de café y del marcador de un juego de bolos en la sección 6.14.
PROBLEMAS
1. Escriba un programa en VHDL para un registro de desplazamiento a la izquierda de 8
bits, con borrado asíncrono.
2. Diseñe un contador MOD 11 con flip-flops J-K, y con flip-flops D. Muestre como lo
haría con un contador con carga en paralelo.
3. Escriba un programa en VHDL para un contador MOD 12 con borrado síncrono.
4. Diseñe un contador descendente de 3 bits con flip-flops tipo D.
5. Escriba Un programa VHDL para sintetizar un registro universal como el de la
Figura 7.1.6
6. Escriba un programa en VHDL para sintetizar un contador de segundos en un reloj digital,
con salida BCD, similar al de horas de la Figura 6.2.15.
7. Escriba un programa en VHDL para dividir la frecuencia de un reloj clk entre 2, 4 y 8.
8. Escriba un programa VHDL para implementar un reloj manual o automático. Utilice un
switch para determinar la condición MANUAL/AUTOMATICO, y un pulsador para generar
cada pulso en modo manual.
9. Diseñe un sistema para efectuar las microoperaciones siguientes:
T1: AA´, FF´
T2F : AA+B
T3 : AA+B´, F1
A y B son registros de 8 bits, F la salida de un flip-flop JK
8. Dibuje la arquitectura para realizar la microoperación A7: AA+1 si
a. A es un registro con carga en paralelo de 8 bits
b. A es un contador con señal de habilitación cnt.
9. Implemente el controlador del candado serial de la sección 6.7 sin codificación de
estados (one-hot)
10. Implemente el controlador del simulador del juego de dados de la sección 6.9
mediante un PLA.
11. Implemente el controlador de l máquina surtidora de café de la sección 6.10
mediante el controlador programable MP1.
12. Implemente el controlador del multiplicador secuencial de la sección 6.12
13. Implemente el controlador del multiplicador secuencial de la sección 6.12
mediante compuertas, y mediante MUXes.
14. Implemente el controlador del candado serial mediante el controlador programable
MP1.
15. Muestre el diagrama de estados del controlador del juego de boliche con 16
estados
16. Diseñe el marcador de un set de tenis que disputan los jugadores A y B,
considerando las reglas siguientes:
El set lo gana el jugador que obtenga 6 juegos, con una diferencia de al menos 2
juegos (6-0, 6-1,…6-4).
En caso de empate a 5 juegos, se puede ganar el set 7-5. Si hay empate en 6, se
pasa a muerte súbita.
En muerte súbita, gana el jugador que obtenga 7 puntos, con una diferencia
mínima de 2 (7-0, 7-1,…7-5). En caso de empate a 6, se sigue jugando hasta que
un jugador obtenga una diferencia de 2 puntos (8-6,9-7, etc.).
Un juego se gana logrando 4 puntos con diferencia de al menos 2: (4-0,4-1,4-2).
En caso de empate a 3 (denominado deuce), se sigue jugando hasta que
un jugador obtenga una diferencia de 2 puntos. No se contabiliza ya más que
deuce o ventaja; gana el juego así el jugador que obtenga el punto teniendo
ventaja.
17. Diseñe el simulador de un repartidor de cartas (“dealer”) del juego de “Black
-jack”. Las cartas del 2 al 10 valen de 2 a 10 puntos; el jack, dama y rey también
valen 10 puntos. El as vale originalmente 11 puntos, pero puede cambiar a 1
punto. Así, un as y un 10, jack, dama o rey resultan en 21 puntos. El objeto del
juego es lograr un número de puntos lo más cercano a 21.
Las reglas que tiene el repartidor son: Se sirve 2 cartas. Mientras tenga menos de
19 puntos deberá seguir tomando cartas. Si obtiene de 17 a 21 puntos, puede
tomar más cartas (se queda). Si rebasa los 21 puntos, pierde. En caso de que
tenga un as contabilizado con 11 puntos, podrá cambiarlo a 1 punto y seguir el
juego con las mismas reglas.
Haga su diseño capturando valores a partir de switches o un teclado, y
use componentes SSI y MSI. Sintetice y simule también su diseño por medio de
un programa VHDL.
18. Diseñe un cronómetro que cuenta minutos y segundos cuando se habilita un
botón start_stop; la cuenta se suspende cuando se oprime de nuevo el botón. El tiempo debe
exhibirse por medio de LEDs de 7 segmentos.
19. Escriba un programa VHDL para convertir un número binario de 8 bits en 3 dígitos BCD.
Experimentos sugeridos
1. Implemente el multiplicador secuencial de 4 bits en un FPGA usando una tarjeta de
desarrollo. Utilice switches para los operandos, y los programas de los problemas 8 y
19 para visualizar el resultado con cada pulso de reloj.