Está en la página 1de 42

DISEÑO CON VHDL

LABORATORIO DE TECNOLOGÍA ELECTRONICA I. ITT

DPTO. ELECTRÓNICA- UNIVERSIDAD DE ALCALÁ.


Diseño con VHDL
.

ÍNDICE
0. INTRODUCCIÓN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

1. DESCRIPCIÓN DEL DISEÑO A REALIZAR. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2. ARCHIVOS FUENTE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.1. MÓDULO BCD2SEG. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2. MODULO PRESCALER. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.3. MÓDULO CONTROL VISUALIZACIÓN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Módulo antirrebotes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Módulo Máquina de estados. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4. MÓDULO CRONO.VHD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Contador de décadas. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Registros de visualización. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.5. BANCO DE PRUEBAS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3. CREACIÓN DE LOS ARCHIVOS FUENTE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

4. ENTORNO DE SIMULACIÓN ModelSim. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16


4.1 ARRANQUE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Librerías. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2. CREACIÓN DE UN PROYECTO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3. COMPILACIÓN DEL CÓDIGO FUENTE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Compilación desde el entorno gráfico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.4. CARGA DE LA UNIDAD DE DISEÑO A SIMULAR. . . . . . . . . . . . . . . . . . . . . 24
4.5. SELECCIÓN DE PUNTOS DE PRUEBA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Simulación desde el entorno gráfico. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.6. INTRODUCCIÓN DE ESTÍMULOS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.7. AVANCE Y DETENCIÓN DE LA SIMULACIÓN. . . . . . . . . . . . . . . . . . . . . . . . 34

5. ANÁLISIS DE RESULTADOS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
5.1.PUNTOS DE RUPTURA. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

6. FINALIZAR LA SESIÓN DE SIMULACIÓN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

7. METODOLOGÍA DE TRABAJO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

-i-
Diseño con VHDL
.

0. INTRODUCCIÓN.
El objetivo perseguido con la elaboración de este tutorial es familiarizar al alumno con el diseño
de sistemas digitales en VHDL. El proceso de diseño se divide en tres fases: creación,
compilación y simulación.

Para la creación de los archivos fuente se puede utilizar cualquier editor de textos, aunque se
recomienda emacs debido a que tiene precargadas plantillas con la sintaxis de VHDL, lo que
facilita de forma notable la creación de dichos archivos.

Para la compilación y simulación se va a utilizar Modelsim de Mentor Graphics. Esta


herramienta es suficientemente potente como para pretender conocerla en su totalidad con este
tutorial. Si bien, se proporcionarán los conocimientos básicos para poder manejarla. El usuario
para profundizar en su manejo puede acceder en todo momento a los manuales completos
de la herramienta proporcionados por el fabricante, tanto en formato HTML como en PDF.

1. DESCRIPCIÓN DEL DISEÑO A REALIZAR.


Para ilustrar el proceso de diseño de un sistema digital en VHDL se empleará como ejemplo
de diseño la realización de un cronometro digital con precisión de segundos y valor máximo de
cuenta de un minuto. Con este diseño se pretende ilustrar las situaciones más frecuentes que
aparecen en los diseños con VHDL. La figura 1 muestra el diseño a realizar. En el archivo
enunciado.pdf se indican las condiciones de funcionamiento impuestas.

OSCILADOR
Vcc
Vcc
R R CLK DisplayUnidades
CAPTURA
MARCHA
RST
UPDOWN
DisplayDecenas

Figura 1. Diseño a realizar.

La señal de reloj del sistema proviene de un oscilador externo, que proporciona una señal
(CLK) de frecuencia 10 MHz y ciclo de trabajo del 50%. El número de segundos (unidades y
decenas de 00 59) transcurridos se visualizará sobre sendos displays de 7 segmentos de
cátodo común. El sistema dispone de un pulsador RST para inicializar (puesta a cero) la cuenta
del tiempo. Además, se dispone de otro pulsador (CAPTURA) para implementar la función de
congelación de la visualización. Al pulsar este pulsador se congela el tiempo actual de forma
que sobre los displays se muestra dicho instante de tiempo mientras que el cronómetro sigue
contando internamente. Al volver a pulsar este pulsador se refresca la visualización, mostrando
el tiempo transcurrido actualmente. Hay que hacer notar que los pulsadores son elementos
mecánicos con lo que cada vez que se actúa sobre ellos se producen rebotes (figura 2) siendo
sus amplitudes y duraciones aleatorias, si bien se sabe que su duración nunca excede de los
5 ms .

-1-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

< 5 ms < 5 ms

Figura 2. Rebotes producidos en los pulsadores.

Para implementar el sistema se ha realizado un diseño jerárquico como el mostrado en la figura


3. Realizandose una realización estructural del diseño. El componente BCD2SEG realiza la
función de un decodificador BCD a 7 segmentos para displays de cátodo común, cuyo
funcionamiento viene especificado en el fichero bcd2seg.vhd. Este decodificador se instanciará
como sendos componentes en la entidad de mayor jerarquía declarada en el fichero crono.vhd.
En esta entidad se instancia también el componente PRESCALER que proporciona una señal
de 1 Hz empleada para contar los segundos, obtenida a partir de la señal de 10 MHz. La señal
de 1 Hz se obtiene de dividir la frecuencia de la señal de reloj CLK por un factor de 107. Este
componente se modela en el archivo prescaler.vhd. Así mismo, también se proporciona una
señal de 5 ms a utilizar por el componente ANTIRREBOTES. El proceso CONTADOR es el
encargado de medir el tiempo transcurrido. Para lo que se modela un contador BCD de dos
décadas o dígitos (unidades y decenas).

CONTADOR
PRESCALER REGISTROS BCD2SEG
0-59

prescaler.vhd DIVISOR
7 4 EN1HZ
10 y 5.10 EN

BCD2SEG

CLK
EN

bcd2seg.vhd
RST
ANTIRREBOTES MÁQUINA DE ESTADOS
SET CE
CAPTURA P P
EN200Hz cnt_cap.vhd
ant_reb.vhd maq_fsm.vhd
CONTROL DE LA VISUALIZACIÓN

crono.vhd

Figura 3. Diagrama de bloque del sistema a diseñar.

En la jerarquía de mayor nivel, también, se instanciará el componente CONTROL DE LA


VISUALIZACIÓN, el cual, a su vez, corresponde con un diseño jerárquico formado por los
componentes ANTIRREBOTES y MAQUINA DE ESTADOS, encargado de controlar la
habilitación de los registros que permiten la congelación de la visualización y se ubican entre
el contador 0-59 y los decodificadores BCD a 7 segmentos. Cuando la señal de habilitación de
estos registros está activa sus salidas reflejan el valor actual de cuenta. Si por el contrario la
señal de habilitación está desactivada no se actualiza la salida del contador sobre los displays,
implementando de esta forma la función de congelación.

La señal de habilitación de estos registros se controla mediante una máquina de estados que
recibe como entrada la señal procedente del pulsador de CAPTURA, una vez eliminados los
posibles rebotes, y cuyo grafo se muestra en la figura 4. La variable P indica el estado del
pulsador: 1 sin pulsar, 0 pulsado.

-2-
Diseño con VHDL
.

P=1

P=0 S1
1 P=1

S4
P=0 S2 P=0
1
0

P=1 S3 P=0
0

P=1

Figura 4. Grafo de la máquina de estados.

Inicialmente la máquina parte del estado S1 (la salida está a 1), de forma que la cuenta no está
congelada. Si en este estado se pulsa el pulsador (P=0) se pasa al estado S2, inhabilitandose
el refresco de los registros (CE= 0). Se permanece en este estado mientras el pulsador se
encuentre activado. Al liberarse (P=1) se pasa al estado S3 (CE= 0), donde se espera hasta
que se vuelva a activar el pulsador (P=0) momento en el cual se pasa al estado S4 (CE= 1),
habilitando de nuevo el refresco de los registros. El sistema permanece en S4 mientras el
pulsador permanece activado, pasando a S1 al liberarse.

Para saber si la señal procedente del pulsador está libre de rebotes es suficiente con
examinarla en varios instantes de tiempo, de forma que si en todos ellos el valor es ‘0' o ‘1' se
puede considerar que la señal no tiene rebotes. El intervalo de tiempo muestreado deberá ser
superior a 5 ms. Para realizar este filtrado de los rebotes se puede utilizar el circuito de la figura
5. En este caso, como se utiliza una señal(EN200Hz) de periodo 5 ms para habilitar los
biestables tipo D, el intervalo muestreado es de 20 ms.

S
Q P
R

CE

C
SET

CA PTURA D Q D Q D Q D Q

CL K C C C C

EN200HZ
SET

CE CE CE CE
SET

SET

SET

SET

Figura 5. Diagrama de bloques del circuito antirebotes.

Así, la descripción VHDL de este diseño está compuesta por los siguientes ficheros, listados
de menor a mayor jerarquía (orden que se deberá mantener en la compilación). Indicar que el
último de ellos (crono_tb.vhd) es un testbench utilizado para simular el diseño.

! bcd2seg.vhd.
! prescaler.vhd.
! ant_reb.vhd.
! maq_fsm.vhd.
! cnt_cap.vhd.
! crono.vhd
! crono_tb.vhd

-3-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Una vez descrito el comportamiento del diseño se pasará describir los archivos VHDL creados
para modelarlo. En el archivo codigo.zip se encuentran todos los ficheros VHDL necesarios
para realizar la aplicación antes descrita. Estos archivos se almacenarán en el directorio raíz
del diseño.

En el archivo script.zip se encuentran archivos scripts a utilizar con la herramienta de


compilación y simulación que permitirán simplificar la fase de diseño. A lo largo de este manual
se irán explicando la funcionalidad de cada uno de ellos.

2. ARCHIVOS FUENTE.
A continuación se muestra el código VHDL de cada uno de los archivos que forman el diseño.

2.1. MÓDULO BCD2SEG.

El modelo del decodificador BCD a 7 segmentos se almacena en el fichero bcd2seg.vhd. La


decodificación se realiza mediante una asignación concurrente de señal seleccionada tal y
como se muestra en el siguiente listado. La salida de este módulo es un bus de 7 líneas donde
la de menor peso corresponde al segmento “a” y la de mayor peso al segmento “g”.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity BCD2SEG is
port (
BCD : in std_logic_vector(3 downto 0);
Display : out std_logic_vector(6 downto 0)); --gfedcba
end BCD2SEG;

architecture rtl of BCD2SEG is

begin
with BCD select
Display <= "0111111" when "0000", --0
"0000110" when "0001", --1
"1011011" when "0010", --2
"1001111" when "0011", --3
"1100110" when "0100", --4
"1101101" when "0101", --5
"1111101" when "0110", --6
"0000111" when "0111", --7
"1111111" when "1000", --8
"1100111" when "1001", --9
"0000000" when others; -- apaga todos los segmentos
end rtl;

-4-
Diseño con VHDL
.

2.2. MODULO PRESCALER.

Para realizar la división de la frecuencia de la señal de entrada se emplean contadores. En este


caso para optimizar los recursos en el caso de que el diseño se implementara en una FPGA,
los factores de división son 107 y 5.104, se han implementado tres contadores: el primero divide
por 10000, el segundo por 5 y el tercero por 1000. Los contadores segundo y tercero al hacer
uso de la señal FC como habilitación proporcionan un factor de división de 5.104 y 107
respectivamente. Como las señales de fin de cuenta se van a utilizar para habilitar otros
sistemas secuenciales, que utilizan la señal de 10 MHz como señal de reloj, deben estar a nivel
alto un único periodo de esta última.

library ieee;
use ieee.std_logic_1164.all;
entity prescaler is
port (
CLK : in std_logic;
RST : in std_logic;
EN1HZ : out std_logic;
EN200HZ : out std_logic);
end prescaler;
architecture rtl of prescaler is
signal cnt5 : integer range 0 to 5;
signal cnt1000 : integer range 0 to 1000;
signal cnt10000 : integer range 0 to 10000;
signal fc : std_logic;
begin
process (clk, rst)
begin
if rst = '0' then
cnt10000 <= 0;
elsif clk'event and clk = '1' then
if cnt10000 = 9999 then
cnt10000 <= 0;
else
cnt10000 <= cnt10000+1;
end if;
end if;
end process;
fc<= '1' when cnt10000 = 9999 else '0';
process (clk, rst)
begin
if rst = '0' then
cnt5 <= 0;
elsif clk'event and clk = '1' then
if fc = '1' then
if cnt5 = 4 then
cnt5 <= 0;
else
cnt5 <= cnt5+1;
end if;
end if;
end if;
end process;
process (clk, rst)
begin
if rst = '0' then
cnt1000 <= 0;
elsif clk'event and clk = '1' then
if fc = '1' then
if cnt1000 = 999 then
cnt1000 <= 0;
else
cnt1000 <= cnt1000+1;
end if;
end if;
end if;
end process;
EN200HZ <= '1' when fc = '1' and cnt5 = 4 else '0';
EN1HZ <= '1' when fc = '1' and cnt1000 = 999 else '0';
end rtl;

-5-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

2.3. MÓDULO CONTROL VISUALIZACIÓN.

Este modulo es el encargado de activar la señal de habilitación de los registros que congelan
la visualización del tiempo. Para su creación se ha realizado un diseño jerárquico que utiliza
los bloques ANTIRREBOTES y MAQUINA DE ESTADOS, los cuales se modelan en las
entidades ant_reb y maq_fsm, repectivamente.

Módulo antirrebotes.

Es el encargado de eliminar los rebotes que se producen al pulsar y liberar el pulsador. La


función implementada es la reflejada en el esquema de la figura 5.

library ieee;
use ieee.std_logic_1164.all;
entity ant_reb is
port (
captura, clk, en200hz, set : in std_logic;
p : out std_logic);
end ant_reb;
architecture rtl of ant_reb is
signal a, b, c, d, s_and, s_nor : std_logic;
begin
s_and <= captura and a and b and c and d;
s_nor <= not(captura or a or b or c or d);
process (clk, set)
begin
if set = '0' then
a <= '1';
b <= '1';
c <= '1';
d <= '1';
p <= '1';
elsif clk'event and clk = '1' then
if en200hz = '1' then
a <= captura;
b <= a;
c <= b;
d <= c;
if s_and = '1' then
p <= '1';
elsif s_nor = '1' then
p <= '0';
end if;
end if;
end if;
end process;
end rtl;

Módulo Máquina de estados.

Atendiendo al grafo de la figura 4, la maquina a modelar es del tipo Moore, cuyo diagrama de
bloques se muestra en la figura 6. En este caso se ha optado por modelar la máquina utilizando
dos procesos: uno, secuencial, para controlar las transiciones entre estados y otro,
combinacional, para generar la salida de la máquina.
Rst

Próximo
estado Estado
P Elementos
actual
Cálculo del de memoria Cálculo de
próximo estado las salidas. CE

Lógica Clk Lógica Lógica


combinacional secuencial combinacional

Proceso secuencial Proceso combinacional

Figura 6. Diagrama de bloques de la máquina de estados.

-6-
Diseño con VHDL
.

Para representar el estado de la máquina se ha definido el tipo enumerado stateFSM que


puede tomar los valores correspondientes a dichos estados. El valor del estado actual de la
FSM se almacena en la señal state. La salida de la FSM es la señal ce que toma el valor cero
cuando la cuenta está congelada. El código completo que modela la maquina de estados es
el mostrado a continuación.

library ieee;
use ieee.std_logic_1164.all;
entity maq_fsm is
port (
p : in std_logic;
rst : in std_logic;
clk : in std_logic;
ce : out std_logic);
end maq_fsm;
architecture rtl of maq_fsm is
-- Estados de la FSM que controla el sistema.
type stateFSM is (
S1, -- RunningWaitingOnPush
S2, -- RunningWaitingOnRelease
S3, -- FrozenWaitingOnPush
S4); -- FrozenWaitingOnRelease
signal state : stateFSM;
begin
process(clk, rst)
begin
if(rst = '0') then
state <= S1;
elsif (clk'event and clk = '1') then
case state is
when S1 =>
if (p = '1') then
state <= S1;
else
state <= S2;
end if;
when S2 =>
if (p = '0') then
state <= S2;
else
state <= S3;
end if;
when S3 =>
if (p = '1') then
state <= S3;
else
state <= S4;
end if;
when S4 =>
if (p = '0') then
state <= S4;
else
state <= S1;
end if;
end case;
end if;
end process;
process(state)
begin
case state is
when S2 | S3 =>
ce <= '0';
when S1 | S4 =>
ce <= '1';
end case;
end process;
end rtl ;

El modulo que controla el estado de la visualización está compuesto por la instanciación de los
dos últimos componentes: ant_reb y maq_fsm, siendo su código el mostrado a continuación

-7-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

library ieee;
use ieee.std_logic_1164.all;
entity cnt_cap is
port (
captura : in std_logic;
clk : in std_logic;
en200hz : in std_logic;
rst : in std_logic;
ce : out std_logic);
end cnt_cap;
architecture rtl of cnt_cap is
component ant_reb
port (
captura : in std_logic;
clk : in std_logic;
en200hz : in std_logic;
set : in std_logic;
p : out std_logic);
end component;
component maq_fsm
port (
p : in std_logic;
rst : in std_logic;
clk : in std_logic;
ce : out std_logic);
end component;
signal p_i : std_logic;
begin
u1 : ant_reb
port map (
captura => captura,
clk => clk,
en200hz => en200hz,
set => rst,
p => p_i);
u2 : maq_fsm
port map (
p => p_i,
rst => rst,
clk => clk,
ce => ce);
end rtl;

2.4. MÓDULO CRONO.VHD.

Este es el fichero principal o raíz del diseño sobre el que se instancian los componentes
bcd2seg, prescaler y cnt_cap. El resto de los módulos que aparecen en el diagrama de
bloques de la figura 1.4 (contador y registros) aparecerán como procesos dentro de la
arquitectura del cronometro, a continuación se detalla el funcionamiento de estos dos
elementos.

Contador de décadas.

Este contador se implementa mediante el proceso cuyo listados se muestra a continuación.


Dicho proceso es sensible a las señales de reset asíncrona (rst) y reloj (clk). El carácter
asíncrono de la señal de reset se fija mediante la posición de la sentencia if dentro de la
estructura de if anidados que evalúa su estado. El valor de cuenta se almacena sobre las
señales CntUnidades y CntDecenas. Estas señales están declaradas de tipo unsigned. Este
es un tipo derivado de std_logic_vector que permite realizar operaciones aritméticas. El valor
de cuenta sólo se modifica si la señal EN1HZ está a 1. Esta señal se obtiene del módulo
prescaler.

-8-
Diseño con VHDL
.

process(clk, rst)
begin
if(rst = '0') then
CntUnidades <= (others => '0');
CntDecenas <= (others => '0');
elsif(clk = '1' and clk'event) then
if(EN1HZ = '1') then
if (CntUnidades = 9) then
CntUnidades <= (others => '0');
if (CntDecenas = 5) then
CntDecenas <= (others => '0');
else
CntDecenas <= CntDecenas + 1;
end if;
else
CntUnidades <= CntUnidades + 1;
end if;
end if;
end if;
end process;

Registros de visualización.

Los registros empleados para implementar la función de congelación de la visualización se


describen mediante el siguiente proceso.

process(clk, rst)
begin
if(rst = '0') then
Unidades <= (others => '0');
Decenas <= (others => '0');
elsif (clk'event and clk = '1') then
if (CE = '1') then
Unidades <= std_logic_vector(CntUnidades);
Decenas <= std_logic_vector(CntDecenas);
end if;
end if;
end process;

Si la señal CE correspondiente a la salida de la FSM está a uno (visualización no congelada)


las señales Unidades y Decenas reflejan el valor de cuenta en cada flanco activo de la señal
de reloj. Las cuales se conectan a las entradas de los decodificadores BCD a 7 segmentos.
Hay que destacar que estas señales son de tipo std_logic_vector mientras que las señales de
cuenta CntUnidades y CntDecenas son de tipo unsigned. Por este motivo es preciso emplear
una conversión “cast” en la asignación.

2.5. BANCO DE PRUEBAS.

A continuación se proporciona el listado del fichero VHDL correspondiente al banco de pruebas


empleado para validar el diseño. Se trata de una entidad sin puertos. En la parte declarativa
de la arquitectura se declara el componente a verificar (crono) y un conjunto de señales
correspondientes a cada uno de los puertos de dicho componente. Éstas son fácilmente
reconocibles porque tienen el sufijo _i.

-9-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

library IEEE;
use ieee.std_logic_1164.all;
entity crono_tb is
end crono_tb;
architecture simula of crono_tb is
constant REBTIME : time := 50 us; -- Tiempo de duración de un rebote.
constant PUSHTIME : time := 100 ms; -- Tiempo de duración de una tecla.
constant RSTTIME : time := 10 ms; -- Tiempo de activación del reset.
constant Tclk : time := 100 ns; -- Periodo de la señal de reloj.
-- Declaración del componente crono.
component crono
port (
captura : in std_logic;
rst : in std_logic;
clk : in std_logic;
DisplayUnidades : out std_logic_vector(6 downto 0);
DisplayDecenas : out std_logic_vector(6 downto 0));
end component;
-- Señales auxiliares para de excitación para el banco de pruebas.
signal captura_i : std_logic := '1';
signal rst_i : std_logic := '0';
signal clk_i : std_logic := '0';
signal DisplayUnidades_i : std_logic_vector(6 downto 0);
signal DisplayDecenas_i : std_logic_vector(6 downto 0);
begin
-- Instantación del componente crono.
dut : crono
port map (
captura => captura_i,
rst => rst_i,
clk => clk_i,
DisplayUnidades => DisplayUnidades_i,
DisplayDecenas => DisplayDecenas_i);
-- Generación de la señal de reset.
rst_i <= '1' after RSTTIME;
-- Generación de la señal de reloj.
clk_i <= not clk_i after Tclk/2;
-- Proceso principal control de la excitacion.
process
--------------------------------------------------------
-- PULSAR: Simula la pulsación del pulsador captura
-- Parámetros de entrada:
-- No tiene.
---------------------------------------------------------
procedure pulsar is
begin
captura_i <= '1';
for i in 1 to 10 loop
captura_i <= not captura_i;
wait for REBTIME;
end loop;
captura_i <= '0';
wait for PUSHTIME;
for i in 1 to 10 loop
captura_i <= not captura_i;
wait for REBTIME;
end loop;
captura_i <= '1';
wait for PUSHTIME;
end pulsar;
begin
-- Secuencia de operación.
wait for 2 sec;
pulsar;
wait for 2 sec;
pulsar;
wait;
end process;
end simula;

El control de la introducción de estímulos propiamente dicha se realiza mediante un proceso.


En él se declara un procedimiento para las acciones a llevar a cabo en la verificación del
diseño. En este ejemplo el procedimiento pulsar reproduce la pulsación de la tecla CAPTURA.

-10-
Diseño con VHDL
.

En el cuerpo del proceso se controla el instante en que se realiza cada acción (ejecución del
proceso asociado) mediante sentencias wait for. Notese que este proceso no tiene lista de
sensibilidades por lo que se estaría ejecutando siempre. Para evitarlo se finaliza dicho proceso
con una sentencia wait .

3. CREACIÓN DE LOS ARCHIVOS FUENTE.


Para la creación de los archivos fuente se va a utilizar el editor emacs debido a que tiene
precargadas plantillas con la sintaxis de VHDL, lo que facilita de forma notable la creación de
dichos archivos. Aunque se podría utilizar cualquier otro editor de textos, incluso el que tiene
la herramienta que se va utilizar para simular los archivos VHDL. Aunque dicha herramienta
también dispone de plantillas de VHDL, no son tan sencillas de manejar como las de emacs.
En esta sección vamos a vez los elementos básicos que nos permitirán crear cualquier tipo de
archivo VHDL, aunque se va a utilizar una ínfima parte de las posibilidades que este editor nos
aporta.

Para familiarizarnos con el entorno se va a crear un archivo sencillo, correspondiente a una


entidad que realiza la cuenta de 0 a 99, de forma similar que el contador de décadas utilizado
en la entidad crono, y cuyo listado se muestra a continuación. Dicho archivo se suministra
dentro de la carpeta archivo y tiene de nombre contador.vhd.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity contador is
port (
rst : in std_logic;
clk : in std_logic;
EN1HZ : in std_logic;
unidades : out std_logic_vector(3 downto 0);
decenas : out std_logic_vector(3 downto 0));
end contador;
architecture rtl of contador is
signal CntUnidades : unsigned(3 downto 0);
signal CntDecenas : unsigned(3 downto 0);
begin -- rtl
process(clk, rst)
begin
if(rst = '0') then
CntUnidades <= (others => '0');
CntDecenas <= (others => '0');
unidades <= (others => '0');
elsif(clk = 1' and clk'event) then
if(EN1HZ = 1') then
if (CntUnidades = 9) then
CntUnidades <= (others => '0');
if (CntDecenas = 5) then
CntDecenas <= (others => '0');
else
CntDecenas <= CntDecenas + 1;
end if;
else
CntUnidades <= CntUnidades + 1;
end if;
end if;
end if;
end process;
unidades <= std_logic_vector(CntUnidades);
decenas <= std_logic_vector(CntDecenas);
end rtl;

Nótese que en la línea - if(EN1HZ = 1') then- se ha cometido un error de forma deliberada para
ver como se pueden depurar con las herramientas utilizadas.

-11-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Para iniciar el editor emacs se hace doble clic en el icono de acceso directo de la figura 7,
apareciendo la ventana de la figura 8.

Figura 7. Icono de la aplicación.

Este es un editor pensado para trabajar en UNIX, por lo que no acepta los comandos típicos
de windows, posteriormente volveremos sobre esto.

Figura 8. Ventana de bienvenida de emacs.

En la ventana de trabajo existen tres zonas: la superior en la que se encuentra la barra de


herramientas, la central o zona de trabajo en la que se escribe el texto, y la inferior o ventana
de comandos, desde la que se pueden ejecutar algunos comando de la herramienta.

Con el comando File de la barra de herramientas podemos acceder a los comandos de manejo
de archivos, de forma similar a otros programas de windows, con la salvedad de que no
aparece el comando new (nuevo). Un archivo nuevo se crea con el comando File º Open File,
y una vez seleccionada la carpeta donde queremos crear el archivo se le da un nombre que
no exista en dicha carpeta.

Figura 9. Comando File.

-12-
Diseño con VHDL
.

Los archivos VHDL tienen siempre la extensión vhd. Cuando se esta editando un archivo VHDL
aparece un nuevo elemento de nombre VHDL en la barra de herramientas, esto es un buen
indicativo de que hemos utilizado la extensión correcta para nuestro archivo.

Una vez seleccionado el archivo de entrada, ya se puede a introducir las líneas de texto como
si de otro editor se tratase. Para la operación de guardar archivo se utiliza el comando Edit º
Save buffer. En este entorno, lo referente a buffer equivale a file en un entorno de windows.
Con lo cual, con lo visto ya seríamos capaces de crear un archivo VHDL, si bien la utilización
del editor emacs viene justificada por la sencillez en la utilización de las plantillas de
construcciones típica de VHDL.

Para acceder a las plantillas de VHDL se selecciona VHDL º Template, apareciendo las
opciones de la figura 10. Dentro de las plantillas podemos introducir tanto datos de
organización como son la cabecera o la fecha como comandos de VHDL. En ambos casos hay
campos en los que el autor debe completarlos, para ello en la ventana de comandos se
pregunta por el dato a introducir, el cual, una vez introducido, se valida con 5.

Figura 10. Plantillas VHDL.

Por ejemplo para introducir las dos primeras líneas de nuestro código se seleccionaría la
construcción VHDL library y se introduce el nombre ieee (figura 11), el cual es validado con
5, a continuación nos pedirá el nombre del paquete de la librería anterior que queremos
seleccionar (comando use). Si se desea introducir otro paquete de la misma u otra librería se
utilizará la plantilla use.

Figura 11. Plantilla Library.

-13-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Una forma más simple de seleccionar la librería y el paquete consiste en ejecutar el comando
VHDLº Templateº Templateº Package, accediendo a los paquetes más comunes en
VHDL (figura 12). De esta forma, se introduce a la vez la librería que contiene al paquete, y
él mismo.

Figura 12. Paquetes seleccionables.

En nuestro ejemplo si se selecciona el comando VHDLº Templateº Templateº Packageº


std_logic_1164, aparecenlas siguientes líneas:

library ieee;
use ieee.std_logic_1164.all;

Existen plantillas en las que algunos campos, según los casos, no se tiene o quiere introducir
datos. En este caso cuando se pidan dichos datos se pulsa 5. Por ejemplos, ésto sucede
cuando estamos utilizando la plantilla entity y nos pide los nombres de los genéricos o los
comentarios a añadir a los puertos.

A la hora de introducir algunos datos, sobre todo en el caso de palabras reservadas de VHDL,
no es necesario introducir todos los caracteres de las mismas, basta teclear los primeros
caracteres del comando y con la tecla Tab (º›) se completa. Puede darse el caso, según los
caracteres introducidos, que existan varias opciones, para pasar de una a otra se pulsa
nuevamente la tecla Tab. Obviamente, cuantos más caracteres de la palabra reservada se
introduzcan más rápido se de accederá a él. Esta forma de completar las palabras reservadas
de VHDL, también se puede realizar con los nombres de los objetos (puertos, señales, etc)
declarados en un archivo

Una vez completado el nombre de una palabra reservada de VHDL con la tecla Tab, a
continuación se pulsa la barra espaciadora para proceder a completar los campos del comando
el valor de cada campo se valida con pulsa 5, pasando a introducir los datos para otro campo,
si lo hay.

Un caso que merece comentarse es la creación de un proceso, en el que se nos pregunta si


el proceso es secuencial o combinacional, En el primer caso nos pide el nombre de las señales
de reloj y reset y a continuación lo completa con el siguiente código:

process (clk, rst)


begin -- process
if rst = '0' then -- asynchronous reset (active low)

elsif clk'event and clk = '1' then -- rising clock edge

end if;
end process;

-14-
Diseño con VHDL
.
faltaría por introducir el código que modele el funcionamiento asíncrono y síncrono.

En el caso de los procesos combinacionales se nos pide los objetos que conforman la lista de
sensibilidad.

Tal y como se dijo al principio, este editor está pensado para trabajar en un entorno UNIX, con
lo que no acepta algunos de los comandos típicos de windows, tal es el caso de Crt+c para
copiar y Ctr+v para pegar. Para copiar, tan sólo es necesario seleccionar con el cursor la
porción de código que se quiere copiar, pasando de forma automática al portapapeles. Para
pegar se ejecuta el comando Editº Paste.

Para poder seleccionar texto con las teclas May(8) y los cursores es necesario teclear: Alt+x,
para entrar en la ventana de comandos, y desde aquí se introduce pc-selection-mode.

A la hora de utilizar componentes un comando que ahorrar gran cantidad de tiempo es VHDLº
Portº Copy, antes de ejecutarlo es necesario situar el cursor dentro de la declaración de una
entidad. A continuación se puede realizar el pegado con diferentes opciones (figura 13).

Figura 13. Opciones de pegado de Port.

Como una entidad:

entity contador is
port (
rst : in std_logic;
EN1HZ : in std_logic;
unidades : out std_logic_vector(3 downto 0);
decenas : out std_logic_vector(3 downto 0));
end contador;

Como un componente:

component contador
port (
rst : in std_logic;
EN1HZ : in std_logic;
unidades : out std_logic_vector(3 downto 0);
decenas : out std_logic_vector(3 downto 0));
end component;

Como una instanciación

u1: contador
port map (
rst => rst_i,
EN1HZ => EN1HZ_i,
unidades => unidades_i,
decenas => decenas_i);

-15-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Como señales
signal rst_i : std_logic;
signal EN1HZ_i : std_logic;
signal unidades_i : std_logic_vector(3 downto 0);
signal decenas_i : std_logic_vector(3 downto 0);

Como testbench. En este caso se crea un nuevo archivo de nombre el de la entidad seguido
de _tb y con el siguiente contenido

-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-------------------------------------------------------------------------------
entity contador_tb is
end contador_tb;
-------------------------------------------------------------------------------
architecture sim of contador_tb is
component contador
port (
rst : in std_logic;
EN1HZ : in std_logic;
unidades : out std_logic_vector(3 downto 0);
decenas : out std_logic_vector(3 downto 0));
end component;
signal rst_i : std_logic;
signal EN1HZ_i : std_logic;
signal unidades_i : std_logic_vector(3 downto 0);
signal decenas_i : std_logic_vector(3 downto 0);
begin -- sim
DUT: contador
port map (
rst => rst_i,
EN1HZ => EN1HZ_i,
unidades => unidades_i,
decenas => decenas_i);

end sim;
-------------------------------------------------------------------------------

Es posible estar trabajando con más de un archivo a la vez, para movernos por ello se utiliza
el comando buffer.

A medida que se va introduciendo código no es necesario prestar atención a la introducción de


tabulaciones para que el código sea mas legible, existiendo un comando que lo realiza de
forma automática. Este comando es VHDLº Beautify º Beautify_Buffer.

4. ENTORNO DE SIMULACIÓN ModelSim.


Para verificar la validez de lo diseños VHDL se va a utilizar el simulador ModelSim de Mentor
Graphics. Este simulador se puede controlar mediante una interface gráfica de usuario basada
en menús y cajas de diálogo desplegables o bien mediante una línea de comandos. En este
tutorial se explicará el uso del simulador mediante ambas opciones, siendo más potente la
utilización de comandos, pudiendose englobar un conjunto de ellos en un archivo script que
facilita notablemente las tareas de simulación, el cual se ejecuta como una macro. Además

-16-
Diseño con VHDL
.
cabe indicar que el interface de usuario puede variar de una versión a otra, no ocurriendo esto
con los comandos.

La secuencia de comandos a emplear para realizar una simulación se pueden almacenar en


un fichero de script. Conceptualmente los ficheros de scripts son similares a los ficheros de
proceso por lotes de un sistema operativo (por ejemplo .bat para DOS). Se les suele asignar
la extensión .do. Para ejecutar un fichero de script se emplea el comando do cuya sintaxis es:

do <nombre_fichero_script>

La posibilidad de almacenar estas secuencias de comandos en ficheros de script permite


reutilizarlos en los distintos tipos de simulación a realizar (funcional, post-implementación y
temporal) durante el flujo de diseño VHDL para FPGAs.

Para realizar este tutorial se ha empleado la versión 6.0, por lo que algunas de las ventanas
mostradas pueden variar ligeramente en otras versiones. Hay que indicar que esta herramienta
es case sensitive, distinguiendo entre mayúsculas y minúsculas. Los comando siempre se
escriben en minúsculas.

4.1 ARRANQUE.

Para arrancar el simulador se puede hacer doble clic sobre el icono de acceso directo (figura
14) del escritorio del PC o seleccionando Inicio º Programas º ModelSim SE 6.0 º
ModelSim.

Figura 14. Icono de la aplicación.

En ese momento se muestra la pantalla que aparece en la figura 15.

BARAR DE HERRAMIENTAS

VENTANA DE TRABAJO VENTANA DE EDICIÓN

VENTANA DE TEXTO

Figura 15. Pantalla principal de ModelSim.

-17-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

En la ventana de trabajo pueden aparecer varias pestañas dependiendo de las operaciones


realizadas con el diseño:

En ella se muestran los archivos fuente que forman parte del diseño, pudiendo
ser compilados. Para ello es necesario añadirlos.

Visualiza las librerías que podemos utilizar en nuestro diseño. Haciendo clic en
+ podemos ver los paquetes que incluyen.

Muestra la estructura jerárquica de la entidad que se está simulando.

Muestra los archivos VHDL que forman parte del diseño que se está simulando.

En la ventana de texto donde se introducen los comando y se visualiza los mensajes que se
producen durante su ejecución. Utilizando las teclas de cursor arriba (8) y abajo (9) se puede
acceder a los comandos anteriores o posteriores introducidos, para poder ejecutarlos de nuevo.

En la ventana de edición se muestra el contenido de los archivos VHDL seleccionados,


permitiendose su modificación.

La barra de herramientas engloba todas las herramientas que se pueden utilizar.

Los pasos a dar para simular un diseño son los siguientes.

Ø Creación del proyecto.


Ù Creación de nuevas librerías y mapeado de las librerías a reutilizar.
Ú Compilación del código fuente.
Û Carga de la unidad de diseño a simular.
Ü Definición de puntos de prueba.
Ý Avance y detención de la simulación.
Þ Introducción de estímulos.
ß Análisis de resultados.
ô Finalización de la sesión de simulación.

Para salir de ModelSim se selecciona File º Quit, o se ejecuta el comando quit

Librerías.

Las librerías son directorios que contienen unidades de diseño compiladas. Estas unidades de
diseño pueden ser primarias o secundarias. Las unidades de diseño primarias (entidades,
declaraciones de paquetes y configuraciones) almacenadas en una librería deben tener un
nombre único. Por otro lado las unidades de diseño secundarias (arquitecturas y cuerpos de
paquetes) pueden tener nombres comunes. Por ejemplo, las arquitecturas de dos entidades
distintas pueden tener el mismo nombre.

Este simulador clasifica las librerías en dos tipos: librerías de trabajo y librerías de recursos.
Todo diseño dispone de una única librería de trabajo que por defecto se denomina work, donde
se almacenan, una vez que se han compilado, las unidades de diseño descritas en los ficheros
fuente del diseño. La librería de trabajo debe crearse antes de compilar los ficheros fuente del
diseño. Por otro lado las librerías de recursos contienen unidades de diseño a las que se puede

-18-
Diseño con VHDL
.
hacer referencia desde diseño que se está compilando. Estas librerías se declaran mediante
las sentencias library y use.

Para crear una librería se utiliza el comando vlib. La sintaxis de este comando es:

vlib <library_name>

donde <library_name> es el nombre de la librería. Este comando crea el directorio asociado


a dicha librería en el directorio de trabajo actual.

Puede ocurrir que el directorio donde se almacena una librería no este contenido en el
directorio de trabajo actual. Esta es una situación típica que se da cuando se pretenden utilizar
unidades de diseño compiladas con anterioridad para otro diseño en el diseño actual.

Para gestionar estas situaciones ModelSim asigna a cada librería un nombre físico y un nombre
lógico. El nombre físico corresponde al path del directorio donde se almacenan las unidades
de diseño compiladas. El nombre lógico es la denominación que recibe la librería cuando se
hace referencia a ella desde el simulador o desde el código fuente VHDL, por ejemplo mediante
la sentencia use. Cuando una librería se encuentra almacenada en el directorio de trabajo
actual el nombre físico coincide con el nombre lógico. En caso contrario es preciso asignar a
la librería un nombre lógico mediante el comando vmap. A este proceso se le denomina
mapeado. La sintaxis de este comando es:

vmap <nombre_logico> <path_del_directory>

El mapeado de estas librerías sólo se realiza una vez, es decir, no es preciso compilar estas
librerías para cada nuevo diseño a realizar. Ademas el archivo de inicialización de ModelSim
es modificado de forma que dichas librerías serán siempre visibles para posteriores diseños.

Otros comandos empleados para la gestión de librerías son vdir y vdel que se emplean
respectivamente para mostrar el contenido de una librería y para borrar elementos de ésta. La
sintaxis de vdir es:

vdir [-lib <nombre_librería>]

Si se emplea el comando sin parámetros se muestra el contenido de la librería work. Por otro
lado la sintaxis del comando vdel es:

vdel [-lib <nombre_librería>] [-all |<unidad_de_diseño>]

donde <nombre_librería> es la librería de donde se desea borrar la unidad de diseño en


cuestión. Si no se especifica la librería se toma por defecto la librería work. En cuanto a las
unidades de diseño a borrar éstas se pueden especificar individualmente o bien borrar todas
ellas utilizando el parámetro -all. En este último caso se borra incluso el directorio
correspondiente a la librería por lo que si se desean compilar con posterioridad nuevos ficheros
fuente sobre ésta será preciso crearla de nuevo con el comando vlib.

Al igual que ocurre en los compiladores de C, los cuales proporcionan en la librería de soporte
del sistema las funciones definidas por ANSI C, los simuladores VHDL suelen disponer de una
serie de librerías predefinidas que no es necesario compilar cada vez que se realiza un nuevo
diseño. En el caso concreto de ModelSim se encuentran predefinidas las siguientes librerías:

! La librería std que contiene los paquetes standard y textio.


! La librería IEEE que contiene paquetes aritméticos precompilados de Synopsys e IEEE.
! La librería vital empleada para realizar simulaciones temporales.

-19-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Estas librerías están optimizadas para la simulación por lo que no es recomendable que el
usuario realice modificaciones sobre ellas.

4.2. CREACIÓN DE UN PROYECTO.

Al igual que ocurre con otros entornos de desarrollo ModelSim gestiona la información de cada
diseño mediante un proyecto, facilitando de esta forma su gestión. Un proyecto se compone
de:

! Un directorio de trabajo en el que se almacenan los distintos ficheros generados


durante la compilación y simulación de un diseño.
! Los ficheros fuente VHDL del diseño.
! Las librerías creadas.
! La configuración empleada en el simulador.

Esta información se almacena en un fichero con el mismo nombre que el del proyecto y la
extensión .mpf. Las operaciones que se pueden realizar con un proyecto son crearlo, abrirlo,
cerrarlo o borrarlo. Estas se realizan mediante las opciones New, Open, Close y Delete del
menú File.

Para crear el proyecto empleado para realizar la simulación funcional del diseño del ejemplo
seleccione la opción File º New º Project de la barra de menús. En ese momento se
mostrará en la pantalla la ventana Create Project (figura16 ), que permite seleccionar el nombre
y ubicación del proyecto. En el caso de que no exista el directorio seleccionado se crea.
Además crea automáticamente la librería work definiendola como la librería de trabajo para
este nuevo diseño.

Si bien el empleo de proyectos no es obligatorio, su uso facilita la gestión de los diseños.

Figura 16. Ventana de diálogo para la creación de un proyecto

En caso de no desear emplear esta facilidad habría que ejecutar los siguientes comandos:

cd c:/users
mkdir tutorial
cd tutorial
vlib work

-20-
Diseño con VHDL
.
Notese que la sintaxis empleada por ModelSim para especificar la jerarquía de un directorio es
la misma que la de Unix, ya que las primeras versiones de este simulador se desarrollaron para
dicho sistema operativo.

Al seleccionar OK en la figura 16 aparece la figura 17 que permite crear un nuevo archivo


fuente (VHDL) o añadir uno ya existente estas opciones se ejecutan si se quiere compilar los
archivos desde el interface gráfico, posteriormente volveremos sobre esta opción. Si se va a
compilar con comandos desde la ventana de texto se selecciona Close.

Figura 17. Ventana de diálogo para la añadir un archivo fuente al proyecto

Si se desea editar un archivo VHDL ya creado, por ejemplo con emacs, se utiliza File º Open
y se selecciona el archivo a editar. Desde la ventana de texto se edita un archivo introduciendo
el comando:

edit <fichero>.vhd

4.3. COMPILACIÓN DEL CÓDIGO FUENTE.

Una vez creado el proyecto y los ficheros VHDL que forman parte del diseño se procederá a
compilarlos. Para ello se emplea el comando vcom. La sintaxis resumida de este comando es:

vcom [-87][-93] [-work <nombre_librería>] <fichero1>.vhd <fichero2>.vhd ...

El parámetro -93 indica que se emplee el la versión 93 de VHDL frente a la 87. Mediante el
parámetro -work se especifica la librería destino en la que se almacenará el código compilado.
Si no se especifica este parámetro por defecto se almacena en la librería work. Recuerdese
que la librería destino debe haber sido creada con anterioridad y en caso de que no se
encuentre en el directorio actual haber sido hecha visible mediante el comando vmap.

Para la compilación del contador de décadas se introduce:

vcom -93 contador.vhd

Durante la compilación el simulador muestra en la consola información referente a la evolución


de ésta. Si aparecen errores, la descripción de estos se muestra en color rojo. Haciendo doble
click sobre la línea de error se muestra automáticamente la línea del fichero fuente que produjo
este error en la ventana de código fuente. En la figura 18 aparece un ejemplo de esto.

-21-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Figura 18. Visualización automática de errores en el código fuente

Sobre la pantalla de la figura 18 y con el editor de ModelSim, se corrigen los errores,


pudiendose realizar también con el emacs. Si en la pantalla de la figura 18 no permitiese
modificar el archivo es debido a que está abierto en modo lectura, para cambiarlo se pulsa
sobre el botón derecho del ratón y se desactiva la opción Only Read.

Para compilar nuevamente el archivo no es necesario teclear otra vez el comando vcom, con
las teclas 8 y 9, estando en la ventana de texto, se puede acceder a él.

Por defecto las unidades de diseño se almacenarán en la librería work. Si un fichero VHDL
proporciona una unidad de diseño que será utilizada en otro fichero, el primero de ellos debe
compilarse en primer lugar. Así, para compilar los ficheros fuente del diseño del cronometro se
han de ejecutar los siguientes comandos desde la consola de ModelSim:

vcom bcd2seg.vhd
vcom prescaler.vhd
vcom ant_reb.vhd
vcom maq_fsm.vhd
vcom cnt_cap.vhd
vcom crono.vhd
vcom crono_tb.vhd

Una forma más sencilla consiste en crear un fichero script en el que se introducen estos
comandos. El archivo creado es compila.do, por tanto se debe ejecutar el comando:

do compila.do

ejecutandose los comandos en el orden introducido.

Compilación desde el entorno gráfico

Para utilizar el entorno gráfico, en primer lugar es necesario añadir los archivos a la ventana
de trabajo. Esto se puede hacer utilizando el menú de la figura 17 cuando se crea el proyecto
o situando el ratón sobre la ventana de trabajo y pulsando el ratón derecho, apareciendo el
menú de la figura 19, donde se selecciona Add to Project. Los elementos que se pueden
añadir son:

-22-
Diseño con VHDL
.
! Un fichero nuevo: el comando Create New File permite crear un nuevo fichero de
diseño VHDL como se efectuará posteriormente.

! Un fichero existente: el comando Add Existing File permite incluir un fichero ya


existente en el proyecto actual copiándolo al directorio del proyecto o referenciándolo
desde su ubicación actual.

! Un directorio virtual: cuando el diseño es complejo y consta de muchos ficheros, puede


resultar interesante emplear el comando Create New Folder para organizarlos en
directorios y subdirectorios. Estos directorios tienen, sobre la pestaña Project del Área
de trabajo, un aspecto similar al de los directorios del sistema operativo pero no se
crean realmente en el disco, sino que son internos al proyecto.

! Una configuración para simulación: El comando Create Simulation permite crear


configuraciones para simulación, es decir, crear una asociación entre la unidad de
diseño y las opciones con las que desea simularse.

Figura 19. Menú para añadir archivos al proyecto.

Al seleccionar el archivo automáticamente se añade a la ventana de trabajo (figura 20). El


significado de la información que aparece en las columnas de la ventana de trabajo es:

Status: Indica el estado del archivo: indica que el fichero aún no ha sido compilado; que
el fichero se ha compilado y contiene errores; que el fichero ha sido compilado con éxito.

Type: Indica el tipo de fichero (VHDL, Verilog, Folder, Simulation).

Order: Indica el número de orden que ocupa el fichero en la secuencia de compilación cuando
hay varios ficheros fuente.

Modified: Muestra la fecha y hora en que el fichero fue modificado por última vez.

-23-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Figura 20. Archivo fuente añadido a la ventana de trabajo.

Al añadir un archivo, se abre automáticamente la ventana del editor de texto del entorno con
dicho archivo. En el caso de añadir más de un archivo si se desea editar uno en particular se
hace doble clic sobre él.

Para compilar el o los archivos se puede seleccionar el menú Compile de la barra de


herramientas o pulsando el botón derecho del ratón sobre la ventana de trabajo (figura 21),
indicando cual o cuales de los archivos de la ventana de trabajo se van a compilar.

Figura 21. Menú para compilar los archivos.

Con la opción Compile Order se puede modificar el orden de compilación.

En el caso de que el proyecto se quiera compilar en otro ordenador o en otro proyecto, a parte
de copiar en él los archivos fuentes habría que añadirlos a la ventana de trabajo y volver a
compilarlos. Cosa que no sucede si se utiliza un script, en el que sólo es necesario ejecutar
este último.

4.4. CARGA DE LA UNIDAD DE DISEÑO A SIMULAR.

Para poder simular el diseño realizado es preciso cargarlo en el simulador. Para ello se emplea
el comando vsim. El formato resumido de este comando es:

vsim [-lib <nombre_librería>] [-t [múltiplo]<unidades_tiempo>][-sdfmin | -sdftyp | -sdfmax


<instancia>=<fichero_sdf>]<entidad> [<arquitectura>] |[ <configuración>]

Como se puede observar todos los parámetros son opcionales excepto el que indica la unidad
de diseño superior. Este último indica la entidad a simular, siendo posible especificar también

-24-
Diseño con VHDL
.
la arquitectura concreta a emplear. Esto resulta especialmente útil cuando la entidad dispone
de varias arquitecturas. Por ejemplo si se deseara simular el contador de décadas el comando
a emplear sería:

vsim contador rtl

o bien simplemente:

vsim contador

La librería que contiene la unidad de diseño a simular también se puede especificar mediante
el parámetro opcional -lib. Si no se especifica, por defecto se supone que dicha unidad se
encuentra almacenada en la librería de trabajo (work). El parámetro -t indica la resolución de
la simulación. Dicha resolución se especifica en unidades de tiempo según el formato indicado
en la tabla 1.1. Adicionalmente puede emplearse un factor multiplicador siendo los valores
admisibles 1, 10 o 100. Si no indica la resolución del simulador, por defecto este trabaja con
una resolución de 1 ns.

Tabla 1.1: Nomenclatura empleada para especificar unidades de tiempo.


Unidades Valor Unidades Valor

fs 10-15 sg ms 10-3 sg

ps 10-12 sg sec segundos

ns 10-9 sg min minutos

us 10-6 sg hr horas

Para el caso de una simulación temporal de un diseño para FPGAs teniendo en cuenta que los
retardos internos se expresan con una resolución de 0.1 ns la opción a emplear para fijar la
resolución sería -t 100ps. Notese que no hay espacios en blanco entre el multiplicador y las
unidades. Por último el parámetro -sdfxxx sólo se usa en simulaciones temporales,
empleandose para especificar el fichero sdf que contiene la retroanotación de retardos, cosa
que no se va a utilizar en este diseño, ya que tan sólo nos limitaremos a realizar una simulación
funcional del mismo.

Según lo expuesto, una vez compilados los ficheros fuente del diseño de nuestro ejemplo se
puede proceder a cargar la unidad de diseño a simular. Para nuestro ejemplo ésta es la entidad
crono_tb, que además sólo tiene una única arquitectura. Por lo que el comando a emplear
sería:

vsim crono_tb

4.5. SELECCIÓN DE PUNTOS DE PRUEBA.

La verificación del diseño mediante simulación se basa en observar los distintos elementos que
aparecen en él. Por analogía con un simulador digital clásico a los puntos del circuito a
observar (señales) los denominaremos puntos de prueba, si bien en diseños descritos en VHDL
la variedad es más amplia: puertos, variables, señales, procesos en ejecución, etc. Tal y como
muestra la figura 22 el simulador define un total de siete ventanas más destinadas a
representar los distintos tipos de elementos. Estas ventanas son:

-25-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

! workspace o structure. Muestra la estructura jerárquica del diseño en forma de árbol.


En nivel seleccionado en esta ventana afectará al contenido de las ventanas de formas
de onda, variables, etc.

! source. Muestra el código fuente del archivo seleccionado en el workspace cuando se


activa la pestaña . Se suele emplear para ejecutar el código paso a paso.

! wave. Permite representar los cronogramas de la evolución de las señales y variables


del diseño.

! objects o signal. Muestra las señales y puertos contenidos en el nivel seleccionado en


el workspace .

! locals. Muestra las variables de una entidad.

! process. Proporciona información del estado de ejecución de los procesos.

! dataflow. La ventana de flujo de datos permite realizar un seguimiento gráfico de la


conexión de procesos mediante las señales del diseño.

! list. La ventana de listado permite observar los resultados de la simulación de forma


tabular y reflejando los ciclos delta

Figura 22. Ventanas del simulador.

Para abrir una de estas ventanas se emplea el comando view cuyo formato es:

view <nombre_ventana>

Este comando admite el carácter comodín * . Así el siguiente comando abre todas las ventanas
citadas:

view *

La descripción detallada del uso de todas las ventanas queda fuera de los objetivos de este
texto. Por este motivo sólo se expondrá el uso de la ventana de formas de onda, al ser éste el
método más empleado para depurar sistemas digitales mediante simulación.

-26-
Diseño con VHDL
.
Para abrir esta ventana seleccione la opción View º Debug windows º Wave de la barra de
menús, o bien ejecute el comando:

view wave

A continuación es preciso seleccionar las señales a visualizar. Si el número de señales a


visualizar es elevado esta operación puede ser un tanto tediosa. En ese caso se puede optar
por realizar esta operación mediante el interface gráfico. Para ello es preciso abrir las ventanas
de estructura y de señales. La primera de ellas nos servirá para navegar por la estructura
jerárquica del diseño, mientras que la segunda nos permitirá seleccionar las señales a añadir
a la ventana de formas de onda. Para abrir la ventana de estructura seleccione la opción View
º workspace de la barra de menús, o bien ejecute el comando:

view structure

también es válido:

view workspace.

De forma similar, para abrir la ventana de señales seleccione la opción View º Debug
windows º Objects de la barra de menús, o bien ejecute el comando:

view signal

también es válido:

view objects.

Tal y como muestra la figura 23 al seleccionar un nivel en la ventana de estructura, se muestran


todas las señales contenidas en dicho nivel sobre la ventana de formas de onda.

Figura 23. Selección de las señales en un determinado nivel jerárquico.

Una vez mostradas las señales de interés en la ventana de señales se procederá a añadirlas
a la ventana de formas de onda. Para ello se seleccionan las señales en cuestión en la ventana
de señales y a continuación se pulsa el botón derecho del ratón, seleccionando una de las
posibles opciones (figura24).

-27-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Figura 24. Seleccionar señales a visualizar


en la ventana wave.

Una forma más simple, consiste en seleccionar y arrastrar las señales o puertos hasta la
ventana wave. Una vez finalizado este proceso la ventana de formas de onda presenta el
aspecto mostrado en la figura 25.

Figura 25. Objetos añadidos a la ventana wave.

También es posible representar en la ventana de formas de onda la evolución de las variables


de los procesos. Para ello es preciso que el proceso al que pertenece la variable a visualizar
esté etiquetado. Esta etiqueta sirve como elemento identificador dentro de la ventana de
estructura. El proceso a seguir es el mismo que el utilizado para seleccionar las señales, pero
utilizando la ventana de variables (locals).

El color de las señales, el formato numérico utilizado en el caso de los vectores, etc. se puede
fijar mediante las distintas opciones del menu sensible al contexto (figura 26)que aparece al
seleccionar una señal determinada y pulsar a continuación el botón derecho del ratón (o con
Format de la barra de menús).

-28-
Diseño con VHDL
.

Figura 26. Parámetros de los objetos de


la ventana wave

La configuración utilizada en la ventana de formas de onda puede almacenarse en un fichero


de scripts denominado wave.do para volverla a utilizar en posteriores sesiones de simulación.
Para ello seleccione la opción Fileº Save Format de la barra de menús de la ventana wave,
o pulsando sobre . Básicamente, este fichero contiene comandos del tipo add wave, los
cuales se utilizan para añadir señales o variables a la ventana de formas de onda. Su sintaxis
resumida es:

add wave [-<format>] [-<radix>] <nombre_elemento>

El parámetro <nombre_elemento> especifica el nombre de la variable o señal a visualizar. Si


dicho elemento no se encuentra en la entidad superior de la jerarquía se debe indicar el camino
completo dentro de la jerarquía En el caso de las variables, se especificará el camino hasta la
arquitectura donde reside el proceso que contiene la variable. Asi. por ejemplo, para añadir la
señal state de la entidad maq_fsm se pondría:

add wave dut/u4/u2/state

El parámetro opcional radix especifica la base numérica con que se representan los vectores.
Los valores que puede tomar este parámetro son binary, octal, decimal (o signed), unsigned,
hexadecimal, ascii, symbolic o default. Puesto que estos nombres son suficientemente
ilustrativos hay poco que añadir a este respecto. Tan sólo indicar, que la opción -symbolic se
emplea con tipos enumerados. Si no se indica nada se representa según la base numérica
fijada por defecto (-default) en las opciones del simulador.

El parámetro opcional format indica el formato de representación (numérico o gráfico) a


emplear de los vectores. Los valores que puede tomar son: literal, logic, analog-step, analog-
interpolated y analog-backstep. Normalmente esta opción no se suele emplear, dejando que
estos los vectores se representen en formato numérico. Las tres últimas opciones permiten
representar la secuencia de valores que toma el vector como las muestras de una señal
analógica digitalizada. Esto es especialmente útil en la implementación de sistemas de
tratamiento digital de señal. La figura 27 muestra un ejemplo de esto.

-29-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Figura 27. Ejemplo de representación analógica de señales.

Una descripción más detallada de los formatos analógicos, como de los digitales, se encuentra
en el manual del simulador, al que se puede acceder desde Help de la barra de menús.

En el ejemplo del contador de décadas, para analizar el funcionamiento del sistema se van a
observar sus puertos, las señales de cuenta (Cntunidades y Cntdecenas). Según esto los
comandos a ejecutar serían:

add wave rst


add wave clk
add wave en1hz
add wave -radix unsigned Cntunidades
add wave -radix unsigned Cntdecenas
add wave -radix unsigned unidades
add wave -radix unsigned decenas

Tal y como se ha indicado una forma sencilla de obtener estos comandos es realizar una
selección manual y a continuación generar el fichero de configuración wave.do, de este último
se extraen los objetos que queremos visualiza, y se añaden al archivo scrip para la simulación.
Téngase presente que el formato de los comandos add wave tienen diferente contenido al
mostrado anteriormente, por lo que, si el usuario lo considera pertinente puede retocarlos, para
tener una sintaxis más corta, si bien la semántica sigue siendo la misma. A continuación se
muestran estos comandos tal y como se encuentran en el archivo wave.do.

add wave -noupdate -format Logic /contador/rst


add wave -noupdate -format Logic /contador/clk
add wave -noupdate -format Logic /contador/en1hz
add wave -noupdate -format Literal -radix unsigned /contador/cntunidades
add wave -noupdate -format Literal -radix unsigned /contador/cntdecenas
add wave -noupdate -format Literal -radix unsigned /contador/unidades
add wave -noupdate -format Literal -radix unsigned /contador/decenas

Los comandos utilizados para cargar el diseño a simular y configurar la ventana de formas de
onda se recogen en el script contador.do proporcionado.

Simulación desde el entorno gráfico.

Para simular una entidad desde el interface gráfico, se selecciona la pestaña Library del
worspace, se abre la librería work y se hace doble clic sobre la entidad a simular. En el caso
de que dicha entidad tuviera más de una arquitectura, se haría doble clic sobre la arquitectura
deseada (figura 28).

-30-
Diseño con VHDL
.

Figura 28. Selección de la entidad


simular.

4.6. INTRODUCCIÓN DE ESTÍMULOS.

Normalmente los estímulos del diseño se introducen mediante el código del fichero de un banco
de pruebas o testbench. Sin embargo en un diseño típico el sistema está compuesto por varios
módulos más sencillos que se instanciarán en el diseño final. Antes de obtener el diseño final
será preciso validar los módulos que lo componen. La realización de un banco de pruebas para
cada uno de estos módulos tan sencillos puede resultar una tarea tediosa. Para solventar esta
situación se puede emplear el comando force, que permite introducir estímulos sobre las
señales resueltas del diseño de una forma sencilla. La sintaxis general de este comando es:

force <nombre_señal> <valor1> <tiempo1>, <valor2> <tiempo2> ...

Con este formato se introducen los estímulos especificados en pares (valor, instante de tiempo)
para la señal en cuestión. Cuando se trata de una señal interna en el nombre se debe
especificar el camino completo en la jerarquía del diseño. Los valores a asignar a una señal
deben ajustarse al tipo de datos de misma. Los instantes de tiempo pueden expresarse en
formato relativo al instante actual de simulación o en valor absoluto respecto al origen de
tiempos (t=0). En este último caso se ha de añadir el prefijo @. Por defecto las unidades en que
se expresan los tiempos coincide con la resolución del simulador (ns).

Existe un conjunto de parámetros adicionales que permiten introducir estímulos periódicos.


Estos son:

-repeat <periodo> Repite el comando force con el periodo de tiempo especificado.


-cancel <tiempo> Cancela el comando force una vez transcurrido el tiempo
especificado.

A continuación se muestran varios ejemplos del uso de este comando.

force clr 0 Fuerza clr a 0 en el instante actual de simulación.

force bus1 01XZ 100 ns Fuerza bus1 a 01XZ 100 ns después del instante actual de simulación.

force bus2 16#4F @200 Fuerza bus2 a 4Fh 200 unidades de tiempo (especificadas por la
resolución de simulación) desde el inicio de ésta.

force clk 0 0, 1 25 -repeat 50 Genera una señal de periodo 50 ns con un ciclo de trabajo del 50%

force clk 0 0, 1 20 -repeat 50 Fuerza clk a 0 en el instante actual de simulación, 20 unidades de


-cancel 1000 tiempo después pasa a 1. Esto se repite cada 50 unidades de tiempo
hasta alcanzar 1000 unidades de tiempo. Por tanto el siguiente 1
ocurrirá en la unidad de tiempo 70.

-31-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Según lo expuesto para validar de forma individual el módulo contador se emplearía la


siguiente secuencia de comandos:

vcom contador.vhd
vsim contador
add wave rst
add wave clk
add wave en1hz
add wave -radix unsigned Cntunidades
add wave -radix unsigned Cntdecenas
add wave -radix unsigned unidades
add wave -radix unsigned decenas
force clk 0, 1 50 -r 100
force en1hz 1
force rst 0
run 200
force rst 1
run 5 us
force en1hz 0
run 500
force en1hz 1
run 1 us

En la figura 29 se muestra el resultado de la simulación del contador de décadas con los


aplicando los comandos anteriores.

Figura 29. Resultado de la simulación del contador de décadas.

El comando force se emplea para aplicar estímulos a señales resueltas. En el caso de que se
aplique un estímulo a una señal interna del diseño, el código VHDL determinará el estado que
toma esta señal. Existe un modo de operación de este comando denominado “modo
congelado” que permite imponer un valor a una señal interna. Esto es especialmente útil para
reducir el tiempo de simulación de un diseño. Así, en el diseño del cronómetro, considerado la
salida del sistema cambia cada segundo se precisaría mucho tiempo para verificar el diseño.
Para reducir el tiempo de simulación se forzará la salida del preescaler (señal EN1Hz) a 1
mediante el comando:

force -freeze crono_tb/dut/u3/en1hz 1

En el caso de utilizar la opción freeze con un comando force, para desactivarla se debe ejecuta
primeramente el comando noforce. Por ejemplo para el caso anterior se utilizaría:

-32-
Diseño con VHDL
.
noforce crono_tb/dut/u3/en1hz

Lo mismo sucede cuando a un puerto se le asigna una señal periódica com la opción -r. Así,
por ejemplo, para la generación de valores para la señal EN1HZ se podría aplicar el comando:

force en1hz 1, 0 100 -r 5us

para generar una señal de 200 Khz, que está a nivel alto 100 ns. Si a continuación, para un
nuevo paso simulación, se quisiera fijar dicha señal a un nivel fijo, por ejemplo a nivel alto, se
deberán utilizar los comandos:

noforce en1hz
force en1hz 1

Resumiendo, para realizar la simulación del diseño se introducirá la secuencia de comandos


que se indica a continuación. Esta secuencia se encuentra almacenada en el fichero de script
crono_tb.do proporcionado.

vcom bcd2seg.vhd
vcom prescaler.vhd
vcom ant_reb.vhd
vcom maq_fsm.vhd
vcom cnt_cap.vhd
vcom crono.vhd
vcom crono_tb.vhd
vsim crono_tb
add wave rst_i
add wave clk_i
add wave dut/u3/en1hz
add wave dut/u3/en200hz
add wave captura_i
add wave dut/u4/p_i
add wave dut/u4/ce
add wave -radix unsigned dut/cntunidades
add wave -radix unsigned dut/cntdecenas
add wave -radix unsigned dut/unidades
add wave -radix unsigned dut/decenas
add wave displayunidades_i
add wave displaydecenas_i
run 5.5 sec
force -freeze crono_tb/dut/u3/en1hz 1
run 100 ms

La figura 30 muestra el aspecto de la ventana wave obtenida al ejecutar el script anterior,


donde se puede comprobar el funcionamiento correcto del diseño.

-33-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Figura 30. Resultado de la simulación del cronómetro.

Para aplicar valores a los objetos desde el interface gráfico, en la ventana wave se selecciona
el objeto al que se le va a asignar un valor, se pulsa el botón derecho del ratón y se selecciona
la opción force, apareciendo el cuadro de dialogo de la figura 31, donde se selecciona el valor
que se le va a asignar y el instante de tiempo.

Figura 31. Asignación de valores.

4.7. AVANCE Y DETENCIÓN DE LA SIMULACIÓN.

Para provocar un avance de la simulación se emplea el comando run, siendo su sintaxis:

run[<magnitud>[<unidades_tiempo>]] | <modo>

El tiempo a avanzar en la simulación se puede especificar de varias formas, de acuerdo a una


serie de modos predeterminados. Una primera especificación del tiempo de simulación es:

run[<magnitud>[<unidades_tiempo>]]

En este formato se avanza el tiempo especificado por el parámetro. Este tiempo se da como
un valor numérico seguido de unas unidades de tiempo empleando para ello el formato descrito
en la tabla 1.1. Si no se especifican las unidades se entiende que el tiempo viene expresado
en la resolución del simulador (por defecto es 1ns). Por ejemplo, el siguiente comando
provocaría un avance en la simulación de 400 ns:

run 400ns

Otra forma de emplear el comando run responde al formato:

run<modo>

-34-
Diseño con VHDL
.

donde el parámetro <modo> puede ser uno de los siguientes valores:

! -all: Ejecuta la simulación indefinidamente hasta que ésta se detenga debido a un punto
de ruptura, a un error de simulación, a una sentencia assert o que se pulse .

! -step: Avanza la simulación hasta la siguiente sentencia VHDL.

! -stepover: Es exactamente igual que la anterior salvo que las llamadas a


procedimientos o funciones se tratan como una única sentencia, ejecutandose de una
vez.

! -continue: Continua la simulación desde el punto en que se detuvo debido a un punto


de ruptura.

! -next: Ejecuta la simulación hasta el siguiente evento.

Según esto el comando:

run -all

ejecutaría la simulación del ejemplo hasta que se detuviera debido a una de las causas antes
comentadas.

Para reiniciar la simulación, volviendo el tiempo a 0 ns, e iniciar una nueva simulación se
emplea el comando restart. Al ejecutar este comando aparece la ventana mostrada en la figura
32. En ella se puede seleccionar qué elementos mantendrán la configuración fijada durante la
sesión de simulación actual.

Figura 32. Ventana Restart.

Si durante la sesión de simulación se descubre un error de diseño que obliga a modificar el


código fuente será preciso finalizar la simulación mediante el comando quit -sim. A
continuación se modifica el código fuente, se compila y se vuelve a cargándolo de nuevo tal y
como se ha descrito.

En la barra de herramientas se encuentran otros iconos que permiten controlar el avance del
tiempo del simulador:

Permite selecciona la cantidad de tiempo que avanza la simulación cuando


se ejecuta el comando run.

-35-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

run.

run -continue

run -all

Parar la simulación (break).

run - step

run - step over

restart

Merece la pena hacer hincapié en la utilización del menú help para acceder a una colección
de archivos en formato pdf que van desde un manual de ModelSim hasta la explicación de la
semántica y sintaxis de todos los comandos.

5. ANÁLISIS DE RESULTADOS.
En este apartado se comentará como navegar por la ventana de cronogramas así como la
realización de mediciones de tiempos.

Para ajustar el zoom de la visualización se emplean cuatro elementos que aparecen en la barra
de herramientas:

! Zoom de acercamiento.
! Zoom de alejamiento.
! Muestra la totalidad de los cronogramas.
! Zoom de un área.

Para realizar medidas de tiempo se emplean los cursores, los cuales se añaden con el
elemento . La primera vez que se pulsa este botón aparece el cursor principal, que tal y
como muestra la figura 34 éste aparece como una línea naranja de trazo grueso. Los cursores
se pueden situar de forma manual pulsando directamente sobre un punto de los cronogramas.
En este caso el cursor se sitúa sobre la transición más próxima al punto seleccionado. Si se
desean desplazar los cursores hasta la siguiente transición de la señal seleccionada se
emplean los botones . Esto es especialmente útil para las medidas de tiempos.

Las mediciones de tiempo se realizan utilizando un segundo cursor, para ello se sitúan el
cursor principal y el secundario sobre las dos transiciones, de la misma u otra señales. Estas
transiciones delimitan el tiempo a medir. El segundo cursor se añade de igual forma que el
primero, mostrándose en trazo discontinuo. El tiempo medido se muestra en la parte inferior
de la pantalla. Finalmente para eliminar estos cursores se emplea el botón .

-36-
Diseño con VHDL
.

Figura 34. Medida de tiempos.

Sobre la figura 34 se puede observar como algunos bits del puerto unidades pasan a valor
desconocido ‘X’ cuando el contador empieza a contar. Esto es debido que sobre una señal o
puerto se está realizando una asignación desde más de una sentencia concurrente. Para
averiguar donde se realiza esa doble asignación se utiliza la ventana dataflow. Para ello, en la
ventana wave, se selecciona unidades y se pulsa , abriendose la ventana dataflow. A
continuación, sobre esta última ventana se selecciona el comando Navigate º View region,
apareciendo un diagrama simbólico con la estructura del diseño (figura 35). En dicha figura se
puede observar como a unidades se realiza una doble asignación concurrente en las líneas
42 y 20 del archivo fuente. Para subsanar el error es necesario eliminar la línea:

unidades <= (others => '0');

Figura 35. Ventana dataflow.

Una ver realizada la corrección se vuelve a simular el diseño, obteniendose los resultados de
la figura 36. Como se puede comprobar, ahora el diseño funciona correctamente.

Figura 36. Resultado de la simulación del contador de décadas.

-37-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Para llevar el cursor a instante en que un elemento de la ventana wave toma un


determinado valor se utiliza, una vez seleccionado el objeto, el comando Edit º
Search, apareciendo el menú de la figura 37, donde se selecciona las opciones de
búsqueda. Para indicar un valor de un objeto vector, éste se pondrá entre comillas
dobles, en binario o en decimal (“0011"ó “3"). En el caso de ser individual se pondrá 0
ó 1.

Figura 37. Opciones de búsqueda.

5.1.PUNTOS DE RUPTURA.

Una de las posibilidades más empleadas en los simuladores son los puntos de ruptura
(breakpoints). ModelSim permite trabajar con dos tipos de puntos de ruptura. El primero
de ellos se fija sobre las líneas de código de la ventana de código fuente (source). Este
tipo de puntos de ruptura se asemeja al empleado por los depuradores de software.
Para activar un punto de ruptura de este tipo basta con pulsar con el ratón sobre la
línea en la que queremos poner el punto de ruptura, apareciendo un punto de color
rojo(figura 38). Para desactivarlo basta con una nueva pulsación. Cuando se ejecuta
la línea de código marcada se detiene la simulación.

Figura 38. Colocación de un punto de ruptura

Los puntos de ruptura también se pueden introducir desde la ventana de texto mediante el
comando bp. El formato empleado es:

bp <nombre_fichero> <número_de_línea>

-38-
Diseño con VHDL
.

El segundo formato, denominado condicional, se asemeja al concepto empleado por un


simulador digital, permitiendo asociarlo a señales, para ello se utiliza el comando when, cuya
sintaxis es:

when [-label <nombre>] {<expresión_condición>} {<acción>}

El parámetro -label asigna el identificador <nombre> al punto de ruptura definido. El parámetro


<expresión_condición> define la condición a evaluar en el punto de ruptura. Cuando esta
expresión es cierta se dispara el punto de ruptura. La sintaxis de esta expresión responde al
siguiente formato:

subexpresión1 operador_lógico subexpresión2 operador_lógico subexpresión3...

Las subexpresiones vienen dadas por operadores relacionales y atributos de detección de


eventos. Los operadores que se pueden utilizar son:

siguientes ejemplos muestran las situaciones admitidas.

! Igualdad. clk = ’1' ó clk==’1'


! Desigualdad Cntdecenas /= “0000"
! Detección de eventos: clk’EVENT

Los operadores de igualdad y desigualdad sólo admiten como segundo parámetro un literal, es
decir no se puede comparar el estado de dos señales. Los operadores lógicos que ligan las
subexpresiones pueden ser el operador and o el operador or. En la expresión condicional se
admite el empleo de paréntesis para establecer la prioridad con que se evalúan las distintas
subexpresiones.

El parámetro <acción> define la secuencia de comandos a del simulador a ejecutar cuando se


dispara el punto de ruptura. Este parámetro es opcional, si no se indica la acción a realizar
consiste en detener la simulación.

Por ejemplo, para simular el contador de décadas se podría añadirlos siguientes el siguientes
comandos:

when -label pto1 { unidades=”001"} {echo "unidades toma el valor 3" stop}
run -all

Así, la simulación se realizará hasta que unidades tome el valor 3 (binario-0011), apareciendo
en la ventana de texto: unidades toma el valor 3

-39-
Electrónica Industrial. Laboratorio de Tecnología Electrónica I.

Para borrar un punto de ruptura de este tipo se emplea el comando nowhen, cuya sintaxis es:

nowhen <identificador>

Por ejemplo para borrar el punto de ruptura definido en el ejemplo se emplea el comando:

nowhen pto1

6. FINALIZAR LA SESIÓN DE SIMULACIÓN.

La simulación de un diseño permite comprobar el correcto funcionamiento del mismo. Desde


que se crean un diseño hasta que se van a realizar varias simulaciones hasta depurar y obtener
el código correcto, por lo que será preciso finalizar la sesión de simulación, modificar el código
fuente, compilar y volver a simular.

Para finalizar la sesión de simulación se emplea el comando:

quit -sim

Notese que el finalizar la sesión de simulación no supone cerrar ModelSim.

El uso de este comando tiene su interés cuando el código VHDL hace uso de ficheros. Una
práctica muy habitual es emplear fichero del cual se toma la secuencia de estímulos (vectores
de test) a aplicar al diseño. Por ejemplo en el caso de sistemas de tratamiento digital de señal
implementados en FPGAs, el bando de pruebas puede obtener los datos a procesar desde un
fichero previamente creado mediante Matlab. De forma similar los resultados del procesamiento
se pueden almacenar en un fichero de salida para su posterior análisis. En este caso, el
simulador abre el ficheros de salida al cargar la unidad de diseño a simular, manteniendo el
control sobre éste por lo que no se puede acceder a su contenido hasta que no finalice la
sesión de simulación. En ese momento el fichero de salida puede abrirse con otra herramienta.

7. METODOLOGÍA DE TRABAJO.

En la descripción realizada a cerca del manejo del simulador se ha hecho especial hincapié en
su uso mediante comandos, prestandose menos interés al uso del interface gráfico.
Aparentemente el uso de comandos puede parecer más complejo debido al esfuerzo inicial que
supone la creación de estos ficheros. Pero hay que tener en cuenta que en raras ocasiones se
obtiene a la primera un diseño totalmente correcto. En tal caso la verificación del diseño
mediante simulación se convierte en un proceso iterativo consistente en modificar el código
fuente, compilarlo, simular y observar los resultados.

A esto hay que añadir que este esfuerzo inicial que supone la creación de los ficheros de script
se ve recompensado por la facilidad de poder reutilizarlos. Así los scripts creados para la
simulación funcional se pueden reutilizar con leves modificaciones en la simulación temporal.
Además en su formato básico no varían demasiado de un diseño a otro, por lo que también se
suelen reutilizar en este caso.

-40-