Ejercicio: Diseñar con VHDL e implementar en la tarjeta Digilent con FPGA Spartan 3E un contador binario de 5 bits tanto ascendente como en forma descendente, que trabaje a 1 Hz de frecuencia. El contador dispone además de entrada de habilitación con la cual se puede bloquear.
Solución: Creamos el proyecto contador0al31 tal como se ha indicado en entradas anteriores de este blog, definiendo como VHDL el modo jerárquico de trabajo.
Como no vamos a trabajar nada en Esquemático lo aconsejable es elaborar un gráfico que resuma el diseño, para elaborar los diferentes módulos VHDL requeridos.
Observamos que hay un bloque principal CONTADOR5BITS de entradas: CLK50Mhz, Habilitador y Dirección y salidas: Q4,Q3,Q2,Q1,Q0. Hay dos bloques sen su interior: el Divisor_Frecuencia de entradas: CLKentrada y Reset, y salida: CLK1Hz. El otro bloque es el contador0al31 cuyas entradas son: Reloj y ModoConteo y salidas: Salida4,...,Salida0.
Vamos a elaborar un programa VHDL para cada bloque en el siguiente órden:
- contador0al31
- Divisor_Frecuencia
- CONTADOR5bits (que enlace los dos anteriores de acuerdo al gráfico)
Al crear Módulo VHDL como nueva fuente para contador0al31 defina las entradas y salidas tal como se indica a continuación:
Observe que la Salida se configura como vector (Bus de 5 bits) .
El ISE 10.1 nos lleva a la ventana para escribir el programa en VHDL del contador el cual lo editamos así:
Para escribir lo concerniente a la arquitectura ...después de begin nos ayudamos de las plantillas de VHDL.
Para ello vaya a Edit --> Language Templates ... --> VHDL --> Synthesis Constructs --> Coding Examples --> Counters --> Binary --> Up/Down Counters --> Simple Counter
La plantilla nos muestra:
process (<clock>)
begin
if <clock>='1' and <clock>'event then
if <ModoConteo = '1' then
<count> <= <count> + 1;
else
<count> <= <count> - 1;
end if;
end if;
end process;
Editamos de acuerdo al nombre dado nuestras entradas, así:
process (Reloj)
begin
if Reloj = '1' and Reloj'event then
if ModoConteo = '1' then
cuenta <= cuenta + 1;
else
cuenta <= cuenta - 1;
end if;
end if;
end process;
Copiamos y pegamos al comienzo (begin) de la arquitectura ... en el archivo en VHDL, y cerramos la plantilla. Salvamos el archivo VHDL, y chequeamos la sintaxis para saber si está bien en este aspecto.
Vemos que se presenta error de sintaxis...
Se indica en el reporte que se presenta un error porque no se ha definido la variable "cuenta"
Procedemos entonces a declarar esa variable "cuenta" como una señal auxiliar interna SIGNAL antes de comenzar el proceso del reloj y así mismo después de finalizar el mismo proceso hay que señalar que lo que está en "cuenta" hay que enviarlo a la "Salida" del contador.
Después de haber efectuado las correcciones el programa queda así:
Al chequear sintaxis vemos que ahora no se presenta error.Luego continuamos con la simulación del circuito.
Creamos el archivo de chequeo de formas de onda, que llamamos contador0al31_tb.
Configure la ventana de tiempos de inicialización como se indica:
Cuando la entrada ModoConteo = 1, el contador lo hace ascendentemente, y si vale 0 cuenta en forma descendente. Dibujamos dicha entrada arbitrariamente, para observar en la simulación el comportamiento del contador:
Salvamos el archivo del banco de pruebas y cerramos la ventana de las formas de onda, y procedemos a efectuar su simulación:
Podemos verificar con las formas de onda que el contador responde a lo solicitado.
Procedemos ahora con el divisor de frecuencia el cual no simulamos.
De este blog en la entrada (Intermitencia en encendido y apagado de un Led) copiamos el respectivo programa VHDL , lo copiamos, editamos para que se acople a las entradas y salidas que le asignamos en nuestro gráfico donde presentamos los bloques, salvamos y chequeamos sintaxis:
Vamos ahora a enlazar los dos bloques o programas, de acuerdo al gráfico inicial, al cual le adicionamos una señal interna X necesaria para el diseño:
Creamos el programa final VHDL CONTADOR5bits para enlazar los dos anteriores:
Fijamos entradas y salidas, como se indica en color amarillo en el gráfico.
El programa final es el siguiente:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity CONTADOR5bits is
Port ( CLK50Mhz : in STD_LOGIC;
Habilitador : in STD_LOGIC;
Direccion : in STD_LOGIC;
Q : out STD_LOGIC_VECTOR (4 downto 0));
end CONTADOR5bits;
architecture Comportamiento of CONTADOR5bits is
component Divisor_Frecuencia is
Port (
CLKentrada: in STD_LOGIC;
Reset : in STD_LOGIC;
CLK1Hz : out STD_LOGIC
);
end component;
component contador0al31 is
Port ( Reloj : in STD_LOGIC;
ModoConteo : in STD_LOGIC;
Salida : out STD_LOGIC_VECTOR (4 downto 0));
end component;
signal X : STD_LOGIC;
begin
C1: Divisor_Frecuencia port map
( CLKentrada => CLK50Mhz, Reset => Habilitador, CLk1Hz => X);
C2: contador0al31 port map
( Reloj => X, ModoConteo => Direccion , Salida => Q);
end Comportamiento;
Chequeamos sintaxis para estar seguros que no se presenta error alguno, y puede ser compilado.
Sigue ahora la asignación de pines a la FPGA para el archivo CONTADOR5bits.vhd final:
Damos doble click en Floor Area /IO/ Logic-Post-Synthesis para entrar al editor PACE donde se asignan los pines a las entradas y salidas:
Damos doble click en Floor Area /IO/ Logic-Post-Synthesis para entrar al editor PACE donde se asignan los pines a las entradas y salidas:
Observe que se ha fijado el iterruptor L13 para la dirección y el pulsador K17 para habilitar el contador.
Salvamos el archivo de asiganación de pines y cerramos el editor PACE.
Damos doble click en Implement Design ( que presenta un interrogante color naranja a su derecha):
Salvamos el archivo de asiganación de pines y cerramos el editor PACE.
Damos doble click en Implement Design ( que presenta un interrogante color naranja a su derecha):
Corroboramos observando en el resumen del diseño (View Design Summary), el reporte de pines (Pinout Report), dando click en la columna (Signal Name) que los pines están localizados correctamente:
Alimentamos la tarjeta Digilent Spartan 3E y conectamos el cable USB para efectuar la programación de la FPGA dando doble click en Configure Target Device.
Al programar la FPGA vimos que el comportamiento del contador presentaba problemas al manejar el pulsador K17. Se decidió cambiarlo por el interruptor N17; para ello editamos el archivo de asignación de pines CONTADOR5bits.ucf y efectuamos el cambio en la entrada Habilitador de K17 por N17 (interruptor al extremo izquierdo de la tarjeta)
Como variamos la asignación de pines, después de salvar el archivo .ucf, se requiere volver a implementar el diseño. Damos doble click en Implement Design (que aparece nuevamente con interrogante color naranja).
Verificamos en el Pinout Report del resúmen del diseño, dando click en la columna de nombre de señal, que se haya verificado el cambio respectivo:
Configuramos el dispositivo en la tarjeta para que se genere el archivo de programación nuevamente, ya con el cambio efectuado.Luego volver a efectuar la programación de la FPGA, alimentando la tarjeta y conectando el cable USB.
En el video podemos observar su correcto funcionamiento:
Alimentamos la tarjeta Digilent Spartan 3E y conectamos el cable USB para efectuar la programación de la FPGA dando doble click en Configure Target Device.
Al programar la FPGA vimos que el comportamiento del contador presentaba problemas al manejar el pulsador K17. Se decidió cambiarlo por el interruptor N17; para ello editamos el archivo de asignación de pines CONTADOR5bits.ucf y efectuamos el cambio en la entrada Habilitador de K17 por N17 (interruptor al extremo izquierdo de la tarjeta)
Como variamos la asignación de pines, después de salvar el archivo .ucf, se requiere volver a implementar el diseño. Damos doble click en Implement Design (que aparece nuevamente con interrogante color naranja).
Verificamos en el Pinout Report del resúmen del diseño, dando click en la columna de nombre de señal, que se haya verificado el cambio respectivo:
Configuramos el dispositivo en la tarjeta para que se genere el archivo de programación nuevamente, ya con el cambio efectuado.Luego volver a efectuar la programación de la FPGA, alimentando la tarjeta y conectando el cable USB.
En el video podemos observar su correcto funcionamiento: