Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
1.1.
En los captulos anteriores se describi el proceso de diseo para sistemas digitales y las herramientas disponibles (tanto software como hardware) para su implementacin. En este captulo
se trataran ejemplos prcticos de diseo de sistemas digitales, iniciando con su descripcin hasta
llegar a su implementacin nal utilizando en algunos casos componentes discretos y VHDL.
1.2.
Una mquina de estados es un sistema secuencial sincrnico que posee un nmero jo de posibles
estados. El valor de sus salidas y la transicin entre los estados depende del valor de sus entradas
y del estado en que se encuentra actualmente. Todos los cambios de estado ocurren ante un
determinado anco de la seal de reloj (ya sea de subida o bajada).
Para entender mejor este concepto imaginemos que nuestra mquina de estados es un televisor,
que slo puede sintonizar cuatro canales y que se puede controlar por un control remoto que
tiene solo dos teclas para aumentar o disminuir el canal. Los estados de nuestro sistema estn
representados por el nmero de canales que se pueden sintonizar, as pues, solo tendremos cuatro
posibles estados (Nmero jo de estados). En la Figura 1 se muestra un diagrama de nuestro
sistema:
Existen varias formas de representar el comportamiento de las mquinas de estado, siendo los
ms utilizados las tablas y los diagramas de estado. Tomemos nuevamente el ejemplo del televisor
y representemos en una tabla los estados actual y siguiente (Estado al que pasa el sistema ante un
cambio de las entradas).
La Figura 2 muestra el sistema como una caja negra en la que slo se indican las entradas
y las salidas. Supongamos que nuestro sistema tiene dos entradas que son las correspondientes a
Adelantar (UP) y disminuir (DN) canal, y que tiene cuatro salidas C1, C2, C3, C4 que corresponden
a los cuatro canales y que me indican cual canal se est sintonizando actualmente. En este punto
debemos tomar varias decisiones:
Cuando se considera que una entrada esta activa?, Es decir, con que valor lgico de la entrada
se produce un cambio y con cual no. En nuestro caso un valor lgico alto en las entradas producir
un cambio de estado, es decir, si UP = `1' el canal sintonizado aumentar o si DN = `1' el canal
disminuir. Otra decisin que debemos tomar y que se deriva de esta es: que sucede si por error
las dos entradas son `1' simultneamente, lo ms conveniente es que el sistema conserve su estado
ante esta posible situacin.
El valor de las salidas para cada estado, en este ejemplo, un uno lgico en una salida indica
que el canal ha sido seleccionado (por ejemplo, un uno en C1 indicara que actualmente el canal
seleccionado es el 1), por lo tanto slo una salida puede tener un valor lgico alto.
Una vez denido completamente el funcionamiento de nuestro sistema se procede a representarlo
mediante una tabla de estados:
1.3.1.
Tabla de Estados
Salidas
Estado Actual
!UP.!DN
!UP.DN
UP.!DN
UP.DN
C1,C2,C3,C4
Canal 1
Canal 1
Canal 4
Canal 2
Canal 1
1,0,0,0
Canal 2
Canal 2
Canal 1
Canal 3
Canal 2
0,1,0,0
Canal 3
Canal 3
Canal 2
Canal 4
Canal 3
0,0,1,0
Canal 4
Canal 4
Canal 3
Canal 1
Canal 4
0,0,0,1
1.3.2.
Diagrama de Estados
SINTESIS DE FSM
1.4.1.
Lgica de estado siguiente: Est encargada de generar las seales necesarias para producir un
cambio de estado en la FSM (Estado Siguiente). Puede observarse que el estado siguiente depende
del estado actual y de las entradas
Memoria de Estado: Normalmente esta formada por Flip-Flops tipo D o JK, los cuales tienen
la misma seal de reloj. Las salidas de los Flip-Flops determinan el estado actual de la FSM, cada
salida del Flip-Flop puede tomar dos valores distintos `1' o `0', por lo tanto se pueden tener dos
estados con un Flip-Flop. Si tenemos N Flip-Flops tendremos 2N estados.
Lgica de Salida: La lgica de salida esta encargada de producir los valores necesarios a la salida
de la FSM, su la arquitectura esta basada en decodicadores.
Existen dos tipos de mquinas de estados: Moore: El estado siguiente depende del valor de las
entradas y del estado actual; Y la salida depende nicamente del estado actual; y Mealy: Al igual
que la mquina de Moore el estado siguiente depende del valor de las entradas y del estado actual,
pero se diferencian en que la salida depende del estado actual y del valor de las entradas.
1.4.2.
Proceso de Sntesis
El primer paso en el proceso de sntesis de una FSM y en general de cualquier sistema digital
es la descripcin del sistema ya sea mediante un algoritmo o de un diagrama de tiempos. El
siguiente paso consiste en pasar la descripcin funcional a un diagrama de estados para su posterior
representacin en tablas de estado y de salida. A continuacin debemos reducir el nmero de estados
(si es posible) utilizando algoritmos de minimizacin. Despus debemos realizar la codicacin de
estados, es decir, asignarle a los estados un grupo nico de valores que corresponden a los valores
que tomarn los Flip-Flops. A continuacin se debemos obtener las ecuaciones de estado siguiente
y de salidas. El siguiente paso consiste en la eleccin del tipo de Flip-Flop que se va a utilizar
para la implementacin, recuerde que todos los Flip_Flops tienen diferentes ecuaciones de estado
siguiente:
Tipo de F-F
Q* = D
JK
Q* = J,!Q + !K.Q
Q* = !Q
SR
Q* = S + !R.Q
S1
V+
GND
V+
GND
S2
V+
GND
GND
V+
S3
GND
V+
GND
V+
S4
GND
V+
V+
GND
Para que el motor gire un paso (normalmente 1.8 grados) es necesario que se aplique S1 y luego S2,
o S2 y S3 o S3 y S4 o S4 y S1. Si se desea que el motor gire cinco pasos se debe seguir la secuencia
S1, S2, S3, S4, S5. La inversin del sentido de giro se logra invirtiendo la secuencia anterior, es
decir, S1, S4, S3, S2, S1.
Diagrama de Caja Negra El primer paso consiste en realizar un diagrama de caja negra en el
que se indiquen las entradas y salidas (Figura 7).
Figura 7. Diagrama de
Caja Negra del Controlador de Motor de Paso.
A continuacin realizaremos una breve descripcin del funcionamiento del circuito. Como se
observa en la Figura 7. Se tienen tres entradas:
DIR: Encargada de indicar la direccin de giro del motor. DIR = 0 Secuencia Directa (S1,
S2, S3, S4), DIR = 1 Secuencia Invertida (S4, S3, S2, S1) EN: ENABLE, encargada de habilitar
nuestro control Si EN = 1 el circuito realizar su funcin si EN = 0 el control conservar el ltimo
estado de las salidas.
CLOCK: Es el reloj del sistema y gobierna todas las transiciones entre estados. Y las cuatro
salidas A, B, C, D son las encargadas de manejar los terminales del motor de paso.
Diagrama de Estado Una vez se conoce el funcionamiento del circuito, o las funciones que
debe cumplir se procede a realizar el diagrama de estados del mismo. La Figura 8 muestra este
diagrama para el controlador de motor de paso.
Salidas
Estado Actual
!EN.!DIR
!EN.DIR
EN.!DIR
EN.DIR
A, B, C, D
S1
S1
S1
S2
S4
1, 0, 1, 0
S2
S2
S2
S3
S1
1, 0, 0, 1
S3
S3
S3
S4
S2
0, 1, 0, 1
S4
S4
S4
S1
S3
0, 1, 1, 0
estados en mltiplos de 2. Por ejemplo, supongamos que tenemos 7 estados, para lo cual necesitamos
3 FFs, para utilizar slo 2 FFs necesitamos reducir el nmero de estados de 7 a 4 o menos.
La minimizacin de estados se basa en la equivalencia funcional, por ejemplo, se dice que
dos circuitos son equivalentes cuando proporcionan la misma salida ante los mismos cambios de
entrada. Dos o ms estados son equivalentes s:
Ambos estados producen las mismas salidas ante igual cambio en las seales de entrada. Ambos
estados tienen los mismos estados siguientes ante los mismos cambios de las seales de entrada.
En nuestro caso no tenemos equivalentes ya que todos tienen diferentes valores de salida y
diferentes estados siguientes ante variaciones de las entradas.
salidas de los FFs para cada estado, estos valores deben ser nicos para cada estado, es decir,
no se deben repetir. Debido a que nuestra mquina tiene cuatro estados, tenemos 2 FFs y por lo
tanto debemos asignar a cada estado un cdigo formado por dos bits. Existen muchas posibles
codicaciones para los cuatro estados, unas ms ecientes que otras. En este libro no se tratarn
las tcnicas existentes para hallar la codicacin ptima ya que esta funcin las realizan las herramientas CAD y adems, se sale del objetivo de este libro. Para nuestro ejemplo utilizaremos la
siguiente codicacin:
Q1
Q0
S1
S2
S3
S4
Donde Q1 y Q0 son las salidas del primer y segundo FF correspondientemente. Con esta
asignacin de estados la tabla de estados queda de la siguiente forma:
Estado
Actual
(S)
SALIDAS
EN
!DIR
DIR
A, B, C, D
Q1*
0
Q0*
0
Q1*
0
Q0*
1
Q1*
1
Q0*
1
1, 0, 1, 0
1, 0, 0, 1
0, 1, 0, 1
0, 1, 1, 0
Q1
Q0
Donde Q1* y Q0* representan los valores siguientes de las seales Q1 y Q0 respectivamente.
Note que no se representaron los casos !EN.!DIR y !EN.DIR, esto se debe a que cuando la seal
En tiene un valor lgico bajo la FSM conserva su estado sin importar el valor de DIR.
obtencin de las ecuaciones de estado siguiente Q1* y Q0* . Para obtener estas ecuaciones debemos
sumar todos los unos de la tabla de estados (suma de minitrminos). Para Q1* debemos observar
todas las columnas correspondientes a Q1* y sumar los minitrminos asociados. Por ejemplo, la
primera columna de Q1* correspondiente a la asociada con !EN, el primer minitrmino asociado
es: !EN.Q1.!Q0 ya que est en la la correspondiente a Q1 = 1 y Q0 = 0. Y el segundo !EN.Q1.Q0.
Q1* = !EN.Q1.!Q0 + !EN.Q1.Q0 + EN.!DIR.!Q1.Q0 + EN.!DIR.Q1.!Q0 + EN.DIR.!Q1.!Q0
+ EN.DIR.Q1.Q0.
Q0* = !EN.!Q1.Q0 + !EN.Q1.Q0 + EN.!DIR.!Q1.!Q0 + EN.!DIR.Q1.!Q0 + EN.DIR.!Q1.!Q0
+ EN.DIR.Q1.!Q0.
Estas ecuaciones deben pasar a travs de un proceso de minimizacin para encontrar una
implementacin ptima.
SR
JK
00
0X
0X
01
10
1X
10
01
X1
11
X0
X0
00
01
11
10
00
01
11
10
00
01
11
10
00
01
11
10
11
00
10
01
01
10
00
11
La regin sombreada corresponde a los valores de las seales Q1* (en negrilla) y Q0*.
Para el FF D tenemos: Q* = D. Por lo tanto:
D1 = !EN.Q1 + EN.DIR (Q1 XOR Q0) D0 = EN XOR Q0
Para el FF JK debemos ordenar las ecuaciones obtenidas de la forma: Q* =J.!Q + !K.Q, por
lo que para Q1:
00
01
11
10
00
01
11
10
0X
0X
X0
X0
0X
0X
X0
X0
1X
0X
X0
X1
0X
1X
X1
X0
La regin sombreada indican los valores que deben tener las seales J1(en negrilla) y K1.
J1 = !Q1.!Q0.EN.DIR + !Q1.Q0.EN.!DIR = EN.!Q1(Q0 XOR DIR) K1 = Q1.!Q0.EN.DIR +
Q1.Q0.EN.!DIR = EN.Q1.(Q0 XOR DIR)
Para Q0
00
01
00
01
11
10
0X
X0
0X
X0
1X
X1
1X
X1
X0
0X
X0
0 X
X1
1X
00
01
11
10
00
01
11
10
11
10
X1
1X
J0 = EN K0 = EN
Flip-Flop tipo T:
Para Q1:
01
11
10
00
01
11
10
00
01
11
10
T0 = EN
Flip-Flop tipo SR.
Para Q1:
00
01
11
10
0X
0X
X0
X0
0X 10
0X 0X
X0 X0
X0 01
0X
10
01
X0
00
01
11
10
00
01
11
10
0X
X0
X0
0X
0X
X0
X0
0X
10
01
01
10
10
01
01
10
S0 = EN.!Q0 R0 = EN.Q0
Del anlisis anterior observamos que la implementacin que ocupa el menor nmero de compuertas es la correspondiente a los Flip-Flops tipo T.
En esta seccin se realizar la descripcin en VHDL del controlador de motor de paso. Inicialmente se har una descripcin estructural, basndose en los resultados obtenidos en la seccin
5.4.3.7. Y a continuacin se utilizar la descripcin funcional para la implementacin del controlador.
no
PORT(
A
B
Y
: IN BIT ;
: IN BIT ;
: OUT BIT ) ;
END and2 ;
ARCHITECTURE Y OF and2 IS
BEGIN
END;
Y <= A AND B ;
A : IN BIT ;
B : IN BIT ;
Y : OUT BIT ) ;
END xor2 ;
ARCHITECTURE XR OF xor2 IS
BEGIN
Y <= A XOR B ;
END;
INVERSOR ENTITY i n v IS
PORT(
A : IN BIT ;
Y : OUT BIT ) ;
END i n v ;
ARCHITECTURE NO OF i n v IS
BEGIN
Y <= not (A ) ;
END;
T ENTITY FFT IS
BIT ;
BIT ) ;
OF FFT I I S
BEGIN
process (CLK) begin
i f (CLK' e v e n t and CLK = ' 1 ' ) then
i f ( t = ' 1 ' ) then
Q <= not (Q) ;
e lse
Q <= Q;
end i f ;
end i f ;
end process ;
END;
Una vez realizada la implementacin de los componentes, se procede a su unin. Para lograr esto
se deben sintetizar las anteriores declaraciones, y sus archivos deben estar en el mismo directorio
de trabajo.
Y : OUT BIT ) ;
END COMPONENT;
COMPONENT XOR2
PORT (A, B : IN BIT ;
Y : OUT BIT ) ;
END COMPONENT;
COMPONENT INV
PORT (A : IN BIT ;
Y : OUT BIT ) ;
END COMPONENT;
COMPONENT FFT
PORT(
CLK, T : IN BIT ;
Q : OUT BIT ) ;
END COMPONENT;
BEGIN
library i e e e ;
USE i e e e . s t d _ l o g i c _ 1 1 6 4 . a l l ;
USE i e e e . s t d _ l o g i c _ a r i t h . a l l ;
ENTITY FSMF IS
PORT(
clk
: IN s t d _ l o g i c ;
EN, DIR
: IN s t d _ l o g i c ;
A, B, C, D : OUT s t d _ l o g i c ) ;
END FSMF;
ARCHITECTURE f u n c i o n a l OF FSMF IS
TYPE e s t a d o s IS ( S1 , S2 , S3 , S4 ) ;
SIGNAL s t a t e : e s t a d o s ;
BEGIN
PROCESS ( c l k )
BEGIN
IF ( c l k ' e v e n t and c l k = ' 1 ' ) then
case s t a t e i s
when S1 => A <= ' 1 ' ; B <= ' 0 ' ; C <= ' 1 ' ; D <= ' 0 ' ;
IF (EN = ' 0 ' ) then
s t a t e <= S1 ;
ELSE
s t a t e <= S4 ;
END IF ;
when S2 => A <= ' 1 ' ; B <= ' 0 ' ; C <= ' 0 ' ; D <= ' 1 ' ;
IF (EN = ' 0 ' ) then
s t a t e <= S2 ;
ELSE
s t a t e <= S1 ;
END IF ;
when S3 => A <= ' 0 ' ; B <= ' 1 ' ; C <= ' 0 ' ; D <= ' 1 ' ;
IF (EN = ' 0 ' ) then
s t a t e <= S3 ;
ELSE
s t a t e <= S2 ;
END IF ;
when S4 => A <= ' 0 ' ; B <= ' 1 ' ; C <= ' 1 ' ; D <= ' 0 ' ;
IF (EN = ' 0 ' ) then
s t a t e <= S4 ;
ELSE
s t a t e <= S3 ;
END IF ;
END CASE;
END IF ;
END PROCESS;
END f u n c i o n a l ;
SIGNAL B : std_logic;
SIGNAL C : std_logic;
SIGNAL D : std_logic;
constant ncycles : integer := 40;
constant halfperiod : time := 5 ns;
BEGIN
uut: fsmf PORT MAP(
clk => clk,
EN => EN,
DIR => DIR,
A => A,
B => B,
C => C,
D => D);
-- Generacion del Reloj
Clock_Source: process
begin
for i in 0 to ncycles loop -- Genera ncyclos de periodo 10 ns
BEGIN
for i in 1 to ncycles/4 loop -- Durante ncyclos/4 genera las diferentes
wait until Clk='1' and Clk'event; -- Combinaciones de EN y DIR
EN <= '0';
DIR <= '0';
end loop;
for i in 1 to ncycles/4 loop
wait until Clk='1' and Clk'event;
EN <= '0';
DIR <= '1';
end loop;
for i in 1 to ncycles/4 loop
wait until Clk='1' and Clk'event;
EN <= '1';
DIR <= '0';
end loop;
for i in 1 to ncycles/4 loop
wait until Clk='1' and Clk'event;
EN <= '1';
DIR <= '1';
end loop;
END PROCESS;
END;
En donde se puede observar que se lleg a las mismas ecuaciones obtenidas anteriormente.
Observe que se utilizaron 2 Flip-Flops tipo T uno de los cuales tiene a la seal EN como entrada
(primera sea que aparece dentro de los parntesis despus de TFFE. ). Mientras que el otro tiene
a la seal _EQ001 conectada a su entrada T. La ecuacin para _EQ001 es:
!DIR & EN & state1 # DIR & EN & !state1 = EN.((!DIR.sate1) + (DIR.!state1)
Como vimos en captulos anteriores la arquitectura de un CPLD no posee compuertas XOR,
por lo tanto las ecuaciones son de la forma de suma de productos. Lo interesante es observar el
ahorro de tiempo asociado a la utilizacin del VHDL como herramienta de diseo.
2.
2.1.
INICIO
PP=0, I=0
A=MD, Load B
SI
NO
LSBB=0?
PP=PP + A
A = A << 1
B = B >> 1
NO
B=0?
SI
DONE
INICIO
PP=0, I=0
A=MD, Load B
SI
NO
LSBB=0?
ACUMULADOR
PP=PP + A
CORRIMIENTO A LA IZQUIERDA
A = A << 1
B = B >> 1
NO
CORRIMIENTO A LA DERECHA
SI
B=0?
DONE
COMPARADOR
Figura 4: Identicacin de los componentes del camino de datos para el multiplicador de numeros
binarios.
MD
MR
LSR
SH
SHIFT
LOAD
RESET
A
ACC
RSR
SHIFT
LOAD
B
COMP
RESET
ADD
ADD
Z
PP
Figura 5: Identicacin de las seales de control e interconexin del camino de datos.
La primera operacin que aparece en el diagrama de ujo es la del acumulador, el cual acumula
el valor de la salida del registro de corrimiento que almacena el multiplicando, de aqu obtenemos la
conexin entre el registro de corrimiento (LSR) a la izquierda y el acumulador (ACC). La segunda
operacin que aparece es la de los registros de corrimiento, por lo que los valores del multiplicando
y multiplicador deben cargarse para su posterior corrimiento a las unidades de corrimiento a la
izquierda y derecha respectivamente. La salida del corrimiento a la derecha del multiplicador es
comparada en cada ciclo para determinar si se lleg al nal del algoritmo, por lo que la entrada
del comparador es la salida del registro de corrimiento del multiplicador.
Para determinar las seales de control de cada componente del camino de datos, se debe identicar su funcin y las operaciones que debe realizar; los registros de corrimiento deben permitir
la carga de un valor inicial y el corrimiento de las mismas, esto se realiza con las seales LOAD
y SHIFT respectivamente; el acumulador debe tener la posibilidad de inicializarse en cero y una
seal para que sume el valor de la entrada al que tiene almacenado, esto se hace con las seales
RESET y ADD ; por ltimo el comparador debe proporcionar una seal que indique que el valor
de su entrada es igual a cero, Z en este caso.
Aunque es posible que la mquina de control maneje todas las seales de control del camino de
datos, es mejor aguparlas de acuerdo a su activacin; esto es, si una seal se activa al mismo tiempo
que otra, se puede utilizar una seal que las controle a ambas. Para esto se utiliza el diagrama de
ujo y se observa en que momento se realizan las operaciones: Se observa que se cargan los valores
de los registros de corrimiento y se inicializa en cero el acumulador nicamenet al comenzar el
algoritmo y durante la ejecucin del mismo no se vuelve a relizar esta operacin, por este motivo
utilizaremos la misma seal (RESET ) para cargar los registros de desplazamiento e inicializar en
cero el acumulador; la seal que controla el momento en que el acumulador se incrementa es nica,
ya que no se realiza ninguna operacin en ese punto del algoritmo y en este caso recibe el nombre
de ADD ; las operaciones de corrimiento se realizan en el mismo lugar, por lo que se puede utilizar
una seal comn, que en este caso llamaremos SH ; por ltimo la salida del comparador Z y el bit
menos signicativo de B LSB son seales de salida del camino de datos que le darn a la unidad
de control la informacin necesaria para tomar la accin adecuada en los bloques de decisin.
INIT=0
SI
NO
LSBB=0?
CHECK
START
Z=1
PP=PP + A
INIT
DONE=0,
RESET=1
SH=0, ADD=0
DONE=0,
RESET=0
SH=0, ADD=0
Z=0
LSB=0
A = A << 1
B = B >> 1
NO
B=0?
SI
LSB=1
SHIFT
ADD
DONE=0,
RESET=0
SH=1, ADD=0
DONE=0,
RESET=0
SH=0, ADD=1
DONE
La mquina de estados debe iniciar en START y se queda en este estado siempre que la seal
INIT tenga un valor de `0', En el estado INIT la seal RESET = `1', con lo que el valor del
acumulador se hace cero y se cargan los registros A y B. Cuando INIT = `1', entramos al estado
CHECK el cual evala la seal LSB, s LSB = `0', no se debe realizar la suma de MD, pero si se
debe realizar un corrimiento para obtener el siguiente bit del multiplicador y realizar el corrimiento
necesario en MD. Si LSB = `1' se debe sumar el valor de las salidas de LSR al valor del acumulador,
y despus se debe realizar un corrimiento. En el estado ADD se hace la salida ADD = `1' para
que el valor a la entrada del acumulador se sume al valor almacenado en l. En el estado SHIFT
se realiza el corrimiento de RSR y LSR haciendo el valor de la seal SH = 1.
Para vericar el buen funcionamiento del diagrama de estado debemos realizar una prueba de
escritorio: Supongamos que tenemos A = 7 y B = 5 y que INIT = 1:
ESTADO
SH
LSR
RSR
LSB
ADD
DONE
ACC
CHECK
00000111
0101
00000000
ADD
00000111
0101
00000111
SHIFT
00001110
0010
00000111
CHECK
00001110
0010
00000111
SHIFT
00011100
0001
00000111
CHECK
00011100
0001
00000111
ADD
00011100
0001
00100011
SHIFT
00111000
0000
00100011
CHECK
00111000
0000
00100011
END1
00111000
0000
00100011
START
00000111
0101
00000000
Como puede observarse el resultado es correcto (35), en la tabla las casillas sombreadas corresponden a las seales que cambian de un estado a otro.
2.1.6. Simulacin
Como se mencion anteriormente, es posible realizar las simulaciones utilizando las herramientas
grcas de cada uno de los entornos de desarrollo que proporcionan los fabricantes de dispositivos
lgicos programables, sin embargo, su uso diculta la portabilidad del diseo. Por este motivo,
se recomienda el uso de testbench escritos con el lenguaje estndard. Como parte del proceso de
diseo, cada mdulo debe ser simulado antes de ser integrado en la descripcin de ms alto nivel.
Es bueno tener en cuenta los diferentes niveles de simulacin que se pueden realizar a un
sistema bajo prueba; la simulacin ms rpida es la que tiene en cuenta nicamente el lengiaje
de descripcin de hardware utilizado, sin embargo, no es posible garantizar que los resultados del
circuito sintetizado sean los mismos que la simulacin del lenguaje; por esto, existe la simulacin
2.1.7. Pruebas
Aunque la simulacin es una buena herramienta para la deteccin de errores, es necesario
realizar una prueba sobre el circuito congurado en el dispositivo lgico programable, para esto
existen dos opciones: realizar el montaje de la aplicacin y probar la funcionalidad del dispositivo
congurado, dependiendo de la complejidad del sistema esta puede ser una tarea tediosa; la segunda
opcin es utilizar el puerto JTAG para aplicar los vectores de prueba y capturar los resultados,
este proceso se describir en la siguiente seccin.
2.2.
Slo hasta el sexto resultado parcial obtenemos un cero en la primera cifra de la resta (recuerde
que en complemento a dos los nmeros tienen una longitud ja en nuestro caso 4 bits, s una
operacin provoca un bit adicional este se descarta, los bits descartados se encerraron en lneas
punteadas en la Figura 7), lo que indica que el nmero es mayor o igual que el divisor, en este caso,
se coloca un `1' en el resultado parcial y se conserva el valor de la operacin de resta, el cual se
convierte en el nuevo residuo parcial, este proceso se repite hasta haber bajado todos los dgitos
del dividendo. En la Figura 24 se muestra el algoritmo de divisin de dos nmeros sin signo.
PORT(
clk,shift,load,reset: IN STD_LOGIC;
Data,DataL: IN STD_LOGIC_VECTOR(width downto 0);
Qlsr:
BUFFER STD_LOGIC_VECTOR(width downto 0));
END Component;
Component Decrement
Port(
Clk,Init,dec : IN STD_LOGIC;
Z : OUT STD_LOGIC);
End Component;
Component addsub
GENERIC(width:natural:=7);
PORT(
clk,reset,add,sub: IN STD_LOGIC;
msb:
OUT STD_LOGIC;
A,B : IN STD_LOGIC_VECTOR(width downto 0);
AS:
BUFFER STD_LOGIC_VECTOR(width downto 0));
END Component;
Signal ld,sh,re,ad,su,Z,msb,de,q0,sq : STD_LOGIC;
Signal INN1
:STD_LOGIC_VECTOR(width downto 0);
Begin
A1: lsr
Generic map(width)
Port Map(clk,sh,ld,re,A,INN1,R);
A2: lsrq
Generic map(width)
Port Map(clk,sq,q0,re,D);
A3: Decrement
Port Map(Clk,re,de,Z);
A4: AddSub
Generic map(width)
Port Map(clk,re,ad,su,msb,R,B,INN1);
A5: Controll
Port Map(Clk,Init,msb,Z,sh,re,q0,done,su,ad,de,ld,sq);
End Estructural;
CONTROLL
Begin
Process (Init,msb,Z, current_state)
Begin
Case current_state is
When rst => shift <= '0';reset <= '0';q0 <= '0';sub <= '0';
add <= '0';dec <='0'; load <= '0';done <= '0';sq <= '0';
if init = '1' then
next_state <= wait1;
else
When subb => shift <= '0';sub <= '1';reset <= '0';add <= '0';
else
q0 <= '1';
load <= '1';
end if;
next_state <= check1;
when check1 => shift <= '0';sub <= '0';add <= '0';reset <= '0';
dec <='0';done <= '0';sq <= '0';
if Z = '1' then
next_state <= end1;
else
Begin
if (clk'event and clk = '0') then
LSRQ
Este bloque es un registro de corrimiento a la izquierda con una entrada que determina el valor
del bit menos signicativo. Su descripcin funcional es la siguiente:
Library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY lsrq IS
GENERIC(width:natural:=7);
PORT(
clk,shift,DIN,reset : IN STD_LOGIC;
Qlsrq : BUFFER STD_LOGIC_VECTOR(width downto 0));
END lsrq;
Architecture funcional of lsrq is
Begin
Process(Clk)
Begin
if (Clk'event and Clk = '1') then
if reset = '1' then
Qlsrq <= "00000000";
else
LSR
Este mdulo est encargado de realizar el corrimiento a la izquierda del dividendo y almacenar
los resultados de la resta. La descripcin funcional de este mdulo es el siguiente:
Library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY lsr IS
GENERIC(width:natural:=7);
PORT(
clk,shift,load,reset: IN STD_LOGIC;
Data,DataL: IN STD_LOGIC_VECTOR(width downto 0);
Qlsr:
BUFFER STD_LOGIC_VECTOR(width downto 0));
END lsr;
ARCHITECTURE funcional OF lsr IS
SIGNAL INN1: STD_LOGIC_VECTOR(width downto 0);
BEGIN
Process(CLK)
Begin
if (clk'event and clk = '1') then
if Reset = '1' then
Qlsr <="00000000";
else
DECREMENT
Este mdulo est encargado de controlar el nmero de veces que se realizan las iteraciones. La
descripcin funcional se muestra a continuacin:
Library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
Entity Decrement is
Port(
Clk,Init,dec : IN STD_LOGIC;
Z : OUT STD_LOGIC);
End Decrement;
Architecture funcional of Decrement is
Signal INN1 : Std_logic_vector (2 downto 0);
signal end1 : Std_Logic;
Begin
Process (Clk,dec)
Begin
if (Clk'event and Clk = '1') then
if Init = '1' then
Z <= '0';
INN1 <= "111";
end1 <= '0';
elsif (dec = '1' and end1 = '0') then
if (INN1 > 0) then
z <= '0';
INN1 <= INN1 - 1;
else
z<= '1';
end1 <= '1';
End if;
else
End if;
End Process;
End funcional;
ADDSUB
Este mdulo est encargado de realizar la resta para determinar si al nmero contenido en el
mdulo LSR se le puede restar el divisor. La descripcin funcional de este mdulo se muestra a
continuacin.
Library IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY addsub IS
GENERIC(width:natural:=7);
PORT(
clk,reset,add,sub: IN STD_LOGIC;
msb:
OUT STD_LOGIC;
A,B : IN STD_LOGIC_VECTOR(width downto 0);
AS:
BUFFER STD_LOGIC_VECTOR(width downto 0));
END addsub;
ARCHITECTURE funcional OF addsub IS
BEGIN
PROCESS (clk, Reset)
BEGIN
if Reset = '1' then
AS <= "00000000";
else
if (clk'event and clk='1') then
if add = '1' and sub = '0' then
AS <= A + B;
else
AS <= "00000000";
end if;
end if;
End if ;
END PROCESS;
Process(AS)
Begin
DIVISOR
Finalmente se realiz la simulacin del archivo DIVISOR.VHD. El cual contiene la unin de los
mdulos anteriores. La simulacin del divisor se muestra en la Figura 32. Y la implementacin en
VHDL del testbench se muestra a continuacin:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY testbench IS
END testbench;
ARCHITECTURE behavior OF testbench IS
COMPONENT divisor
PORT(
A : IN std_logic_vector(7 downto 0);
B : IN std_logic_vector(7 downto 0);
Init : IN std_logic;
clk : IN std_logic;
D : BUFFER std_logic_vector(7 downto 0);
R : BUFFER std_logic_vector(7 downto 0);
Done : OUT std_logic
);
END COMPONENT;
SIGNAL A : std_logic_vector(7 downto 0);
SIGNAL B : std_logic_vector(7 downto 0);
SIGNAL Init : std_logic;
SIGNAL clk : std_logic;
SIGNAL D : std_logic_vector(7 downto 0);
SIGNAL R : std_logic_vector(7 downto 0);
SIGNAL Done : std_logic;
constant ncycles : integer := 80;
constant halfperiod : time := 5 ns;
BEGIN
begin
for i in 0 to ncycles loop -- Genera ncyclos de periodo 10 ns
CLK <= '0';
A <= "01100100";
B <= "00000011";
INIT <= '0'; wait for halfperiod;
INIT <= '1';
wait until CLK'event and CLK='1';
begin
begin
Se desea disear un sistema digital que sea capaz de medir segundos y dcimas de segundo
utilizando una fuente de reloj externa de FMHZ MHz y dos displays de 7 segmentos para la
visualizacin. El diagrama de bloques del sistema aparece en la Figura 34.
de frecuencia programable no tiene una entrada ja, esta entrada depende de la disponibilidad del
sistema, por lo que en este caso es un genrico. El cdigo en VHDL del contador es el siguiente:
Library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
Entity clk_div Is
GENERIC( FMHZ: Natural := 8 ); -- FMHZ genrico 8MHz por defecto
PORT(
clock_FMHZ : IN STD_LOGIC; -- Seal de reloj externa.
Reset : IN Std_Logic; -- Reset del Mdulo
clock_1Hz : OUT STD_LOGIC); -- Salida a 1Hz.
end clk_div;
Architecture RT of clk_div is
Signal count_1Mhz : Std_Logic_Vector(4 DOWNTO 0);
Signal Clock_1MHz : Std_Logic;
Signal Count_1Hz : Integer Range 0 to 1000000;
Begin
Process
Begin
else
else
else
Begin
if Reset = '0' then
Count_1Hz <= 0;
else
if clock_1Mhz'event and clock_1Mhz = '1' then
if count_1Hz < 1000000 then
count_1Hz <= count_1Hz + 1;
else
count_1Hz <= 0;
end if;
if count_1Hz < 5000000 then
clock_1Hz <= '0';
else
Begin
Process (Clock, Reset)
Begin
If Reset = '0' then
Unidades <= "0000";
Decenas <= "0000";
else
if Clock'event and Clock = '1' then
If Unidades < "1001" then
else
else
GENERIC(
FMHZ: Natural := 8;
TD : Natural := 20 ); -- FMHZ genrico 8MHz por defecto
PORT(
clock_FMHZ : In Std_Logic; -- Seal de reloj externa.
Reset : In Std_Logic; -- Reset del Mdulo
clock_1Hz : Out Std_Logic;
Clock_TD : Out Std_Logic ); -- Salida a 1Hz.
END clk_div2;
Architecture RT of clk_div2 is
Signal count_1Mhz : STD_LOGIC_VECTOR(4 DOWNTO 0);
Signal Clock_1MHz : Std_Logic;
Signal Clock_1ms : Std_Logic;
Signal Count_1Hz : Integer Range 0 to 100;
Signal Count_1ms : Integer Range 0 to 100;
Signal Count_TDms : Integer Range 0 to 100;
Begin
Process
Begin
else
else
else
Begin
if Reset = '0' then
Count_1ms <= 0;
else
if clock_1Mhz'event and clock_1Mhz = '1' then
if count_1ms < 1000 then
count_1ms <= count_1ms + 1;
else
count_1ms <= 0;
end if;
if count_1ms < 500 then
clock_1ms <= '0';
else
Begin
if Reset = '0' then
Count_1Hz <= 0;
else
if clock_1ms'event and clock_1ms = '1' then
if count_1Hz < 1000 then
count_1Hz <= count_1Hz + 1;
else
count_1Hz <= 0;
end if;
if count_1Hz < 500 then
clock_1Hz <= '0';
else
Begin
if Reset = '0' then
Count_TDms <= 0;
else
if clock_1ms'event and clock_1ms = '1' then
if count_TDms < TD then
count_TDms <= count_TDms + 1;
else
count_TDms <= 0;
end if;
if count_TDms < TD/2 then
clock_TD <= '0';
else
Architecture RT of Show is
Signal Binary : Std_logic_Vector ( 3 downto 0 );
Type Estados is ( Show_Decenas, Show_Unidades );
Signal State : Estados;
Begin
Process( Binary )
Begin
Case Binary is
When "0000" =>
BCD_Out <= "0111111";
When "0001" =>
BCD_Out <= "0100001";
When "0010" =>
BCD_Out <= "1110110";
When "0011" =>
BCD_Out <= "1110011";
When "0100" =>
BCD_Out <= "1101001";
When "0101" =>
BCD_Out <= "1011011";
When "0110" =>
BCD_Out <= "1011111";
When "0111" =>
BCD_Out <= "0110001";
When "1000" =>
BCD_Out <= "1111111";
When "1001" =>
BCD_Out <= "1111011";
When others =>
BCD_Out <= "0000000";
end Case;
End Process;
Process(Clk_TDms)
Begin
If (Clk_TDms'event and Clk_TDms = '1') Then
Case State is
When Show_Decenas =>
Begin
A1: clk_div2
Generic map(8, 20)
Port Map( clk, Reset, CLK1Hz, CLKTD );
A2: Contador
port map( CLK1Hz, Reset, Unidades, Decenas );
A3: Show
port map( Unidades, Decenas, CLKTD, Sel, Seven_Seg );
End Architecture Estructural;
El cdigo correspondiente al testbench del cronometro es:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY testbench IS
END testbench;
ARCHITECTURE behavior OF testbench IS
-- Component Declaration
Component cronometro
PORT(
Reset, clk : IN std_logic;
Sel : OUT std_logic_vector(1 downto 0);
Seven_Seg : OUT std_logic_vector(6 downto 0)
);
END COMPONENT;
SIGNAL Reset : std_logic;
SIGNAL clk : std_logic;
SIGNAL Sel : std_logic_vector(1 downto 0);
begin
for i in 0 to ncycles loop -- Genera ncyclos de periodo 10 ns
clk <= '0';
END PROCESS;
END;
EJEMPLO 5: Contador UP/DOWN
Begin
Process -- Este proceso elimina el ruido elctrico generado por los pulsadores
begin
wait until ( Clk'EVENT ) AND ( Clk = '1' );
SHIFT_PB( 2 Downto 0 ) <= SHIFT_PB( 3 Downto 1 );
SHIFT_PB(3) <= NOT Push_Button;
Else
Begin
If Reset = '1' then
state <= Rise;
PB_D <= '0';
else
If Clk'event and Clk = '0' then
Case state is
When Rise =>
PB_D <= '0';
else
else
CONTADOR: Este mdulo est encargado de aumentar o disminuir el valor de sus salidas de
acuerdo a la entrada que este actuando. La interfaz de este mdulo se muestra en la gura
anterior y el cdigo en VHDL se muestra a continuacin.
Library Ieee;
Use Ieee.Std_Logic_1164.all;
Use Ieee.Std_Logic_Arith.all;
Use Ieee.Std_Logic_unsigned.all;
Entity Contador is
Port(
Up : In Std_Logic;
Down : In Std_Logic;
Reset : In Std_logic;
Clk : In Std_logic;
Unidades : Buer Std_Logic_Vector( 3 Downto 0 );
Decenas : Buer Std_logic_Vector( 3 Downto 0 )
);
end Entity Contador;
Architecture RT of Contador is
Begin
Process ( Up, Down, Reset, Clk )
Begin
If Reset = '1' then
Unidades <= "0000";
Decenas <= "0000";
else
If Clk'event and clk='1' then
if Up = '1' and Down = '0' then
If Unidades < "1001" then
Unidades <= Unidades + "0001";
else
else
else
else
else
Reset : in STD_LOGIC;
Sel : Buer STD_LOGIC_VECTOR (1 downto 0);
SEG : out STD_LOGIC_VECTOR (6 downto 0)
);
end UDCounter;
architecture UDCounter_arch of UDCounter is
Component Show
Port(
Unidades : In Std_Logic_vector( 3 downto 0 );
Decenas : In Std_Logic_vector( 3 downto 0 );
Clk_TDms : In Std_Logic;
Sel : Buer Std_Logic_vector( 1 downto 0 );
BCD_Out : Out Std_Logic_Vector( 6 downto 0 ) );
End Component Show;
Component Contador
Port(
Up : In Std_Logic;
Down : In Std_Logic;
Reset : In Std_logic;
Clk : In Std_logic;
Unidades : Buer Std_Logic_Vector( 3 Downto 0 );
Decenas : Out Std_logic_Vector( 3 Downto 0 )
);
end Component Contador;
Component debounce
Port(
Push_Button, Clk : In Std_Logic;
Reset : In Std_Logic;
PB_D : Out Std_Logic);
End Component debounce;
Component clk_div2
GENERIC(
FMHZ: Natural := 8;
TD : Natural := 20 );
PORT(
clock_FMHZ : In Std_Logic;
Reset : In Std_Logic;
clock_1Hz : Out Std_Logic;
Clock_TD : Out Std_Logic );
END Component clk_div2;
Signal CLKTD, CLK1Hz, UPI, DNI : Std_Logic;
Signal Unidades, Decenas : Std_logic_vector( 3 downto 0 );
begin
A1: clk_div2
Generic map(8, 20)
Port Map( Clk, Reset, CLK1Hz, CLKTD );
A2: debounce
Port Map( Up, CLKTD, Reset, UPI );
A3: debounce
Port Map( Down, CLKTD, Reset, DNI );
A4: Contador
Port Map( UPI, DNI, Reset, CLKTD, Unidades, Decenas );
A5: Show
Port Map( Unidades, Decenas, CLKTD, Sel, SEG );
end UDCounter_arch;
La comunicacin asncrona es ampliamente utilizada en los sistemas digitales, por esta razn en
este ejemplo se disear un sistema capz de realizar una comunicacin serial asncrona.
En la Figura 40 se muestra una trama tpica de este tipo de comunicacin, el primer bit en ser
enviado es el Bit de Start ( Cero Lgico ), despus se envan los bits de datos los cuales pueden
variar de 6 a 8 Bits, a continuacin el bit de paridad el cual es til para la deteccin de errores en
la transferencia; Este bit no es obligatorio y en este ejemplo no lo utilizaremos y por ltimo est
el bit de stop.
Figura 40. Trama bsica de la transmisin asncrona: 1 bit de Start, 8 bits de Datos, un bit de
paridad ( opcional ) y un Bit de Stop.
En un protocolo asncrono el emisor y el receptor no comparten el mismo reloj, debido a esto se
debe conocer la velocidad de transmisin ( Baud Rate ) antes de iniciarse las comunicaciones. Por
lo cual los relojes internos del transmisor y el receptor se deben jar a la misma frecuencia. El
receptor sincroniza su reloj interno al iniciar cada trama, esto se puede realizar detectando la
transicin de alto a bajo en seal de recepcin.
Un concepto clave en el diseo de UARTs es que el reloj interno de la UART debe ser ms rpido
que la velocidad de transmisin. En la UART 16450 su reloj es 16 veces ms rpido que la Tasa
de Baudios. Una vez que el inicio de la transmisin se detecta se debe esperar un tiempo igual a
24 ciclos de muestreo ( 16 del Bit de Start + 8 del Bit ) esto se hace para que el receptor pueda
relizar la lectura del dato entrante en la mitad de cada BIT. Despus de esto se muestrea la seal
de entrada cada 16 ciclos del reloj de muestreo. En la Figura 41 se muestra este concepto.
n
BPS 256
begin
Process( CLK, Reset )
Begin
if clk'event and clk = '1' then
begin
Process( CLK, Reset )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
count <= ( others => '0' );
else
if Ld_Div_Low = '1' then
Div_Factor( 7 downto 0 ) <= Divider;
else
if Clk_In = '1' then
count <= count + 1;
Clk_Out <= '0';
end if;
end if ;
end if;
end if;
end process;
end Div_ms_arch;
Bejn
-- Este proceso realiza un corrimiento cada vez que la seal Shift (Clk_Txs ) es igual a `1'
Process( CLK, Reset, Load, Shift )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
Reg_Tx <= ( others => '1' );
Tx <= '1';
else
if Load = '1' and Tx_On = '0' then --Formacin de la trama a transmitir.
Reg_Tx( 8 downto 1 ) <= Data_In;
Reg_Tx( 0 ) <= '0';
Reg_Tx( 9 ) <= '1';
else
if Shift = '1' then Corrimiento de la trama.
Reg_Tx( 8 downto 0 ) <= Reg_Tx( 9 downto 1 );
Tx <= Reg_Tx( 0 );
end if;
end if;
end if;
end if;
end process;
Process( CLK, Reset, Load, Shift )
-- Este proceso controla el nmero de corrimientos realizados por el transmisor
Begin
if clk'event and clk = '1' then
If Reset = '1' then
Tx_On <= '0';
Tx_Empty <= '1';
Count_Tx <= "0000";
else
if Load = '1' and Tx_On = '0' then
Tx_Empty <= '0';
Tx_On <= '1';
elsif Shift = '1' then
if Tx_On = '1' then
Count_Tx <= Count_Tx + 1;
if Count_Tx = "1001" then
Count_Tx <= "0000";
Tx_On <= '0';
Tx_Empty <= '1';
else
else
Reset: in STD_LOGIC;
Clk: in STD_LOGIC;
clk_ms: in STD_LOGIC;
RxD: in STD_LOGIC;
RxDs: out STD_LOGIC
);
end Interface_Rx;
architecture Interface_Rx_arch of Interface_Rx is
Signal ifrxd : Std_Logic_Vector( 2 downto 0 );
begin
Process( CLK, Reset )
Begin
if clk'event and clk = '1' then
if Reset = '1' then
ifrxd <= "111";
else
if ( ifrxd(0) = ifrxd(2) ) and ( ifrxd(0) /= ifrxd(1) ) then
ifrxd(2) <= ifrxd(0);
else
begin
Process( CLK, Reset )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
cont_m <= "0000";
sample <= '0';
Flag_Rx <= '0';
elsif Rst_S = '1' then
cont_m <= "0000";
else
begin
Process( CLK, Reset, Load, Shift )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
Tx_On <= '0';
Tx_Empty <= '1';
Count_Tx <= "0000";
else
if Load = '1' and Tx_On = '0' then
Tx_Empty <= '0';
Tx_On <= '1';
elsif Shift = '1' then
if Tx_On = '1' then
Count_Tx <= Count_Tx + 1;
if Count_Tx = "1001" then
Count_Tx <= "0000";
Tx_On <= '0';
Tx_Empty <= '1';
else
else
begin
Process( CLK, Reset, Load, Shift )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
Reg_Tx <= ( others => '1' );
Tx <= '1';
else
if Load = '1' and Tx_On = '0' then
Reg_Tx( 8 downto 1 ) <= Data_In;
Reg_Tx( 0 ) <= '0';
Reg_Tx( 9 ) <= '1';
else
if Shift = '1' then
Reg_Tx( 8 downto 0 ) <= Reg_Tx( 9 downto 1 );
Tx <= Reg_Tx( 0 );
end if;
end if;
end if;
end if;
end process;
Process( CLK, Reset, Load, Shift )
Begin
if clk'event and clk = '1' then
If Reset = '1' then
Tx_On <= '0';
Tx_Empty <= '1';
Count_Tx <= "0000";
else
if Load = '1' and Tx_On = '0' then
else
else
Clk : in STD_LOGIC;
Samples : in STD_LOGIC;
Read_Data : in STD_LOGIC;
Data_Ready: out STD_LOGIC;
Rx_Full : Buer STD_LOGIC
);
end Component Ctrl_Rx;
Component Buer_Rx
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
RxDs : in STD_LOGIC;
Samples : in STD_LOGIC;
End_Rx : in STD_LOGIC;
Data_Rx : out STD_LOGIC_VECTOR (7 downto 0)
);
end Component Buer_Rx;
Component Interface_Rx
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
clk_ms : in STD_LOGIC;
RxD : in STD_LOGIC;
RxDs : out STD_LOGIC
);
end Component Interface_Rx;
Component div16
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
Clk_In : in STD_LOGIC;
Clk_Out : out STD_LOGIC
);
end Component div16;
Component pulso
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
Data_asyn : in STD_LOGIC;
Data_syn : out STD_LOGIC
);
end Component pulso;
Component Div_ms
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
Clk_In : in STD_LOGIC;
Divider : in STD_LOGIC_Vector( 7 downto 0 );
Ld_Div_Low : in STD_LOGIC;
Ld_Div_Hi : in STD_LOGIC;
Clk_Out : out STD_LOGIC
);
end Component Div_ms;
Component Control_RX
GENERIC(
Div_Hi : Integer := 0;
Div_Low : Integer := 2 );
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
Ld_Div_Low : out STD_LOGIC;
Ld_Div_Hi : out STD_LOGIC;
Data_Out : out STD_LOGIC_VECTOR (7 downto 0)
);
end Component Control_RX;
Component Buer_TX
port (
Reset : in STD_LOGIC;
Clk : in STD_LOGIC;
Load : in STD_LOGIC;
Shift : in STD_LOGIC;
Data_IN : in STD_LOGIC_VECTOR (7 downto 0);
Tx : out STD_LOGIC;
TX_Empty : Buer STD_LOGIC
);
end Component Buer_TX;
Signal Rx_Full, RxDs, samples, sample, clk_pres, clkls, clkl : Std_Logic;
Signal Clk_Tx, Clk_Txs : STD_LOGIC;
Signal carga_div_low, carga_div_Hi : STD_LOGIC;
Signal Data_In : STD_LOGIC_VECTOR( 7 downto 0 );
begin
Hi <= '1';
-****************************************************************************************************
-- * Generador de Frecuencia: La frecuencia de muestreo debe ser 16 veces mayor que *
-- * la velocidad de transmision. *
-***************************************************************************************************
A1 : div16
port map( Reset, CLK, Hi, clk_pres );
A2 : div_ms
port map( Reset, CLK, clk_pres,data_in, carga_div_low, carga_div_Hi, clkl );
A3 : pulso
port map( Reset, CLK, clkl, clkls );
A4 : div16
port map( Reset, CLK, clkls, Clk_Tx );
A5 : pulso
port map( Reset, CLK, Clk_Tx, Clk_Txs );
-- **************
-- * Receptor *
-- *************
-- Sincroniza la seal de entrada Rx con clkls, RxDs seal de salida sincronizada
A6 : Interface_Rx
port map( Reset, CLK, clkls, Rx, RxDs );
-- Detecta Bit de Start y genera una seal (sample) que indica cuando se debe
-- leer un bit. Sample tiene una duracion de un ciclo de reloj CLK.
A7 : Sample_Rx
port map( Reset, CLK, Rx_Full, clkls, RxDs, sample );
-- Sincroniza la senal de entrada sample, samples senal sincronizada.
A8 : pulso
port map( Reset, CLK, sample, samples );
-- Control del numero de bits, cuando se reciben 10 pulsos de la seal sample
-- Rx_Full se hace igual a '1'.
A9 : ctrl_rx
port map( Reset, CLK, samples, Read_Data, Data_Ready, Rx_Full );
-- Realiza la conversin de serie a paralelo del dato recibido.
A10: Buer_Rx
BEGIN
-- Component Instantiation
uut: Uart PORT MAP(
Reset => Reset,
Clk => Clk,
Rx => Rx,
Read_Data => Read_Data,
Data_Ready => Data_Ready,
begin
for i in 0 to ncycles*10 loop -- Genera ncyclos de periodo 10 ns
clk <= '0';
-- D5
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D6
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D7
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- BSTOP
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- SEGUNDO BIT ENVIADO
-- BIT DE START
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D0
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D1
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- LECTURA DEL PRIMER BIT RECIVIDO
Read_Data <= '1';
wait until clk'event and clk = '1';
Read_Data <= '0';
-- D2
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = = '1';
end loop;
-- D3
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D4
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- D5
Rx <= '1';
for i in 0 to tbit loop
-- D6
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = = '1';
end loop;
-- D7
Rx <= '0';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
-- BSTOP
Rx <= '1';
for i in 0 to tbit loop
wait until clk'event and clk = '1';
end loop;
wait; -- will wait forever
END PROCESS;
Transmiter : Process
Begin
for i in 0 to 10 loop
wait until clk'event and clk ='1';
end loop;
Data_Tx <= "10101010";
Internamente la CPU est dividida en: El camino de datos o Datapath el cual a su vez est
formado por:
PC: ( Program Counter ) Encargado de almacenar la direccin de memoria de la instruccin que
se est ejecutando actualmente.
IR: ( Instruction Register ) Encargado de almacenar el cdigo de la instruccin en ejecucin.
ACC: ( Acumulator ) Utilizado para realizar clculos y como almacenamiento temporal de datos
de programa.
MAR: ( Memory Address Register ) Utilizado para el direccionamiento de la memoria de
programa.
y la lgica de control que est encargada de manejar el Datapath dependiendo de la instruccin
en ejecucin.
El primer paso en el diseo de un computador es denir las operaciones que se podrn realizar,
este conjunto de operaciones recibe el nombre de Set de Instrucciones. Nuestro computador ser
capaz de realizar operaciones de Suma ( ADD ) , Resta ( SUB ), LOAD y STORE; Debido a que
tenemos 4 instrucciones sern necesarios dos bits para su codicacin ( opcode ), es importante
notar que cada instruccin debe tener un cdigo nico:
Operacin
Cdigo
ADD
SUB
LOAD
STORE
00
01
10
11
La siguiente gura muestra una arquitectura que nos servir para realizar las operaciones de la
lgica de control. La unidad de control es la encargada de sincronizar las tareas que deben
realizarse para ejecutar las instrucciones sobre el datapath.
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ALU is
Port ( A : in std_logic_vector(7 downto 0);
B : in std_logic_vector(7 downto 0);
Opera : in std_logic;
Operacion : in std_logic_vector(1 downto 0);
Resultado : out std_logic_vector(7 downto 0));
end entity ALU;
architecture RT of ALU is
begin
Process ( A, B, Opera, Operacion )
Begin
If Opera = '1' then
Case Operacion is
When "00" => -- Suma
Resultado <= A + B;
Para realizar una escritura se debe colocar la seal Write en `1' e indicar el registro destino
asignndole el valor adecuado a SelWriteReg y esperar un anco de subida en la seal del reloj.
El proceso de lectura es bastante sencillo, basta con indicar el registro a leer ( asignndole un
valor a SelReadReg ). El cdigo en VHDL del Banco de Registros se muestra a continuacin.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity RagBank is
Port ( Clk : in std_logic;
Init : in std_logic;
DataWrite : in std_logic_vector(7 downto 0);
SelWriteReg : in std_logic_vector(1 downto 0);
Write : in std_logic;
begin
Process(Clk, Init, Write)
type RegBank is array ( 0 to 3 ) of std_logic_vector( 7 downto 0 );
variable Registers: RegBank;
Begin
If Init = '1' then
for i in 0 to 3 loop
Registers( i ) := "00000000";
end loop;
elsif Write = '1' then
if Clk'event and clk = '1' then
Registers( conv_integer( SelWriteReg ) ) := DataWrite;
end if;
end if;
DataRead <= Registers( conv_integer( SelReadReg ) );
End Process;
end RT;
Ntese que se utiliz la funcin conv_integer la cual convierte a entero un valor dado en
std_logic_vector, esto se debe hacer ya que el subndice de un arreglo debe ser de tipo entero.
Registros A, B y de salida: Estos registros estn encargados de almacenar los operandos y el
resultados de las operaciones de la ALU. Su interfaz se muestra en la siguiente gura.
begin
Process( clk, load, reset )
Begin
if Reset = '1' then
OUTR <= "00000000";
else
if clk'event and clk = '1' then
if load = '1' then
OUTR <= INR;
end if;
end if;
end if;
End Process;
end RT;
begin
Process( Clk, Reset, IncCP )
Begin
if Reset = '1' then
OutCP <= "00000000";
else
if IncCP = '1' then
if clk'event and clk = '1' then
else
2.3.
EJERCICIOS
1. En un estacionamiento se cuenta con dos sensores que deben detectar el ingreso o salida de
vehculos. Cuando un vehculo se encuentra frente a uno de los sensores genera un nivel lgico
`1'. En la siguiente gura se muestra el diagrama de tiempos de las seales generadas por los
sensores al entrar y al salir un vehculo.
El sistema debe entregar dos seales UP y DOWN las cuales se colocan en un nivel lgico alto
cuando se detecta la secuencia completa de entrada y salida de un automvil respectivamente.
3. Disear el decodicador del teclado matricial que se muestra en la siguiente gura. Cuando no
se tiene ninguna tecla presionada, en las entradas R0 a R3 se tiene una lectura de 0000. Si por
ejemplo se presiona la tecla superior izquierda, se recibir un `1' lgico en R0 cuando la secuencia
de las columnas C0 a C3 sea 1000. Por lo tanto un valor lgico alto en las entradas R0 a R3
indica la la de la tecla oprimida, pero no sabemos cual de las cuatro teclas de la la est
presionada. Para averiguarlo debemos colocar un `1' lgico en solo una de las columnas y rotarlo
por todas ellas. R0 ser igual a `1' slo cuando se coloque el `1' lgico en la columna de la tecla
oprimida y `0' en los otros casos.
Una vez detectada la tecla oprimida el decodicador debe generar un cdigo nico para cada una
de ellas y debe indicar el evento haciendo key_press = `1'.
1. Disear el sistema de control de los semforos de un cruce de vehculos.
1. Disear un sistema que sea capz de generar caracteres ASCII en un monitor VGA. Una
trama de video VGA est compuesta por 480 lneas de 640 pixels. El monitor cuenta con las
siguientes seales de control:
1.
Red, Green, Blue : Entradas de seal anloga de color, estas entradas tienen un rango
de 0 a 0.7 V
Sincronismo Horizontal : Indica el principio y fn de cada lnea de video ( 480 lneas ).
Sincronismo Vertical : Indica el principio y n de cada trama de video.
El anco de bajada de la seal de sincronismo horizontal indica el inicio de la lnea y al colocar
en alto esta seal se asegura que la informacin contenida en la lnea de video (Red, Green, Blue
) se despliegue en la parte visible de la pantalla. En la siguiente gura puede verse la forma de
onda y el diagrama de tiempos de esta seal.
1. Disear el control de un display inteligente. Este display tiene como elemento de visualizacin
una matriz de leds de 7x5. Se desea visualizar los caracteres ASCII desde el 20H ` ` hasta el
7EH ` '. La siguiente gura muestra el diagrama de bloques propuesto.
Debido a que los dispositivos lgicos programables no pueden suministrar la corriente necesaria
para manejar los leds, es necesario utilizar el siguiente circuito para manejar la matriz:
000h,000h,000h,000h,000h
! 000h,000h,0FAh,000h,000h
'"'000h,0E0h,000h,0E0h,000h
'#'044h,0FEh,044h,0FEh,044h
'$'048h,054h,0FEh,054h,024h
' %'046h,026h,010h,0C8h,0C4h
'&'00Ah,044h,0AAh,092h,06Ch
'''000h,0C0h,0A0h,000h,000h
'('000h,082h,044h,038h,000h
')'000h,038h,044h,082h,000h
'*'028h,010h,07Ch,010h,028h
'+'010h,010h,07Ch,010h,010h
','000h,00Ch,00Ah,000h,000h
'-'010h,010h,010h,010h,010h
'.'000h,006h,006h,000h,000h
' '
' '
'/'040h,020h,010h,008h,004h
0 07Ch,0A2h,092h,08Ah,07Ch
'1'000h,002h,0FEh,042h,000h
'2'062h,092h,08Ah,086h,042h
'3'05Ch,0A2h,0A2h,082h,044h
'4'008h,0FEh,048h,028h,018h
'5'09Ch,0A2h,0A2h,0A2h,0E4h
'6'04Ch,092h,092h,092h,07Ch
'7'0C0h,0A0h,090h,08Eh,080h
'8'06Ch,092h,092h,092h,06Ch
'9'07Ch,092h,092h,092h,064h
':'000h,06Ch,06Ch,000h,000h
';'000h,06Ch,06Ah,000h,000h
'<'082h,044h,028h,010h,000h
'='014h,014h,014h,014h,014h
'>'010h,028h,044h,082h,000h
'?'060h,090h,08Ah,080h,040h
'@'07Ch,082h,09Eh,092h,04Ch
'A'03Eh,048h,088h,048h,03Eh
'B'06Ch,092h,092h,092h,0FEh
'C'044h,082h,082h,082h,07Ch
'D'07Ch,082h,082h,082h,0FEh
'E'082h,082h,092h,092h,0FEh
'F'080h,090h,090h,090h,0FEh
'G'05Eh,092h,092h,082h,07Ch
'H'0FEh,010h,010h,010h,0FEh
'I'000h,082h,0FEh,082h,000h
'J'080h,0FCh,082h,002h,004h
'K'082h,044h,028h,010h,0FEh
'L'002h,002h,002h,002h,0FEh
'M'0FEh,040h,030h,040h,0FEh
'N'0FEh,008h,010h,020h,0FEh
'O'07Ch,082h,082h,082h,07Ch
'P'060h,090h,090h,090h,0FEh
'Q'07Ah,084h,08Ah,082h,07Ch
'R'062h,094h,098h,090h,0FEh
'S'04Ch,092h,092h,092h,064h
'T'080h,080h,0FEh,080h,080h
'U'0FCh,002h,002h,002h,0FCh
'V'0F8h,004h,002h,004h,0F8h
'W'0FCh,002h,01Ch,002h,0FCh
'X'0C6h,028h,010h,028h,0C6h
'Y'0E0h,010h,00Eh,010h,0E0h
'Z'0C2h,0A2h,092h,08Ah,086h
'['000h,082h,082h,0FEh,000h
'\'004h,008h,010h,020h,040h
']'000h,0FEh,082h,082h,000h
''020h,040h,080h,040h,020h
'_'002h,002h,002h,002h,002h
''000h,020h,040h,080h,000h
'a'01Eh,02Ah,02Ah,02Ah,004h
'b'01Ch,022h,022h,012h,0FEh
'c'004h,022h,022h,022h,01Ch
'd'0FEh,012h,022h,022h,01Ch
'e'018h,02Ah,02Ah,02Ah,01Ch
'f'040h,080h,090h,07Eh,010h
'g'07Ch,04Ah,04Ah,04Ah,030h
'h'01Eh,020h,020h,010h,0FEh
' '
i 000h,002h,0BEh,022h,000h
j 000h,0BCh,022h,002h,004h
'k'000h,022h,014h,008h,0FEh
'l'000h,002h,0FEh,082h,000h
'm'01Eh,020h,018h,020h,03Eh
'n'01Eh,020h,020h,010h,03Eh
'o'01Ch,022h,022h,022h,01Ch
'p'020h,050h,050h,050h,07Eh
'q'07Eh,030h,050h,050h,020h
'r'010h,020h,020h,010h,03Eh
's'004h,02Ah,02Ah,02Ah,012h
't'004h,002h,012h,07Ch,010h
'u'03Eh,004h,002h,002h,03Ch
'v'038h,004h,002h,004h,038h
'w'03Ch,002h,00Ch,002h,03Ch
'x'022h,014h,008h,014h,022h
'y'03Ch,00Ah,00Ah,00Ah,030h
'z'022h,032h,02Ah,026h,022h
'{'082h,082h,06Ch,010h,000h
'|'000h,000h,0FEh,000h,000h
'}'000h,010h,06Ch,082h,082h
''080h,040h,0C0h,080h,040h
' '
' '
1. Se desea disear un display formado por 5 matrices de Leds de 7x5 que sea capz de almacenar
mensajes de 70 caracteres. El mensaje a desplegar debe ser introducido via serial o por medio
de un teclado.
1. Disear un circuito que permita detectar la tecla oprimida en un teclado:
Cada vez que se oprime una tecla en in teclado IBM el teclado enva un cdigo, este cdigo es
nico para cada tecla. Por ejemplo si se oprime la tecla `A' se enviar el cdigo 1CH. Si se
mantiene oprimida esta tecla el cdigo se enva contnuamenta hasta que se suelte o se oprima
otra tecla. Cuando se suelta una tecla el teclado enva el cdigo F0H para indicar que se liber
una tecla y a continuacin enva el cdigo de la tecla liberada en nuestro ejemplo cuando se
libera la tecla `A' el teclado enva los cdigos F0H 1CH.
El teclado siempre enva el mismo cdigo para cada letra, por lo tanto se debe tener en cuenta
que cada vez que se oprima la tecla `SHIFT' la siguiente letra debe cambiarse de maysculas a
minsculas o viceversa. Tambin se debe tener en cuenta el estado de la tecla `CAPS'.
Host Commands
Set Scan Code Set. Upon Sending F0, keyboard will reply with
ACK (FA) and wait for another byte, 01-03 which determines
F0
the Scan Code Used. Sending 00 as the second byte will return
the Scan Code Set currently in Use
F4
F5
FE
Commands
FA Acknowledge
AA Power On Self Test Passed (BAT Completed)
Resend - Upon receipt of the resend command the Host should re-transmit
the last byte sent.
Sca
El teclado riene una interfaz PS2 la cual cuenta con la disposicin de pines y el diagrama de
tiempos indicados en la siguiente gura:
La gura anterior muestra la comunicacin entre el teclado y el Host. Como puede verse se trata
de una comuniacacin serial sincrnica en la cual el teclado genera las seales Data y Clock. Solo
durante el anco de bajado se debe leer el estado de la seal de datos.
La comunicacin entre el Host y el teclado se muestra en la siguiente gura. Como puede verse el
Host debe iniciar la transmisin generando un anco de bajada en la seal clock y un tiempo
despus generar el Bit de Start, despus de esto el teclado genera la seal de reloj y el Host debe
enviar serialmente el comando deseado, si el teclado recibe correctamente la trama responde con
ACK.
El conector PS2 tiene 6 pines los cuales tiene las siguientes funciones:
Se desea que el driver de teclado tenga una salida ASCII, para poder ser utilizado con el Display
inteligente del ejercicio 6. La siguiente tabla da una relacin entre el cdigo de la tecla y el cdigo
ASCII de la letra o carcter correspondiente.
NC
F9
NC
F5
F3
F1
F2
F12
NC
F10
F8
F6
F4
Tab
00 FF 01 FF 02 FF 03 FF 04 FF 05 FF 06 FF 07 FF 08 FF 09 FF 0A FF 0B FF 0C FF OD 09 0E 7C
NC
Alt
SHL
NC
CTL
NC
NC
NC
10 FF 11 FF 12 FF 13 FF 14 FF 15 71 16 31 17 FF 18 FF 19 FF 1A 7A 1B 73 1C 61 1D 77 1E 32
NC
20
21
31
NC
40
41
NC
50
60
b
32
61
0
71
33
NC
62
63
64
5
73
55
65
6
74
NC
BKS
66
8
75
56
NC
NC
37
46
NC
NC
27
36
45
54
NC
26
35
44
NC
2
72
53
4
25
34
43
52
<
24
NC
d
23
42
51
NC
70
22
NC
30
NC
47
NC
57
NC
67
28
NC
38
77
29
48
2A
NC
39
NC
49
58
m
3A
68
78
5A
NC
69
+
79
NC
6A
7A
4B
4C
+
5B
NC
5C
4
6B
7
6C
7B
u
3C
t
2C
3B
4A
59
f
2B
NC
*
7C
;SHIFT + KEY
;00 NC 01 F9 02 NC 03 F5 04 F3 05 F1 06 F2 07 F12 08 NC 09 F10 0A F8 0B F6 0C
F4 0D TAB OE 0F NC
db 0FFH, 04300H, 0FFH, 03F00H, 03D00H, 03B00H, 03C00H, 08600H, 0FFH, 04400H,
04200H, 04000H, 03E00H, 009H, 0A7H, 0FFH
;10 NC 11 ALT 12 SHL 13 NC 14 CTL 15 Q 16 ! 17 NC 18 NC 19 NC 1A Z 1B S 1C
A 1D W 1E @ 1F NC
db 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 051H, 021H, 0FFH, 0FFH, 0FFH, 05AH, 053H,
041H, 057H, 040H, 0FFH
;20 NC 21 C 22 X 23 D 24 E 25 $ 26 # 27 NC 28 NC 29 SPC 2A V 2B F 2C T 2D R
2E % 2F NC
db 0FFH, 043H, 058H, 044H, 045H, 024H, 023H, 0FFH, 0FFH, 0FFH, 056H, 046H,
054H, 052H, 025H, 0FFH
;30 NC 31 N 32 B 33 H 34 G 35 Y 36 & 37 NC 38 NC 39 NC 3A M 3B J 3C U 3D /
3E ( 3F NC
db 0FFH, 0FFH, 042H, 048H, 047H, 059H, 026H, 0FFH, 0FFH, 0FFH, 04DH, 04AH,
055H, 02FH, 028H, 0FFH
r
2D
7
3D
5
2E
8
3E
p
4D
}
5D
NC
6D
9
7D
`
4E
NC
5E
NC
6E
BD
7E
;40 NC 41 ; 42 K 43 I 44 O 45 = 46 ) 47 NC 48 NC 49 : 4A _ 4B L 4C 4D P 4E ?
4F NC
db 0FFH, 03BH, 04BH, 049H, 04FH, 03DH, 029H, 0FFH, 0FFH, 03AH, 05FH, 04CH,
0A5H, 050H, 03FH, 0FFH
;50 NC 51 NC 52 [ 53 NC 54 55 56 NC 57 NC 58 CAP 59 SHR 5A ENT 5B * 5C
NC 5D ] 5E NC 5F NC
db 0FFH, 0FFH, 05BH, 0FFH, 0B0H, 0ADH, 0FFH, 0FFH, 0FFH, 0FFH, 013H,
02AH, 0FFH, 05DH, 0FFH, 0FFH
;60 NC 61 > 62 NC 63 NC 64 NC 65 NC 66 BKS 67 NC 68 NC 69 END 6A NC 6B <6C HM 6D NC 6E NC 6F NC
db 0FFH, 03EH, 0FFH, 0FFH, 0FFH, 0FFH, 08H, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH,
0FFH, 0FFH, 0FFH, 0FFH
;70 0 71 DEL 72 AD 73 5 74 -> 75 AUP 76 ESC 77 NUM 78 F11 79 + 7A PDN 7B 7C * 7D PUP 7E B D 7F NC
db 030H, 0FFH, 0FFH, 035H, 0FFH, 0FFH, 0FFH, 0FFH, 0FFH, 02BH, 0FFH, 02DH,
02AH, 0FFH, 0FFH, 0FFH
;83 F7
;E011 ALT GR E014 CTRR E069 END E06B LEFT E06C HOME E070 INS E071 DEL
;E072 DOWN E074 RIGHT E075 UP E07A P DN E07D P UP E05A INTRO
;E11477E1F014F077 PAUSE
;E012E07C PRINT SCREEN