estructura y tecnologia de computadores 3 - libro problemas
TRANSCRIPT
UNIVERSIDAD NACIONAL DE EDUCACION A DISTANCIA (UNED)
ESCUELA TECNICA SUPERIOR DE INGENIERIA INFORMATICA
Casos prácticos de diseñode circuitos digitales con VHDL
Texto de problemas de la asignatura“Estructura y Tecnología de los Computadores III”
Curso 2007/08
Alfonso UrquíaCarla Martín Villalba
Departamento de Informatica y Automatica, UNED
Juan del Rosal 16, 28040 Madrid, Espana
{aurquia,carla}@dia.uned.es
http://www.euclides.dia.uned.es
Índice
1 Fundamentos 1
1.1. Lenguajes para la descripcion de hardware . . . . . . . . . . . . . . 1
1.2. Ciclo de diseno de los circuitos digitales . . . . . . . . . . . . . . . 4
1.3. Propiedades de los circuitos digitales . . . . . . . . . . . . . . . . . 5
1.4. Simulacion de eventos discretos . . . . . . . . . . . . . . . . . . . . 8
1.5. Test de los circuitos . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.6. Dos simuladores de VHDL’93: VeriBest y ModelSim . . . . . . . . 16
2 Conceptos básicos de VHDL 19
2.1. Definicion de la entidad de diseno . . . . . . . . . . . . . . . . . . . 20
2.2. Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3. Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3.1. Asignaciones concurrentes . . . . . . . . . . . . . . . . . . . 22
2.3.2. Bloque process . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.3.3. Descripcion de la estructura . . . . . . . . . . . . . . . . . . 24
2.3.4. Constantes generic . . . . . . . . . . . . . . . . . . . . . . . 28
2.4. Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.5. Senales, variables y constantes . . . . . . . . . . . . . . . . . . . . 28
2.5.1. Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.5.2. Atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.5.3. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.6. Librerıas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.7. Modelado del retardo . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.7.1. Sentencia wait . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.7.2. Retardos en la asignacion a senales . . . . . . . . . . . . . . 39
2.7.3. Retardo inercial y de transporte . . . . . . . . . . . . . . . 39
2.7.4. Retardo delta . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.7.5. Caso practico . . . . . . . . . . . . . . . . . . . . . . . . . . 41
2.8. Assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.9. Procedimientos y funciones . . . . . . . . . . . . . . . . . . . . . . 44
ii A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3 Casos prácticos de diseño de circuitos combinacionales 47
3.1. Sıntesis de logica combinacional . . . . . . . . . . . . . . . . . . . . 47
3.1.1. Empleo de sentencias concurrentes . . . . . . . . . . . . . . 48
3.1.2. Empleo de bloques process . . . . . . . . . . . . . . . . . . 50
3.2. Funciones logicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.2.1. Modelado de las funciones logicas . . . . . . . . . . . . . . . 50
3.2.2. Programacion del banco de pruebas . . . . . . . . . . . . . 51
3.3. Multiplexor de 4 entradas . . . . . . . . . . . . . . . . . . . . . . . 54
3.3.1. Bloque process, sentencia if . . . . . . . . . . . . . . . . . . 55
3.3.2. Bloque process, sentencias if y case . . . . . . . . . . . . . . 57
3.3.3. Sentencias concurrentes . . . . . . . . . . . . . . . . . . . . 59
3.4. Restador completo de 1 bit . . . . . . . . . . . . . . . . . . . . . . 60
3.4.1. Descripcion del comportamiento . . . . . . . . . . . . . . . 61
3.4.2. Descripcion de la estructura . . . . . . . . . . . . . . . . . . 62
3.4.3. Programacion del banco de pruebas . . . . . . . . . . . . . 65
3.4.4. Banco de pruebas usando un procedimiento . . . . . . . . . 68
3.4.5. Banco de pruebas usando una funcion . . . . . . . . . . . . 70
3.5. Sumador binario paralelo con propagacion de arrastre . . . . . . . 71
3.5.1. Diseno de un sumador completo . . . . . . . . . . . . . . . 72
3.5.2. Banco de pruebas de sumador completo . . . . . . . . . . . 75
3.5.3. Diseno del sumador de 4 bits . . . . . . . . . . . . . . . . . 77
3.6. Bus bidireccional y memorias . . . . . . . . . . . . . . . . . . . . . 77
3.6.1. Memoria de solo lectura . . . . . . . . . . . . . . . . . . . . 78
3.6.2. Memoria de lectura y escritura . . . . . . . . . . . . . . . . 79
3.6.3. Bus bidireccional . . . . . . . . . . . . . . . . . . . . . . . . 80
3.7. Unidad aritmetico logica (ALU) . . . . . . . . . . . . . . . . . . . . 82
3.7.1. Modelado mediante asignacion concurrente . . . . . . . . . 83
3.7.2. Modelado mediante bloque process . . . . . . . . . . . . . . 84
3.7.3. Programacion del banco de pruebas . . . . . . . . . . . . . 85
3.8. Conversor de BCD a binario . . . . . . . . . . . . . . . . . . . . . . 89
3.8.1. Circuito conversor . . . . . . . . . . . . . . . . . . . . . . . 90
3.8.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 91
3.9. Codificador 4:2 con prioridad . . . . . . . . . . . . . . . . . . . . . 93
3.9.1. Diseno del circuito . . . . . . . . . . . . . . . . . . . . . . . 93
3.9.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 94
4 Casos prácticos de diseño de circuitos secuenciales 99
4.1. Diseno de circuitos secuenciales sıncronos . . . . . . . . . . . . . . 99
4.1.1. Circuito detector de secuencias . . . . . . . . . . . . . . . . 100
4.2. Sıntesis de logica secuencial . . . . . . . . . . . . . . . . . . . . . . 102
4.2.1. Sentencias condicionales incompletas . . . . . . . . . . . . . 102
4.2.2. Sentencias condicionales completas . . . . . . . . . . . . . . 103
4.2.3. Retardos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.2.4. Inicializacion . . . . . . . . . . . . . . . . . . . . . . . . . . 103
4.2.5. Bloques process . . . . . . . . . . . . . . . . . . . . . . . . . 104
Indice iii
4.3. Flip-flop JK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
4.3.1. Diseno del flip-flop . . . . . . . . . . . . . . . . . . . . . . . 105
4.3.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 106
4.4. Maquinas de estado finito de Moore . . . . . . . . . . . . . . . . . 109
4.4.1. Diseno de la maquina . . . . . . . . . . . . . . . . . . . . . 110
4.4.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 113
4.4.3. Modelado estructural . . . . . . . . . . . . . . . . . . . . . 117
4.5. Maquinas de estado finito de Mealy . . . . . . . . . . . . . . . . . . 119
4.5.1. Diseno de la maquina . . . . . . . . . . . . . . . . . . . . . 119
4.5.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 126
4.6. Descripcion VHDL de alto nivel . . . . . . . . . . . . . . . . . . . . 130
4.6.1. Circuito detector de secuencia . . . . . . . . . . . . . . . . . 130
APENDICES 133
A VeriBest VB99.0 133
A.1. Instalacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
A.2. Circuito digital ejemplo: buffer triestado . . . . . . . . . . . . . . . 134
A.2.1. Modelo VHDL del buffer triestado . . . . . . . . . . . . . . 134
A.2.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 135
A.3. Edicion y compilacion de un modelo . . . . . . . . . . . . . . . . . 136
A.3.1. Arranque del simulador VeriBest VHDL . . . . . . . . . . . 136
A.3.2. Creacion de un espacio de trabajo . . . . . . . . . . . . . . 136
A.3.3. Edicion de un fichero . . . . . . . . . . . . . . . . . . . . . . 137
A.3.4. Anadir un fichero al espacio de trabajo . . . . . . . . . . . . 137
A.3.5. Compilacion de un fichero . . . . . . . . . . . . . . . . . . . 138
A.3.6. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 140
A.4. Simulacion y visualizacion de los resultados . . . . . . . . . . . . . 140
A.4.1. Establecer las condiciones de la simulacion . . . . . . . . . 140
A.4.2. Activacion del simulador . . . . . . . . . . . . . . . . . . . . 141
A.4.3. Simulacion y visualizacion de resultados . . . . . . . . . . . 142
A.5. Depurado usando el debugger . . . . . . . . . . . . . . . . . . . . . 144
B ModelSim PE Student Edition 147
B.1. Instalacion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
B.2. Circuito digital ejemplo: buffer triestado . . . . . . . . . . . . . . . 148
B.2.1. Modelo VHDL del buffer triestado . . . . . . . . . . . . . . 148
B.2.2. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 149
B.3. Edicion y compilacion de un modelo . . . . . . . . . . . . . . . . . 150
B.3.1. Arranque del simulador . . . . . . . . . . . . . . . . . . . . 150
B.3.2. Creacion de un proyecto . . . . . . . . . . . . . . . . . . . . 151
B.3.3. Anadir ficheros al proyecto . . . . . . . . . . . . . . . . . . 152
B.3.4. Compilacion de un fichero . . . . . . . . . . . . . . . . . . . 156
B.3.5. Banco de pruebas . . . . . . . . . . . . . . . . . . . . . . . 157
B.4. Simulacion y visualizacion de los resultados . . . . . . . . . . . . . 160
iv A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
B.4.1. Activacion del modo simulacion . . . . . . . . . . . . . . . . 160
B.4.2. Visualizacion de los resultados . . . . . . . . . . . . . . . . 161
B.4.3. Ejecucion de la simulacion . . . . . . . . . . . . . . . . . . . 162
B.4.4. Insercion de puntos de ruptura . . . . . . . . . . . . . . . . 163
Índice alfabético 167
Bibliografía 169
1Fundamentos
Objetivos. Una vez estudiado el contenido del tema, deberıa saber:
– Discutir la finalidad de los lenguajes para la descripcion del hardware (HDL) y
algunas de las principales ventajas que presenta su uso.
– Discutir el ciclo de diseno del hardware digital y el papel que desempenan en
el ciclo de diseno los HDL.
– Discutir los conceptos fundamentales de la simulacion de eventos discretos,
en particular la gestion del reloj de la simulacion y del calendario de eventos.
– Realizar, con “lapiz y papel”, la simulacion de eventos discretos de circuitos
digitales, tal como se muestra en el Caso Practico de la Seccion 1.4.
– Discutir las siguientes propiedades de los circuitos digitales: el retardo de los
dispositivos, su ejecucion concurrente, la marginalidad en el diseno y la fortaleza
de las senales.
– Discutir que son los arboles de buffers y cual es su finalidad.
– Discutir el proposito y los fundamentos del test en diseno y manufactura, ası
como los conceptos: modelo de fallos, cobertura del test y calidad del test.
– Discutir la utilidad y composicion de los bancos de pruebas.
– Instalar en su propio ordenador y realizar las operaciones basicas de manejo de
algun entorno de simulacion de VHDL’93, tal como ModelSim (preferible) o
VeriBest. Estas operaciones basicas incluyen al menos: edicion de modelos
y depurado usando el debugger, simulacion y visualizacion de los resultados.
1.1 Lenguajes para la descripción de hardware
Los sistemas digitales se han ido haciendo mas y mas complejos durante las
pasadas decadas. Este incremento en la complejidad responde, a grandes rasgos,
a la Ley de Moore, que establece que el avance tecnologico posibilita que cada
aproximadamente 18 meses se doble el numero de transistores que es posible alojar
en un circuito integrado.
2 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
De esta forma, en la decada de 1970 un circuito integrado tıpico contenıa
decenas de miles de transistores. En la decada de 1980, la capacidad aumento a
cientos de miles de transistores, y en la decada de 1990 fue del orden de decenas
de millones. En la decada de 2000, la capacidad de los circuitos integrados es del
orden de miles de millones de transistores.
En los anos 70, cuando se fabricaba un circuito integrado, se documentaba
su funcionamiento empleando una combinacion de esquematicos (representacion
grafica de los componentes del circuito), diagramas de transicion de estados y
lenguaje natural (por ejemplo, ingles). Esta documentacion podıa consistir en
varios cientos de paginas. Los ingenieros, que compraban el circuito integrado para
usarlo en sus propios disenos, tenıan que leer esta documentacion para entender
el funcionamiento del circuito integrado. Sin embargo, leer cientos de paginas
no era tarea facil. Ademas, en ocasiones la documentacion contenıa errores o
ambiguedades. La consecuencia de ello era que frecuentemente los ingenieros
tenıan problemas para emplear los circuitos integrados en el desarrollo de sus
propios sistemas.
Debido a esta situacion, el Departamento de Defensa de EE.UU. busco un
procedimiento mediante el cual los fabricantes de circuitos integrados pudieran es-
pecificar de forma precisa el funcionamiento de los circuitos. Con esta motivacion,
el Departamento de Defensa de EE.UU. inicio el desarrollo de un lenguaje para la
descripcion del hardware, para lo cual establecio un grupo de trabajo compuesto
por expertos de varias disciplinas, pertenecientes a diferentes companıas.
Un lenguaje para la descripcion del hardware o HDL (siglas que provienen
del ingles: Hardware Description Language) es un lenguaje, legible tanto por
las maquinas como por los seres humanos, ideado para permitir la descripcion
del hardware. Un HDL describe de forma precisa y rigurosa el funcionamiento,
pudiendo ser simulado en un ordenador con el fin de reproducir exactamente el
funcionamiento del circuito integrado. La simulacion por ordenador permite ob-
tener el valor de las senales de salida del circuito integrado para una determinada
secuencia de senales de entrada.
El HDL que el Departamento de Defensa de EE.UU. creo en los anos 80
se llamo VHDL. Las siglas VHDL provienen de VHSIC Hardware Description
Language. VHSIC es un acronimo de Very High Speed Integrated Circuit, que
fue el nombre del proyecto llevado a cabo por el Departamento de Defensa de
EE.UU.
La sintaxis de VHDL es muy similar a la del lenguaje de programacion ADA.
En 1987, el Institute of Electrical and Electronics Engineers (IEEE) adopto VHDL
como el estandar numero 1076. El establecimiento de un estandar del lenguaje
tiene una ventaja fundamental: las companıas desarrolladoras de software de
simulacion tienen una definicion claramente establecida del lenguaje al que deben
dar soporte.
Capıtulo 1 Fundamentos 3
Ventajas de los HDL
En la actualidad, la casi totalidad de los disenadores de circuitos digitales de cierta
complejidad usan para realizar sus disenos lenguajes para la descripcion del hard-
ware. El empleo de HDL presenta ventajas respecto al empleo de descripciones
basadas en esquematicos. Algunas de ellas son las siguientes:
1. Puesto que una descripcion HDL es simplemente un fichero de texto, es
mucho mas portable que un diseno esquematico, que debe ser visualizado
y editado empleando la herramienta grafica especıfica del entorno de CAD
(Computer-Aided Design - Diseno asistido por ordenador) con el que se ha
creado.
2. Una descripcion esquematica unicamente describe el diseno de manera es-
tructural, mostrando los modulos y la conexion entre ellos. Por el contrario,
la descripcion del circuito usando un HDL puede realizarse bien mostrando
la estructura, o bien describiendo el comportamiento. Es decir, los HDL
permiten describir el comportamiento que se desea que tenga el circuito,
sin hacer ninguna referencia a su estructura. Las herramientas de sıntesis
permiten generar automaticamente la estructura del circuito logico a partir
de la descripcion de su comportamiento.
3. El mismo HDL que se ha usado para la descripcion del circuito, puede
emplearse para describir los vectores de test y los resultados esperados
del test. Los vectores de test son los valores de las senales aplicadas a los
pines de entrada del circuito con la finalidad de probar si el funcionamiento
del circuito es correcto. Ası pues, pueden realizarse los programas de test
(vectores de test e instantes en los cuales son aplicados) del circuito a medida
que se disena el propio circuito, pudiendose con ello ir realizando diferentes
pruebas a medida que se avanza en el diseno. Como ventajas anadidas, la
descripcion de los programas de test usando HDL es altamente portable y
repetible.
HDL más ampliamente usados
En la actualidad, los HDL mas ampliamente usados son Verilog HDL y VHDL.
Ambos son lenguajes estandar de IEEE para el modelado y simulacion de hard-
ware.
– Verilog se creo, a principios de los anos 80, como un lenguaje propiedad de
la companıa Philip Moorby, companıa que anos mas tarde fue adquirida por
Cadence Design Systems. Posteriormente, Verilog se hizo de dominio publi-
co y se promovio como un estandar de IEEE en el ano 1995, denominado
IEEE 1364.
– Como se ha explicado anteriormente, VHDL fue desarrollado en 1983
por el Departamento de Defensa de los EE.UU. con la finalidad de servir
como lenguaje estandar para la descripcion de hardware. En el ano 1987
4 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
se convirtio en un estandar de IEEE (IEEE 1067-1987). Posteriormente, se
incorporaron mejoras al lenguaje que dieron lugar a dos actualizaciones del
estandar: la primera en 1993 (IEEE 1076-1993) y la segunda en 2001 (IEEE
1076-2001).
A principios del ano 2000 se desarrollo otro HDL denominado SystemC, el
cual consiste en un conjunto de librerıas en C++. SystemC se convirtio en el
estandar 1666 de IEEE en el ano 2005.
1.2 Ciclo de diseño de los circuitos digitales
El empleo de HDL es practica habitual en las diferentes fases del ciclo de diseno
de circuitos digitales. En la Figura 1.1 se muestra el ciclo de actividades que
se realizan durante el ciclo de diseno e implementacion de circuitos digitales de
relativa complejidad.
En primer lugar, el disenador debe establecer las especificaciones del diseno, en
terminos de que se espera que haga el circuito y que restricciones debe satisfacer
(frecuencia de reloj, retardos, tamano, etc.).
A continuacion, el disenador debe crear un diseno de alto nivel del circuito,
para lo cual puede emplear un lenguaje para la descripcion de hardware (HDL),
por ejemplo VHDL o Verilog. Seguidamente, debe desarrollar un conjunto de
programas de test (usando tambien VHDL o Verilog) y, si es posible, usar estos
programas para testear el diseno de alto nivel, usando para ello una herramienta
de simulacion (verificacion funcional). En funcion de los resultados de la simula-
cion de los tests, puede ser preciso modificar el diseno de alto nivel, repitiendose
los pasos anteriores tantas veces como sea preciso.
Una vez el diseno de alto nivel funciona adecuadamente, debe traducirse al
nivel de puertas logicas o de transistores. Este proceso se denomina sıntesis. Sın-
tesis es la generacion automatica del diseno del circuito a partir de la descripcion
de su comportamiento. El resultado obtenido de la sıntesis, denominado netlist,
es una descripcion de todas las conexiones y componentes que deben componer
el circuito.
La descripcion a nivel de puertas o transistores obtenida a partir de una
descripcion en HDL puede diferir significativamente, dependiendo de la forma en
que se ha programado el modelo en HDL y de la herramienta de sıntesis empleada.
Las herramientas de sıntesis proporcionan numerosas opciones que permiten al
disenador especificar como debe realizarse. En particular, permiten especificar el
nivel de esfuerzo a emplear por la herramienta en la optimizacion automatica del
circuito, tanto en lo que respecta a la reduccion del area del circuito como en lo
que respecta a sus prestaciones. Asimismo, las herramientas de sıntesis permiten
especificar que modulos del circuito no deben ser optimizados.
El diseno a nivel de puertas o transistores debe ser vuelto a testear mediante
simulacion (verificacion de tiempos), usando, si es posible, el mismo conjunto
de tests que se realizaron sobre el diseno de alto nivel. El objetivo es estudiar
si el diseno se comporta como debe y si satisface todas las restricciones que se
Capıtulo 1 Fundamentos 5
� �� � � � � � � � � � � � � � � �� �
� � �� � � � �� � � � � � �
� � �� ��� � � � � � ��
� �� � � � � � � � � � � � � � � � � � � � � � � � � �
� � �� � � � � � � � � � � �� ��� �� � � � �� � � ��� �
��� � � � � � � � � � � � � � � � � � � � � � �� � � �
�� � � �� � � � � � � �� � � ! � � �" ! � �� #$
� � �� � � � � � �� �� � � � �
Figura 1.1: Ciclo de diseno del hardware digital.
impusieron en la fase de especificacion. Si se detecta un problema a este nivel,
debe volverse al correspondiente paso del ciclo de diseno.
Una vez el diseno ha superado estos tests, puede implementarse usando PLD
(Programmable Logic Device), FPGA (Field-Programmable Gate Array), ASIC
(Application-Specific Integrated Circuit), etc. Se emplean herramientas software
para fabricar (en el caso de los ASIC) o programar (en el caso de los FPGA) el
circuito integrado a partir de la netlist.
Una vez implementado, el circuito integrado puede ser testado con ayuda de
un generador de patrones (para generar los vectores de test) y un analizador
logico u osciloscopio (para medir las salidas).
1.3 Propiedades de los circuitos digitales
Los circuitos digitales reales tienen algunas caracterısticas importantes que afec-
tan a la manera en que deben ser modelados y disenados. Estas caracterısticas
son debidas tanto a los transistores que componen las puertas logicas como a las
conexiones entre ellos. Entre las mas importantes estan las siguientes.
6 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Retardo de los dispositivos
En los sistemas fısicos suelen considerarse dos tipos de retardos: el retardo
inercial y el retardo puro o de transporte. Se va a emplear un motor electrico
como ejemplo para ilustrar la diferencia entre ambos tipos de retardo.
Cuando se enciende el motor, este empieza a girar y su velocidad aumenta
hasta que alcanza la velocidad final. Este proceso puede llevar varios segundos,
siendo debido principalmente este retardo a la inercia del rotor del motor. Si se
apaga el motor antes de que este alcance la velocidad final, la velocidad del motor
disminuye inmediatamente. Esto no sucederıa en el caso de un retardo puro.
Como ejemplo de retardo puro, consideremos que el motor esta en una nave
espacial rumbo a Jupiter. Los comandos para encender y apagar el motor se envıan
desde la tierra y tardan 10 minutos en llegar a la nave. Supongamos que se envıa
un comando para encender el motor y pasados dos minutos se envıa otro comando
para apagarlo. El comando para apagar el motor llegarıa 2 minutos despues que el
comando para encenderlo, causando que el motor estuviese encendido durante dos
minutos. La senal recibida es exactamente igual que la enviada pero desplazada
10 minutos en el tiempo. Los retardos puros pueden representarse por simples
desplazamientos en el tiempo de la senal, ya que la senal en sı misma no se
modifica.
El retardo inercial es adecuado para modelar los retardos a traves de dispo-
sitivos tales como los transistores y las puertas logicas. Un cambio en la entrada
de un dispositivo se ha de mantener estable durante cierto tiempo para que este
valor se propague a su salida. Las puertas actuan ası como filtros paso baja.
Consideremos un inversor con un retardo de 2 ns. El inversor necesita que la
entrada se mantenga estable durante al menos 2 ns para que se produzca un
cambio en su salida. Por tanto, un pulso de 1 ns de duracion no provoca cambios
en su salida, pero si los provoca un pulso de 5 ns. Si la primera transicion del pulso
se recibe en el instante 100 ns, la respuesta de la puerta comienza a transmitirse
en el instante 102 ns. Por otro lado, el retardo de transporte (o puro) es adecuado
para modelar retardos a traves de dispositivos con poca inercia, tales como las
lıneas de metal construidas en el chip para conectar los dispositivos.
Ejecución concurrente
Los modulos logicos se ejecutan concurrentemente. Cuando cambia el valor de
una senal de entrada a varios modulos, todos estos modulos deben ser ejecutados
concurrentemente. Ası pues, los HDL deben ser capaces de describir de manera
precisa este comportamiento concurrente y el simulador debe ser capaz de si-
mularlo. La metodologıa aplicada para ello por el simulador es la simulacion de
eventos discretos.
Diseños marginales
Los retardos de los dispositivos dependen de la condiciones de fabricacion del chip.
En general, existen variaciones en el valor de los retardos de los chips fabricados
Capıtulo 1 Fundamentos 7
en diferentes obleas, e incluso existen variaciones entre los chips fabricados en
posiciones distantes dentro de una misma oblea.
Por este motivo, no es buena idea disenar un circuito cuyo funcionamiento
dependa de que los retardos tomen un determinado valor o que su magnitud
sea mınima. Este tipo de circuitos puede funcionar correctamente cuando son
simulados, ya que las senales simuladas llegan a los modulos en un determinado
orden, que viene determinado por los valores de los retardos contenidos en el
modelo. Sin embargo, si el orden de llegada de los cambios en las senales depende
del valor de los retardos, y los retardos simulados no se corresponden con los
existentes en el diseno fısico, entonces ese diseno producira chips que no funcionen,
o que funcionen solo una parte del tiempo.
Fortaleza de las señales
Las senales de los circuitos digitales reales poseen una determinada “fortaleza”,
que determina en que medida las transiciones en el valor de la senal son abruptas
(y, por tanto, los retardos debidos a esa senal), y el numero y tipo de entradas a
modulos que pueden ser conectados a esa senal.
Esta caracterıstica de las senales, que puede ser modelada en VHDL y en
Verilog, viene determinada por los niveles de tension del ‘0’ y del ‘1’ logicos (por
ejemplo, para un ‘1’ logico, en que medida esta el voltaje de la senal proximo al
voltaje de la alimentacion), y por la cantidad de corriente que puede proporcionar
y aceptar el dispositivo que genera la senal.
En un circuito digital tıpico, la transferencia de un valor logico desde un pin
de salida de un modulo, a varios pines de entrada de otros modulos, precisa de la
transferencia de carga electrica hacia los pines de entrada (en el caso de ‘1’ logico)
o hacia el pin de salida (en el caso de ‘0’ logico). El pin de salida debe tener la
capacidad de hacer de “fuente” y de “sumidero” de toda la corriente necesaria.
Desde el punto de vista practico, esto implica que la salida de un modulo
puede ser conectada como maximo a un determinado numero de entradas de
otros modulos. En aquellos casos en que la senal deba conectarse a un numero
de modulos superior a este numero maximo, entonces debe emplearse un arbol de
buffers. En la Figura 1.2 se muestra un arbol de buffers que lleva una senal (out)
a 16 modulos (in 0, ..., in 15), de tal forma que la salida de los buffers se conecta
unicamente a 4 entradas.
El uso del arbol de buffers tiene un beneficio anadido: igualar los retardos
de las senales de entrada a todos los modulos, ya que el arbol de buffers esta
disenado de modo que la longitud de las lıneas de todas sus ramas sea la misma.
Este tipo de arbol de buffers se emplea para llevar la senal de reloj a los flip-flops
en los circuitos secuenciales sıncronos, en los cuales es importante que la senal de
reloj llegue a todos los flip-flops aproximadamente en el mismo instante.
8 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 1.2: Arbol de buffers para llevar una senal a 16 modulos.
1.4 Simulación de eventos discretos
A la hora de escribir codigo en cualquier lenguaje para la descripcion de hardware,
resulta util saber de que manera se realizara la simulacion de ese codigo. La
mayorıa de las herramientas de simulacion de HDL emplean una metodologıa
denominada simulacion de eventos discretos. En la simulacion de eventos discretos
se lleva una lista global de eventos ordenados en el tiempo, que se denomina
calendario de eventos. Los eventos se representan en el calendario de eventos por
el siguiente par de valores: nuevo valor de la senal e instante de tiempo en que
esta planificado que se realice esta asignacion. Los eventos estan ordenados de
menor a mayor instante de ejecucion en el calendario.
A continuacion se describe el algoritmo de la simulacion, que consta de los
siguientes pasos:
Paso 1. En el instante de inicio de la simulacion, se activa el evento “Inicio de
la Simulacion”. Como parte de las acciones asociadas a la ejecucion de este
evento, se pone el reloj de la simulacion a cero y se registran los nuevos
eventos en el calendario de eventos.
Paso 2. Se extrae el primer evento del calendario.
Paso 3. Se actualiza el reloj de la simulacion al instante de ejecucion del evento.
Capıtulo 1 Fundamentos 9
Paso 4. Se ejecuta el evento y, si procede, se actualiza el calendario de eventos.
Paso 5. Se comprueba si existen mas eventos en el calendario de eventos. Si
existen mas eventos se vuelve al paso 1. En caso contrario, se avanza al
paso 6.
Paso 6. Fin de la simulacion.
El anterior algoritmo de la simulacion no describe como se actualiza el ca-
lendario de eventos. Los pasos a seguir para actualizar el calendario de eventos
dependen del tipo de retardo del evento. Por defecto, se considera que los dispo-
sitivos tienen retardo inercial. El tratamiento de un evento sin retardo sobre una
senal se reduce al caso de un evento con retardo (ya sea inercial o de trasporte)
haciendo el valor del retardo cero.
A continuacion se describen los pasos a seguir para actualizar el calendario
de eventos cuando en el nuevo evento sobre la senal existe un retardo inercial.
Vamos a considerar que la senal sobre la que se produce el evento se denomina A,
el nuevo valor de la senal es Anew, el valor del retardo inercial es ret y el instante
actual de simulacion es tactual. Para actualizar el calendario de eventos hay que
seguir los siguientes pasos:
1. Se borran aquellos eventos sobre A cuyo instante de ejecucion sea igual o
mayor que tactual + ret.
2. Se insertan los nuevos eventos en el calendario de eventos.
3. Todos los antiguos eventos sobre A cuya ejecucion este planificada que suce-
da en un instante de tiempo comprendido en el intervalo (tactual, tactual + ret)
y asignen a A un valor diferente de Anew se borran.
Si el evento sobre la senal A tuviese retardo de transporte (que denominamos
rettransp) en lugar de un retardo inercial habrıa que dar los siguientes pasos para
actualizar el calendario de eventos:
1. Se borran todos los eventos sobre A existentes en el calendario de eventos
cuyo instante de ejecucion sea igual o mayor tactual + rettransp.
2. Se insertan los nuevos eventos en el calendario de eventos.
Caso práctico
Supongamos que se ha descrito el circuito mostrado en la Figura 1.3 usando un
HDL. La puerta NAND tiene un retardo de 1 ns y la puerta OR de 2 ns. Las
dos entradas, x1 y x2, tienen el valor ‘1’ en el instante 0 ns. Las dos siguientes
asignaciones describen, respectivamente, el comportamiento de la salida de la
puerta NAND (s) y de la puerta OR (y) del circuito digital:
s ← x1 nand x2 con retraso 1 ns (1.1)
y ← s or x2 con retraso 2 ns (1.2)
10 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
s
Figura 1.3: Circuito ejemplo.
A continuacion se describen los pasos en la simulacion de dicho circuito:
Paso 1. En el instante inicial el reloj de la simulacion vale 0 ns y se asigna nuevo
valor a las senales x1 y x2. Debido a ello, se ejecutan las asignaciones que
tienen en su lado derecho x1 o x2. En este caso, se ejecutan las asignaciones
correspondientes a la puerta NAND (asignacion 1.1) y a la puerta OR
(asignacion 1.2). Se producen dos nuevos eventos, denominados E0 y E1:
– El evento E0, planificado para el instante 1 ns, se debe a la ejecucion
de la asignacion de la puerta NAND. En este evento se asigna a s el
valor ‘0’.
– El evento E1 se debe a la ejecucion de la asignacion de la puerta OR.
En este evento se asigna a y el valor ‘1’ en el instante 2 ns. Observa que
la asignacion y ← x1 or 1 es equivalente a y ← 1 independientemente
del valor de x1. Si la senal x2 valiese ‘0’ en lugar de ‘1’ el valor de y
serıa indefinido hasta que s tuviese un valor definido.
Ademas, se incorpora al calendario de eventos un evento, llamado E2,
programado para el instante 5 ns, y cuya accion es: x2 ← 0. Los valores
de las senales y el calendario de eventos en el instante 0 ns se presentan en
las tablas siguientes:
Senal Valor
x1 ‘1’
x2 ‘1’
s ‘U’ (valor indefinido)
y ‘U’ (valor indefinido)
Calendario de eventos
E0 1 ns s← 0
E1 2 ns y ← 1
E2 5 ns x2 ← 0
Paso 2. El simulador extrae el evento E0 del calendario y lo ejecuta. El valor de
la senal s pasa a ser cero y el reloj de la simulacion vale 1 ns . El cambio en la
senal s produce que se ejecute la asignacion 1.2 y se genere un nuevo evento
(E3). A continuacion se muestran los valores de las senales y el calendario
de eventos en el instante 1 ns.
Senal Valor
x1 ’1’
x2 ’1’
s ’0’
y ’U’ (valor indefinido)
Calendario de eventos
E1 2 ns y ← 1
E3 3 ns y ← 1
E2 5 ns x2 ← 0
Capıtulo 1 Fundamentos 11
Paso 3. El simulador extrae el evento E1 del calendario y lo ejecuta. Entonces,
el valor de la senal y pasa a ser uno y el reloj de la simulacion vale 2 ns .
El cambio en la senal y no genera ningun evento. Los valores de las senales
y el calendario de eventos en el instante 2 ns se muestran a continuacion.
Senal Valor
x1 ’1’
x2 ’1’
s ’0’
y ’1’
Calendario de eventos
E3 3 ns y ← 1
E2 5 ns x2 ← 0
Paso 4. El simulador extrae el evento E3 del calendario y lo ejecuta. El reloj
de la simulacion vale 3 ns y los valores de las senales y el contenido del
calendario de eventos son los siguientes:
Senal Valor
x1 ’1’
x2 ’1’
s ’0’
y ’1’
Calendario de eventos
E2 5 ns x2 ← 0
Paso 5. El simulador extrae el evento E2 del calendario y lo ejecuta. Como
consecuencia, el valor de la senal x2 pasa a ser cero y el reloj de la simulacion
vale 5 ns . Como resultado, se ejecutan las asignaciones 1.1 y 1.2 y se
generan dos eventos (E4 y E5). A continuacion se muestran los valores
de las senales y el calendario de eventos en el instante 5 ns.
Senal Valor
x1 ’1’
x2 ’0’
s ’0’
y ’1’
Calendario de eventos
E4 6 ns s← 1
E5 7 ns y ← 0
Paso 6. El simulador extrae el evento E4 del calendario y lo ejecuta. El valor
de la senal s pasa ası a ser uno y el reloj de la simulacion pasa a valer
6 ns . Cuando esto sucede, se ejecuta la asignacion 1.2. El evento E5 se
borra del calendario de eventos ya que E5 y el nuevo evento (E6) afectan
a la misma senal asignandole valores distintos y el lapsus de tiempo entre
ambos eventos es inferior a 2 ns. Los valores de las senales y el calendario
de eventos en el instante 6 ns se muestran a continuacion.
Senal Valor
x1 ’1’
x2 ’0’
s ’1’
y ’1’
Calendario de eventos
E6 8 ns y ← 1
12 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 1.4: Cronomagrama de las senales x1, x2, y y s del circuito ejemplo.
Paso 7. En el instante 8 ns se ejecuta el evento E6, que no genera otros eventos.
Puesto que el calendario de eventos se encuentra vacıo, el simulador finaliza
la ejecucion. El cronomagrama de las senales x1, x2, y y s se muestra en la
Figura 1.4.
1.5 Test de los circuitos
El test juega un papel muy importante en el diseno de circuitos integrados. No solo
se emplea para verificar el correcto funcionamiento del circuito ya completamente
disenado, sino que tambien es una ayuda esencial para el disenador durante la
fase de diseno del circuito.
Finalmente, el test se emplea en manufactura, para determinar que chips
han resultado defectuosos o tienen limitadas prestaciones. Por ejemplo, puede
emplearse para separar los chips que funcionan correctamente a alta velocidad,
de los que solo funcionan a baja velocidad (cada tipo es vendido a diferente
precio). Si el diseno se ha realizado correctamente, los chips defectuosos en los
test de manufactura se deben a problemas en los procesos de fabricacion o de
encapsulado. El test realizado en manufactura tiene un impacto directo sobre el
rendimiento (porcentaje de chips fabricados que no son defectuosos), el cual tiene
un impacto directo sobre los beneficios de la companıa fabricante de los chips.
Esencialmente, el test consiste en fijar valores en todas las entradas del circuito
y observar que valores se obtienen en sus salidas. A cada asignacion de valores a
todas las entradas del circuito se le llama un vector de test. El programa de test
consiste en un conjunto de vectores de test, que se aplican sobre el dispositivo en
una determinada secuencia.
Test en manufactura
Un objetivo fundamental del test en manufactura es detectar problemas en el
proceso de fabricacion. Las causas de mal funcionamiento de los chips mas comun-
mente observadas en la practica son:
– Abiertos. Conexiones entre los dispositivos que se encuentran abiertas
debido a algun problema, por ejemplo, debido a la rotura de la lınea de
metal que establece la conexion.
Capıtulo 1 Fundamentos 13
– Cortos. Conexiones que se han establecido entre diferentes dispositivos,
cuando no deberıan haberse producido.
– Acoplos. Valores logicos en una parte del circuito que inadvertidamente
cambian el valor logico en otra parte del circuito.
Modelar estos diferentes tipos de defectos en el circuito es extremadamente
difıcil. Por ello, se han desarrollado diferentes modelos simplificados de fallos.
Uno de estos modelos de fallo es considerar que el defecto de fabricacion hace
que una de las conexiones internas del circuito permanezca siempre a 1, o que
permanezca siempre a 0.
En un circuito tıpico, este tipo de fallos da lugar a un numero muy elevado de
patrones de fallo. Un patron de fallo es una determinada seleccion de conexiones
que se encuentran permanentemente a 1 y de conexiones que se encuentran
permanentemente a 0.
Se da la circunstancia de que varios patrones de fallo pueden desembocar en
el mismo comportamiento del circuito. Por ejemplo, si cualquiera de las entradas
de una puerta NAND se encuentra siempre a 0, el circuito se comporta de la
misma manera que si la salida del circuito se encontrara siempre a 1.
Incluso tomando en consideracion que existen patrones de fallo que dan lugar
a un comportamiento equivalente (defectuoso) del circuito, el numero de patrones
de fallo esencialmente distintos es extremadamente grande.
Por ello, se ha desarrollado un modelo simplificado a partir del anterior.
Consiste en suponer que en el circuito hay una unica conexion que se encuentra
permanentemente a 1, o permanentemente a 0. Aunque este modelo de fallos
pudiera considerarse muy restrictivo, ha demostrado ser eficaz.
Una vez se adopta un determinado modelo de fallos, el siguiente paso es crear
un conjunto de vectores de test que permita detectar ese tipo de fallos. Para que
se produzca la deteccion del fallo, es preciso que la salida del circuito, en caso de
estarse produciendo el fallo, sea diferente de la salida de un circuito que funcione
correctamente. En este caso, se dice que el fallo se encuentra cubierto por el vector
de test. Por supuesto, habra otros tipos de fallos que daran lugar, para ese vector
de test, a las mismas salidas que un circuito que funcione correctamente. Se dice
entonces que el vector de test no cubre esos otros fallos.
Segun se van usando mas y mas vectores de test, el porcentaje de fallos
potenciales (para un determinado modelo de fallo) que son cubiertos se aproxima
al 100 %. Dado un conjunto de vectores de test, la cobertura de fallos de ese
conjunto de vectores de test (dado un modelo especıfico de fallos) corresponde
con el porcentaje de fallos cubiertos.
El test de los circuitos secuenciales es mas complicado, ya que las salidas del
circuito dependen no solo de las entradas, sino tambien de su estado. Por tanto,
en este tipo de circuitos es preciso poder fijar los valores de todos los flip-flops a
voluntad. Esto puede hacerse de las dos maneras siguientes:
1. Mediante una secuencia de inicializacion (secuencia de valores de las entra-
das del circuito), se lleva el circuito al estado deseado. A continuacion, se
aplica el vector de test para probar el circuito en ese estado.
14 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Mediante este procedimiento, un unico test consiste en una secuencia de
inicializacion, seguida de otro vector de test. Este procedimiento conduce
a usar un gran numero de vectores de test, muchos de los cuales son
simplemente secuencias de inicializacion. Ademas, en algunos casos puede
no ser posible fijar todos los flip-flops a los valores deseados.
2. El segundo metodo consiste el usar en el diseno scan flip-flops, que son flip-
flops cuyo valor puede ser cargado desde las entradas al circuito (mientras
se realiza el test), o bien pueden ser usados del mismo modo que un flip-flop
sin modificar (durante el modo normal de funcionamiento del circuito). Los
scan flip-flops pueden construirse insertando multiplexores en la entrada D
de los flip-flops.
En el test en manufactura, la calidad de un conjunto de vectores de test
(denominado programa de test) se mide por medio de la cobertura de fallos
del programa de test (supuesto un determinado modelo de fallo) y del tiempo
necesario para aplicar todos los vectores de test al circuito, que es directamente
proporcional al numero de vectores de test.
Cuanto mayor sea la cobertura de fallos, menor sera el numero de chips
defectuosos que superaran con exito el proceso de inspeccion. Cuanto menor sea
el numero de vectores de test, menor sera el tiempo necesario para ejecutar el
programa de test, con lo cual podran testearse mayor numero de chips por unidad
de tiempo.
Test funcional
El test funcional se emplea en todas las etapas del proceso de diseno del circuito.
Su objetivo es verificar que el circuito realiza todas las operaciones como debiera.
En los disenos grandes, que normalmente se disenan de manera jerarquica,
todos los subcircuitos de bajo nivel deben ser comprobados funcionalmente, usan-
do programas de test especıficos para cada uno, antes de ser incluidos en los
subcircuitos de mas alto nivel.
Aunque todos los subcircuitos sean comprobados por separado, el subcircuito
obtenido de la composicion de todos ellos debe tambien ser comprobado, usandose
para ello su propio programa de test.
A continuacion, una vez se implementa el circuito usando alguna plataforma
hardware (ASIC, FPGA, etc.), debe volver a ser testeado de nuevo. Si es posible,
debe emplearse para testear el prototipo hardware el mismo conjunto de tests que
se ha usado en la fase de simulacion. Habitualmente, el primer prototipo hardware
contiene errores. La comparacion de los resultados del test, con los resultados de
las simulaciones para esos mismos tests, puede ayudar a identificar errores de
diseno y de fabricacion.
Programas de test funcional
Un metodo para testear la funcionalidad de un circuito es probar todos los posibles
vectores de entrada. Sin embargo, en algunos circuitos esto no es posible, bien
Capıtulo 1 Fundamentos 15
porque el numero de posibles vectores es muy grande, o bien porque algunas
combinaciones de valores de las entradas no son validas para ese determinado
circuito. Ademas, algunas funciones requieren de una determinada secuencia de
vectores de entrada.
En conclusion, el programa de test es algo que depende del circuito. Sin
embargo, en general se sigue el criterio de probar todos los posibles vectores
de entrada, siempre que esto sea posible.
Si el numero de posibles vectores de entrada es muy grande (se tardarıa
meses o anos en probarlos todos), existen varios metodos heurısticos que pueden
aplicarse para reducir el numero de vectores de entrada.
1. Puede emplearse el conocimiento sobre el funcionamiento de circuito para
descartar aquellos vectores de entrada que no tienen ninguna funcion en el
circuito, o que nunca ocurriran en la practica.
2. El circuito puede dividirse en varios subcircuitos, que son testeados ex-
haustivamente (usando todas las combinaciones de los vectores de entrada
para cada subcircuito). A continuacion, el circuito completo puede testaerse
usando un conjunto no exhaustivo de vectores de entrada, simplemente para
comprobar que los subcircuitos han sido integrados adecuadamente.
3. Se escoge un conjunto representativo de vectores de entrada, con el fin de
ejercitar el circuito bajo condiciones normales de funcionamiento y bajo
condiciones extremas.
Al testear un circuito, es deseable poder comparar de manera automatica las
salidas del circuito con las correspondientes salidas que se obtendrıan si el circuito
funcionara correctamente. Esto puede hacerse de varias maneras.
1. Una forma es almacenar en un fichero las salidas de un circuito que funcione
correctamente, y compararlas con las salidas obtenidas.
2. Otro procedimiento consiste en calcular la salida esperada del circuito usan-
do un metodo diferente al empleado en el test, y comparar los resultados.
Cuando no es posible aplicar un metodo de calculo alternativo al del test,
puede comprobarse si los resultados obtenidos del test son“razonables”. Por
ejemplo, si un circuito calcula la media de un conjunto de numeros, puede
comprobarse que el resultado obtenido sea mayor o igual que el menor de
los numeros del conjunto, y menor o igual que el mayor de los numeros del
conjunto.
Banco de pruebas
Muchas herramientas de simulacion incluyen menus que permiten asignar valores
a las entradas del circuito. Sin embargo, el uso de este tipo de interfaces graficas
de usuario puede resultar lento y el programa de test desarrollado puede no ser
exportable a otras herramientas de simulacion.
16 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
% &' () &*+ , -. (+ /0 1 ') 0, - 2
345 6 78 64 79:; <= <8 >?:8 ? <@: A B <69: 8< A ? < 9< A9 UUT345 6 78 64 79:? < 6:C D 8:5 >6 7E=? < @: A 8< A4 @9 >?: A?<@ 9 < A9
F G HIJK JLJ M NN O PJ MQ KJ LK RM NN O
Figura 1.5: Diagrama de bloques del modelo de un banco de pruebas.
Una alternativa mucho mas ventajosa consiste en codificar el programa de
test usando un HDL. Es decir, implementar el programa de test en otro modulo
de codigo HDL, que es denominado banco de pruebas.
El banco de pruebas contendra el circuito que esta siendo probado (denomi-
nado abreviadamente UUT, del ingles “Unit Under Test”) como un subcircuito.
Todas las entradas al UUT seran generadas dentro del banco de pruebas, y todas
las salidas del circuito seran comprobadas dentro del banco de pruebas.
En resumen, el banco de pruebas debe incluir (vease el diagrama de bloques
en la Figura 1.5):
– Un subcircuito generador de los vectores de test.
– El circuito que esta siendo probado (UUT).
– Un subcircuito de comprobacion de los resultados obtenidos del test.
Como modulo de codigo en HDL, el banco de pruebas es un modulo sin
entradas ni salidas externas. Puesto que el banco de pruebas normalmente no
va a ser sintetizado en un circuito fısico, puede emplearse cualquier instruccion
disponible en el HDL para generar los vectores de test y analizar las salidas del
UUT, pudiendose llegar a crear programas extremadamente complejos.
Finalmente, recalcar que cuando se disena un circuito digital, es conveniente
disenar tambien su banco de pruebas. Si el circuito se disena jerarquicamente,
entonces cada subcircuito debe ser testeado separadamente antes de ser combi-
nado con otros subcircuitos para integrar un circuito de nivel jerarquico superior.
Asimismo, debera desarrollarse un banco de pruebas para este circuito de nivel
superior.
1.6 Dos simuladores de VHDL’93: VeriBest y ModelSim
En este texto se proponen diferentes casos de diseno de circuitos digitales usando
el lenguaje VHDL, que el alumno debe simular en su propio ordenador. Para ello,
el alumno debe tener instalado en su ordenador un simulador de VHDL.
En esta seccion se proporcionan algunas indicaciones basicas para la instala-
cion y manejo de dos simuladores de VHDL’93: VeriBest VHDL y ModelSim PE
Capıtulo 1 Fundamentos 17
Student Edition. Cualquiera de los dos puede emplearse para la simulacion de los
modelos planteados en este texto.
El simulador VeriBest VHDL fue desarrollado por la companıa VeriBest Inc.
Cuando esta companıa paso a formar parte de la corporacion Mentor Graphics,
dejo de darse soporte al simulador VeriBest VHDL, siendo este sustituido por el
simulador ModelSim.
La unica ventaja de VeriBest es que funciona para casi todas las versiones de
Windows (Windows NT 4.0, Windows 95, Windows 98, etc.). Por tratarse de una
herramienta software del ano 1998, resulta adecuada para su uso en ordenadores
con limitadas prestaciones. Si este no es el caso, es preferible emplear ModelSim
en lugar de VeriBest.
Aparte de estos dos simuladores de VHDL’93, en Internet pueden encontrarse
otros. Asimismo, existen versiones gratuitas de herramientas orientadas no solo
a la simulacion, sino tambien a la sıntesis, entre las que cabe destacar Quartus II
Web Edition, que puede descargarse gratuitamente del sitio web de la companıa
Altera Corporation.
Se sugiere al alumno que escoja en este punto que entorno de simulacion va
a emplear. Si decide usar VeriBest, la guıa de instalacion y uso del Apendice A
puede serle util. Por el contrario, si decide usar ModelSim (lo cual recomendamos),
encontrara la correspondiente guıa en el Apendice B.
2Conceptos básicos de VHDL
Objetivos. Una vez estudiado el contenido del tema deberıa saber:
– Declarar una entidad de diseno en VHDL.
– Declarar los elementos sintacticos basicos de VHDL.
– Discutir las principales caracterısticas de la asignacion concurrente
y las diferencias entre la asignacion secuencial y concurrente.
– Definir el comportamiento de un circuito mediante instanciacion
y conexion de otros circuitos.
– Discutir la utilidad de la parametrizacion en la descripcion de un circuito.
– Discutir las principales caracterısticas de las senales, variables y constantes
en VHDL. Usar adecuadamente cada una de ellas.
– Tipos de datos basicos en VHDL y sus principales atributos.
– Declarar y usar librerıas VHDL y conocer las librerıas mas comunmente usadas.
– Discutir las principales caracterısticas de los tipos de retardo
y modelar los distintos tipos de retardo en VHDL.
– Realizar, con “lapiz y papel”, el cronograma de las senales de un circuito
conocido el codigo VHDL del circuito y de su banco de pruebas.
– Declarar procedimientos y funciones y discutir la utilidad de su uso.
VHDL es un lenguaje complejo, con numerosas capacidades y librerıas de fun-
ciones. De hecho, aunque es un lenguaje para describir hardware, posee muchas
de las capacidades de los lenguajes de programacion (tales como C o Fortran),
incluyendo estructuras record, funciones, procedimientos y soporte a bloques de
codigo compilados separadamente.
Pese a lo anterior, para la mayor parte de las aplicaciones de VHDL al
modelado y simulacion de circuitos digitales, es suficiente con emplear un pequeno
subconjunto de las estructuras y capacidades proporcionadas por el lenguaje. En
particular, se ha definido un subconjunto del lenguaje VHDL, denominado VHDL
20 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
synthesis interoperability subset (estandar IEEE 1076.6), que contiene los tipos
de datos, operadores y otras capacidades de VHDL que deberıan ser usados para
crear codigo VHDL sintetizable. Esto es, codigo a partir del cual las herramientas
de CAD puedan generar automaticamente circuitos hardware que funcionen.
Siguiendo estas reglas y centrandonos en practicas “simples” para la codifi-
cacion de alto nivel, en este capıtulo se introducen los conceptos basicos para el
modelado y la simulacion empleando VHDL.
2.1 Definición de la entidad de diseño
Se denomina entidad de diseno al bloque constitutivo basico para la descripcion
del hardware en VHDL. Consta de las dos partes siguientes:
1. Entity: interfaz con el exterior, en la que se definen los puertos de conexion
(senales de entrada y/o salida) de la entidad de diseno.
2. Architecture: define el comportamiento o la estructura de la entidad de
diseno. Es decir, como los puertos de salida de la entidad de diseno se
relacionan con sus puertos de entrada.
A continuacion, se explica como se define la entity y la architecture, asi
como el procedimiento que proporciona VHDL para asociar una entity a una
determinada architecture.
2.2 Entity
La entity define la interfaz externa de la entidad de diseno. Incluye:
– El nombre de la entidad de diseno.
– La lista de las senales de salida y de entrada que componen la interfaz
(normalmente se aplica el convenio de escribir primero las salidas y a con-
tinuacion las entradas). A cada una de estas senales se le denomina puerto
(port). Existen tres tipos de puertos: in (entrada), out (salida) e inout
(bidireccional).
Ejemplo 2.2.1. En la Figura 2.1 se muestra la definicion de las interfaces de las
puertas logicas NOT, XOR y AND.
La palabra reservada entity, seguida del nombre de la interfaz y de las palabras
reservadas is port, indica el comienzo de la definicion de la interfaz.
A continuacion, se especifica el nombre de cada uno de los puertos, su direc-
cion (in, out o inout) y su tipo. En el ejemplo mostrado en la Figura 2.1, todos
los puertos son senales del tipo std logic.
Finalmente, las palabras reservadas end entity, seguidas del nombre de la
interfaz, indican el final de la definicion.
Capıtulo 2 Conceptos basicos de VHDL 21
y0x0 y0x0
x1y0
x0
x1
entity not is port
( y0 : out std_logic;
x0 : in std_logic );
end entity not;
entity xor2 is port
( y0 : out std_logic;
x0, x1 : in std_logic );
end entity xor2;
entity and2 is port
( y0 : out std_logic;
x0, x1 : in std_logic );
end entity and2;
Figura 2.1: Ejemplos de interfaz (entity) de puertas NOT, XOR y AND.
En VHDL, las palabras reservadas (por ejemplo, entity, is, port, in,
out, end) y los nombres definidos por el usuario (por ejemplo, not1, xor2,
and2, x0, x1, y) pueden escribirse indistintamente en mayusculas o en minusculas,
puesto que en VHDL no se diferencia entre los caracteres en mayuscula y en
minuscula. Por ejemplo, es equivalente escribir entity, ENTITY y EnTiTy, ası
como tambien es equivalente escribir not1 y NoT1.
Los nombres definidos por el usuario deben comenzar por una letra, seguida
opcionalmente por cualquier secuencia de letras, numeros y caracteres guion bajo,
con la limitacion de que ni pueden aparecer dos guiones bajos seguidos, ni el guion
bajo puede ser el ultimo caracter del nombre.
2.3 Architecture
La architecture describe el comportamiento o la estructura de la entidad de
diseno. Esta definicion puede emplear:
– Una descripcion estructural, en la cual el componente es descrito mediante
la conexion de componentes de mas bajo nivel.
– Una descripcion de su comportamiento, en la que se describe el comporta-
miento que debe tener el componente.
– Una descripcion mixta de la estructura y del comportamiento, que incluya
componentes de mas bajo nivel y codigo describiendo el comportamiento.
Ejemplo 2.3.1. En la Figura 2.2 se muestran las architecture que describen el
comportamiento de las puertas logicas NOT, XOR y AND. Las correspondientes
entity son las definidas en la Figura 2.1.
En este ejemplo se ha dado el mismo nombre a la entity y a la architecture
de cada entidad de diseno. En general, se les puede dar nombres diferentes.
A grandes rasgos, la definicion de la architecture tiene la sintaxis siguiente:
architecture <nombre architecture> of <nombre entity> is
<Declaracion de se~nales, variables y constantes locales>
22 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
y0x0 y0x0
x1y0
x0
x1
architecture not of not is
begin
y0 <= not x0;
end architecture not;
architecture xor2 of xor2 is
begin
y0 <= x0 xor x1;
end architecture xor2;
architecture and2 of and2 is
begin
y0 <= x0 and x1;
end architecture and2;
Figura 2.2: Architecture de las puertas NOT, XOR y AND.
<Declaracion de la entity de los componentes>
begin
<Instanciacion de los componentes>
<Asignaciones concurrentes y bloques process>
end architecture <nombre architecture>;
En el area de texto previa a la palabra reservada begin, es donde se declaran
las senales, variables y constantes, todas ellas locales a la definicion de la archi-
tecture, ası como tambien las entity de los componentes usados en la definicion
de la arquitectura.
2.3.1 Asignaciones concurrentes
Las asignaciones directamente contenidas entre las palabras reservadas begin y
end de la architecture se denominan asignaciones concurrentes, debido a
que todas ellas se ejecutan de forma concurrente. Es decir, el orden de ejecucion
de las sentencias no esta determinado por el orden en que se han escrito.
El instante de ejecucion de una sentencia de asignacion concurrente viene
determinado por los eventos en las senales a las cuales la sentencia es “sensible”.
Ejemplo 2.3.2. La sentencia de asignacion concurrente
y0 <= not x0;
es ejecutada cada vez que se produce un cambio en el valor de la senal x0,
calculandose el nuevo valor de la senal y0. En la terminologıa de VHDL, se dice
que esta sentencia, de la cual se calcula y0, es “sensible” a la senal x0.
Ejemplo 2.3.3. Dado el codigo mostrado a continuacion, se producira un cambio
en la senal a cada vez que cambie b, y se producira un cambio en la senal c cada
vez que cambie u o v.
architecture archEjemplo of ...
...
begin
a <= b; -- Asignaciones concurrentes
Capıtulo 2 Conceptos basicos de VHDL 23
c <= u and v; -- a las se~nales: a, c
...
end archEjemplo;
Si dos sentencias de alto nivel (es decir, asignaciones concurrentes) asignan
diferentes valores a una misma senal en un determinado instante de tiempo,
entonces la senal toma el valor X. Observese que en un circuito real una situacion
de ese tipo podrıa producir un dano en el circuito o resultar en la asignacion del
valor 1 o 0 a la senal de manera impredecible.
2.3.2 Bloque process
Para describir la operacion de un determinado circuito, puede ser preciso emplear
una secuencia de sentencias que se ejecuten en secuencia (es decir, en el orden en
que han sido escritas). Para ello se emplea el bloque process. Una secuencia de
sentencias contenidas dentro de un bloque process es simulada ejecutandolas de
manera secuencial.
Por otra parte, los bloques process se ejecuta concurrentemente unos res-
pecto a los otros (solo las sentencias dentro de cada bloque process se ejecutan
secuencialmente), al igual que las demas sentencias de alto nivel, puesto que un
bloque process constituye una sentencia de alto nivel dentro de la definicion de
la architecture.
Las sentencias interiores a un bloque process se ejecutan repetidamente,
desde la primera sentencia del bloque hasta el punto en el cual se alcanza el final
del bloque, en un bucle infinito. Para evitar que un bloque process consuma los
recursos de CPU, debe:
– O bien incluirse sentencias wait dentro del bloque process (esperar hasta
que ocurra cierto evento, o hasta que transcurra cierta cantidad de tiempo
simulado).
– O bien definir la lista de senales a las cuales el bloque process es “sensible”.
Esta lista se escribe, entre parentesis, a continuacion de la palabra reservada
process. En este caso, el bloque process es ejecutado solo en el instante
en que una o varias de estas senales a las que es “sensible” cambia de valor.
Ejemplo 2.3.4. El siguiente codigo muestra un metodo estandar de modelar un
biestable D disparado por el flanco de subida del reloj (clk) y con una entrada
reset asıncrona (reset_n) activada en LOW. Esto significa que cuando la entrada
de reset pasa de valer ’1’ a valer ’0’, entonces se inicializa el biestable: q <- ’0’,
q_n <- ’1’.
--------------------------------------------------
-- Biestable D con reset asıncrono activado en LOW
library IEEE;
use IEEE.std_logic_1164.all;
24 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
use IEEE.numeric_std.all;
entity flipflop_D is port
( q, q_n : out std_logic;
d, clk, reset_n : in std_logic);
end entity flipflop_D;
architecture flipflop_D of flipflop_D is
begin
process(reset_n, clk) is -- Proceso activo cuando cambia
begin -- el valor de reset_n o de clk
if reset_n = ’0’ then -- Comprueba reset asıncrono
q <= ’0’;
q_n <= ’1’;
elsif rising_edge(clk) then -- En el flanco de subida del reloj
q <= d;
q_n <= not d;
end if;
end process;
end architecture flipflop_D;
--------------------------------------------------
2.3.3 Descripción de la estructura
VHDL permite definir circuitos de forma modular y jerarquica. Es decir, es posible
definir un circuito mediante instanciacion y conexion de otros circuitos, y a su vez
usar este nuevo circuito para definir, mediante su conexion con otros circuitos,
otro circuito de un nivel jerarquico superior, y ası sucesivamente. A esto se
denomina realizar una descripcion modular y jerarquica del hardware.
Para describir un circuito mediante la instanciacion y conexion de subcircui-
tos, es necesario:
1. Escribir la declaracion completa de la entity de cada clase de subcircuito.
2. Instanciar los subcircuitos, asignando un nombre a cada uno de los objetos
creados de cada entity.
3. Conectar los subcircuitos. Se hace de la forma siguiente:
– Una conexion entre subcircuitos se indica usando senales con nombres
identicos.
– Una conexion entre el circuito y un subcircuito se indica “mapeando”
la senal del circuito con el correspondiente puerto del subcircuito. Esta
conexion entre senales puede realizarse mediante:
· Asociacion posicional, es decir, mediante la posicion en que la
senal se situa en la lista de parametros.
Capıtulo 2 Conceptos basicos de VHDL 25
· Asociacion mediante el nombre, tambien llamada asignacion ex-
plıcita, en la cual la senal y su puerto asociado son incluidos en la
lista de parametros de la forma
puerto => se~nal
Ejemplo 2.3.5. En la Figura 2.3 se muestra el diagrama y la implementacion de
un multiplexor de 2 senales de 1 bit. Cuando la senal de control s0 vale ’0’, la
senal i0 se transmite a la salida d, mientras que cuando s0 vale ’1’ es la senal
i1 la que se transmite a la salida.
S TS U VWT
X Y Z [ \]
^ _ ` _Figura 2.3: Multiplexor de 2 senales de 1 bit: a) diagrama; b) implementa-cion.
Como puede observarse en la Figura 2.3b, este circuito multiplexor esta com-
puesto por un inversor (inv_1), dos puertas AND de dos entradas (AND2_1,
AND2_2) y una puerta OR de dos entradas (OR2_1). Las senales n1, n2 y n3
tienen por objeto describir la conexion entre los componentes.
A continuacion, se muestra la descripcion de la estructura del circuito en
lenguaje VHDL. Observese que al instanciar cada componente, se indica que senal
debe asociarse a cada uno de sus puertos. Una misma senal asociada a diferentes
puertos indica el establecimiento de una conexion entre esos puertos.
----------------------------------------------
-- MUX 2:1 de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
entity Mux2_1bit is
port ( d : out std_logic;
i0, i1 : in std_logic;
s0 : in std_logic );
end entity Mux2_1bit;
26 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
architecture Mux2_1bit of Mux2_1bit is
component not1 is
port ( y0 : out std_logic;
x0 : in std_logic );
end component not1;
component or2 is
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end component or2;
component and2 is
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end component and2;
signal n1, n2, n3 : std_logic;
begin
Inv_1 : not1 port map ( x0 => s0, y0 => n1);
And2_1 : and2 port map ( x0 => i0, x1 => n1, y0 => n2);
And2_2 : and2 port map ( x0 => i1, x1 => s0, y0 => n3);
Or2_1 : or2 port map ( x0 => n2, x1 => n3, y0 => d);
end architecture Mux2_1bit;
----------------------------------------------
Ejemplo 2.3.6. El circuito multiplexor de dos senales de 1 bit puede emplearse
para disenar un multiplexor de dos senales de 4 bits. En la Figura 2.4 se muestra
la representacion esquematica del circuito. El codigo VHDL que describe este
circuito se muestra a continuacion.
----------------------------------------------
-- MUX 2:1 de 4 bit
library IEEE;
use IEEE.std_logic_1164.all;
entity Mux2_4bit is
port ( d0, d1, d2, d3 : out std_logic;
a0, a1, a2, a3 : in std_logic;
b0, b1, b2, b3 : in std_logic;
s0 : in std_logic );
end entity Mux2_4bit;
architecture Mux2_4bit of Mux2_4bit is
Capıtulo 2 Conceptos basicos de VHDL 27
i0i1
ds0
abcdef
i0i1
ds0
abcdef
i0i1
ds0
abcdef
i0i1
ds0
abcdef
a3b3
a2b2
a1b1
a0b0
d3
d2
d1
d0
s0Figura 2.4: Multiplexor de 2 senales de 4 bit disenado mediante la conexionde 4 multiplexores de 2 senales de 1 bit.
component Mux2_1bit is
port ( d : out std_logic;
i0, i1 : in std_logic;
s0 : in std_logic );
end component Mux2_1bit;
begin
Mux2_0 : Mux2_1bit port map
( d => d0, i0 => a0, i1 => b0 , s0 => s0 );
Mux2_1 : Mux2_1bit port map
( d => d1, i0 => a1, i1 => b1 , s0 => s0 );
Mux2_2 : Mux2_1bit port map
( d => d2, i0 => a2, i1 => b2 , s0 => s0 );
Mux2_3 : Mux2_1bit port map
( d => d3, i0 => a3, i1 => b3 , s0 => s0 );
end architecture Mux2_4bit;
----------------------------------------------
28 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
2.3.4 Constantes generic
Una propiedad muy relacionada con la modularidad y la jerarquıa es la parame-
trizacion, que es la capacidad de modificar el valor de ciertas propiedades de un
circuito cuando es instanciado, con el fin de adaptarlo a la aplicacion en concreto
a la que vaya a destinarse al formar parte del circuito de nivel jerarquico superior.
La parametrizacion es una propiedad fundamental en la reutilizacion del codigo,
ya que permite adaptar un mismo fragmento de codigo a diferentes usos.
La palabra reservada generic se usa para definir aquellas constantes del
dispositivo a las que se desea asignar valor cuando el dispositivo es instanciado,
es decir, cuando es usado como un subcircuito de otro circuito de mayor nivel
jerarquico. Ejemplos tıpicos de constantes genericas son el valor de determinados
retardos, el numero de bits de un bus de senales, etc. Cuando una entity con
constante generic es instanciada como un subcircuito, puede cambiarse el valor
de las constantes generic para definir diferentes subcircuitos, con diferentes
valores de los retardos, anchura de los buses, etc. El caso practico descrito en
la Seccion 3.6 ilustra el empleo de constantes generic.
2.4 Configuration
Se emplea una pareja entity-architecture para describir en VHDL las enti-
dades de diseno (es decir, circuitos y subcircuitos) que pueden ser compilados
separadamente.
El hecho de que se definan separadamente la interfaz (entity) y la arquitectura
(architecture) facilita la definicion de varias arquitecturas para una misma
entidad de diseno (con una unica interfaz). Por ejemplo, pueden definirse varias
arquitecturas de una misma entidad de diseno, correspondientes a diferentes
versiones del circuito: velocidad baja, media y alta.
En este caso, cuando se emplee esa entidad de diseno debe indicarse explı-
citamente que arquitectura hay que emplear. Esto puede hacerse mediante la
definicion de una configuracion (configuration).
2.5 Señales, variables y constantes
En VHDL se emplean variables, senales y constantes para describir la operacion
del circuito. Las senales corresponden con las senales logicas reales existentes en
el circuito. Las variables pueden o no corresponder con senales fısicas reales. Las
constantes corresponden a magnitudes cuyo valor no cambia durante la simulacion
(tıpicamente retardos, numero de lıneas de buses, numero de bits de palabras,
etc.).
Las variables siempre deben usarse dentro de bloques process. Aparte de esta
restriccion, pueden ser usadas con relativa libertad.
Por el contrario, hay que ser cuidadoso con el empleo de las senales. Las
senales definidas en el port de una entity tienen una direccion, lo cual condiciona
Capıtulo 2 Conceptos basicos de VHDL 29
su uso: no puede leerse el valor de una senal de salida (out), ni asignarse un
valor a una senal de entrada (in). Las senales declaradas en la definicion de la
architecture puede ser usadas tanto en la parte derecha como en la izquierda
de las asignaciones.
Un criterio general respecto al uso de las variables y las senales es el siguiente:
– Emplear una variable cuando vaya a usarse solo dentro de un bloque pro-
cess.
– Emplear una senal para datos a los que deba asignarse valor fuera del bloque
process, o para datos que necesitan ser transferidos desde un puerto de
entrada o a un puerto de salida. Esto ultimo es equivalente a decir que los
port solo pueden ser senales.
Para asignar valor a una variable o constante se emplea :=, mientras que
se emplea <= para asignar valor a una senal. Solo puede asignarse valor a las
variables en los bloques process. Puede asignarse valor a las senales mediante
asignaciones concurrentes o en los bloques process.
La diferencia fundamental entre una asignacion a una senal y una asignacion a
una variable, ambas realizadas dentro de un bloque process, es que la asignacion
a la senal se ejecuta concurrentemente con la siguiente sentencia del bloque
process, mientras que la asignacion a la variable se ejecuta antes que la siguiente
sentencia del bloque process.
Dos ejemplos tıpicos de uso de las variables son los siguientes:
1. Cuando hace falta realizar una serie de calculos para poder asignarle valor
a una senal, se definen nuevas variables, se hacen los calculos usando esas
variables, y finalmente se asigna el resultado de los calculos a la senal.
2. Puesto que una senal de salida (es decir, un puerto out) no puede ser leıda,
puede ser necesario definir una variable, leer y escribir sobre esa variable
tantas veces como sea necesario, y finalmente asignar esa variable a la senal
de salida.
Asimismo, existe una diferencia importante en el retraso asociado a una
asignacion de una variable y de una senal. Este punto es discutido en la Seccion
2.7.
Pueden definirse constantes en VHDL usando la palabra reservada constant.
Las sentencias de definicion de constantes pueden situarse en los bloques entity
y architecture, antes de la palabra reservada begin. Tambien pueden definirse
constantes dentro de la definicion de un paquete (package), en cuyo caso deben
ser incluidas mediante una clausula use.
2.5.1 Tipos de datos
Tıpicamente, la informacion se comunica dentro de un sistema digital usando
senales de valor binario (0 o 1). En los sistemas de logica positiva, cuando el
voltaje de la senal tiene un valor “alto” (3.3 o 5 voltios en la tecnologıa CMOS),
30 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
representa un 1 logico, y cuando toma un valor “bajo” (0 voltios en la tecnologıa
CMOS) representa un 0 logico.
Aunque todas las senales son interpretadas en los sistemas digitales como 0 y
1 logicos, no es siempre posible modelar y simular los sistemas digitales usando
solo senales 0 logico y 1 logico. Un motivo es que el valor de algunas senales
puede no ser conocido en determinado intervalo de tiempo de la simulacion, por
ejemplo porque esas senales todavıa no hayan sido inicializadas, es decir, no se
les haya asignado valor. Por otra parte, una senal puede tener un nivel de voltaje
intermedio (que puede ser interpretado como un 0 logico o un 1 logico), por
ejemplo debido a que esta producida por una puerta logica con una salida “debil”.
En VHDL se emplean tipos de datos para modelar las senales. Estos tipos de
datos pueden ser los estandar o bien tipos definidos por el usuario. El usuario
puede definir sus propios tipos de datos, bien como un subconjunto de tipos de
datos estandar, o bien puede definir sus propios tipos enumerados.
Los tipos mas comunes en el modelado de senales digitales son bit y std logic.
A continuacion se describen ambos tipos.
bit y std_logic
Una variable, senal o constante del tipo bit solo puede tomar dos valores: 0 y
1 (observese que los valores se escriben sin comillas). Ası pues, este tipo es util
para realizar modelos sencillos de sistemas digitales.
Las variables, senales o constantes del tipo std logic pueden tomar nueve
valores. Ademas de los valores ’0’ y ’1’ (observese que en este caso los valores se
escriben entre comillas simples), pueden tomar otros valores usados para modelar
valores intermedios o desconocidos de la senal. De estos valores, los mas comunes
son los tres siguientes:
’U’ El valor de la senal esta sin inicializar. Es decir, a la
senal no se le ha asignado todavıa un valor.
’X’ No puede determinarse el valor de la senal, quiza
debido a un conflicto en las salidas (por ejemplo, una
puerta logica intenta poner a ‘0’ la senal mientras otra
puerta logica intenta ponerla a ‘1’).
’Z’ Alta impedancia, es decir, la senal ha quedado desco-
nectada.
Los restantes posibles valores de una senal del tipo std logic son: ’W’ (des-
conocida debil), ’L’ (cero debil), ’H’ (uno debil) y ’-’ (don’t care).
Por lo general, en los modelos mostrados en este texto se empleara el tipo
std logic para representar las senales binarias.
bit_vector y std_logic_vector
Los conjuntos de senales pueden agruparse formando lo que se denominan buses.
Analogamente, los conjuntos de variables pueden agruparse en vectores. Los
buses y vectores pueden modelarse en VHDL mediante los tipos bit vector (un
Capıtulo 2 Conceptos basicos de VHDL 31
conjunto de senales o variables de tipo bit) y std logic vector (un conjunto de
senales o variables de tipo std logic).
Una desventaja de los tipos de datos bit vector y std logic vector es que
no pueden realizarse operaciones aritmeticas sobre este tipo de senales. Esto
es razonable, ya que en los circuitos digitales no pueden realizarse operaciones
aritmeticas directamente sobre los buses de senales, solo pueden realizarse opera-
ciones logicas. La forma de representar los valores literales de estos tipos de datos
se muestran en la Tabla 2.1.
Tabla 2.1: Valores literales.
Literales
bit 0, 1
std logic ’U’, ’0’, ’1’, ’Z’, ’W’, ’L’, ’H’, ’-’
bit vector Strings (cadenas de caracteres delimitadas por dobles
std logic vector comillas) de sus tipos basicos.
Para especificar la base, se antepone la letra:
B (para dıgitos binarios)
O (para dıgitos en octal)
X (para dıgitos en hexadecimal)
El caracter _ (guion bajo) puede usarse como marcador(es ignorado por el compilador de VHDL) con el fin defacilitar la lectura de los numeros.
Por ejemplo, las siguientes son tres formas de expresar elnumero sin signo 29:
B"01_1101" O"35" X"1D"
integer Sus literales estan expresados por defecto en base 10.
real Para especificar valores en otras bases, es necesario usar #para delimitar el valor, con la base precediendo el primer#.
Las constantes de tipo real se representan usando unpunto decimal para separar la parte entera de la partedecimal, y un E (o e) precediendo el valor del exponente.
Por ejemplo, a continuacion se muestran diferentes for-mas de expresar el numero decimal 29:
2#01_1101# 8#35# 16#1D#
2.9e1 2.9E1 29
unsigned y signed
En aquellos casos en que resulte util modelar operaciones aritmeticas realizadas
sobre buses, pueden usarse los tipos de datos unsigned y signed. Ambos tipos
de datos estan definidos usando como tipo de datos base std logic, con lo cual
son vectores de valores std logic.
Ası pues, la diferencia entre el tipo de datos std logic vector y los tipos
de datos unsigned y signed es que para el tipo de datos std logic vector
32 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
estan definidas las operaciones logicas, pero no las aritmeticas, mientras que para
los tipos de datos unsigned y signed estan definidas las operaciones logicas y
aritmeticas.
Puede cambiarse el tamano (es decir, el numero de bits) de los datos unsigned
y signed mediante la funcion resize. El parametro size representa el nuevo
numero de bits del dato.
Tabla 2.2: Funciones para cambio de tamano de unsigned y signed.
Tipo de dato Funcion
unsigned resize(arg,size)
signed resize(arg,size)
real e integer
Tambien existen tipos de datos estandar que no se corresponden necesariamente
con senales en los circuitos fısicos. Resultan utiles para realizar descripciones del
comportamiento de los circuitos y para modelar los tests. Los tipos de datos
integer (32 bits) y real (64 bits) se definen de manera similar a como se hace en
los lenguajes de programacion. Lo mismo sucede con las operaciones aritmeticas
para este tipo de datos. En la Tabla 2.1 se muestra la forma de representar los
valores literales de los tipos integer y real.
time y string
Los tipos de datos time y string son utiles, en el proceso de depuracion (debug-
ging) del modelo, para mostrar mensajes que son generados durante la simulacion.
Las variables del tipo time son usadas para representar el tiempo simulado. La
unidad por defecto de este tipo de variables es el fs (femtosegundo = 10−15 s). Los
valores del tiempo pueden representarse en otras unidades escribiendo la unidad
de tiempo tras el valor del tiempo, el cual es escrito como una constante entera
o real. Las unidades de tiempo disponibles son: fs, ps, ns, us (microsegundos),
ms, sec, min y hr (horas). Ademas, existe una funcion estandar (llamada now,
sin argumentos), que devuelve el valor actual del tiempo simulado.
Para mostrar mensajes de texto y valores de datos en la pantalla, es preciso
convertir todos los argumentos de la sentencia report (la sentencia “print” de
VHDL) a tipos de dato string. Como en la mayorıa de los lenguajes de progra-
macion, un string se define simplemente como un array de caracteres.
Tipos enumerados
Ademas de los tipos estandar de datos descritos anteriormente, es posible definir
tipos enumerados de datos.
Por ejemplo, supongamos una senal llamada opcode, que representa el codigo
de operacion de un circuito. Suponiendo que solo puede tomar cuatro valores
Capıtulo 2 Conceptos basicos de VHDL 33
(suma, resta, salto y parar), entonces es posible definir un nuevo tipo (type),
llamado, por ejemplo, opcode_type, de la manera siguiente:
type opcode_type is ( SUMA, RESTA, SALTO, PARAR );
y declarar opcode del tipo opcode_type.
Este tipo de construccion hace el codigo VHDL mas sencillo de entender. Sin
embargo, esta forma de realizar el modelo no permite especificar explıcitamente
el codigo binario correspondiente a cada uno de los codigos de operacion.
Una forma alternativa de programar el ejemplo anterior es definir SUMA, RESTA,
SALTO y PARAR como constantes (constant) de dos bits, y definir opcode como
una senal que sea un vector de dos bits.
Conversión entre tipos
El compilador del lenguaje VHDL comprueba el tipo de los datos, mostrando
un error si en alguna operacion se emplean tipos para los cuales esa operacion
no esta explıcitamente permitida. La finalidad de ello es reducir los errores de
programacion, si bien tambien obliga a realizar conversiones de tipos, incluso
entre tipos que son esencialmente el mismo (como, por ejemplo, unsigned y
std logic vector).
Las funciones para la conversion de tipos estan definidas en las librerıas
estandar y packages, tıpicamente en el package en el que se define el tipo. Por
ejemplo, entre las funciones incluidas en el package IEEE.numeric std estan:
to unsigned Convierte de integer a unsigned
to integer Convierte de unsigned a integer
Asimismo, la conversion entre tipos cercanos puede realizarse usando funcio-
nes cuyo nombre coincide con el nombre de los tipos. Por ejemplo, unsigned(t)
convierte una senal t del tipo std logic vector al tipo unsigned.
Tabla 2.3: Funciones para la conversion de tipos.
Conversion de: a: Funcion
std logic vector unsigned unsigned(arg)
std logic vector signed signed(arg)
unsigned std logic vector std_logic_vector(arg)
signed std logic vector std_logic_vector(arg)
integer unsigned to_unsigned(arg,size)
integer signed to_signed(arg,size)
unsigned integer to_integer(arg)
signed integer to_integer(arg)
integer std logic vector integer → unsigned/signed → std logic vector
std logic vector integer std logic vector→ unsigned/signed → integer
Observese en la Tabla 2.3 que en la conversion del tipo integer a los tipos
unsigned o signed, es preciso especificar el numero de bits (size) de la senal
del tipo unsigned o signed resultante.
34 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
2.5.2 Atributos
Puede considerarse que los atributos son propiedades de los tipos de datos. Existen
conjuntos estandar de atributos que son soportados para diferentes propositos.
No todos los atributos son soportados para sıntesis. En la Tabla 2.4 se muestra
un conjunto de atributos estandar que son soportados por la mayorıa de las
herramientas de sıntesis.
Tabla 2.4: Atributos soportados por la mayorıa de las herramientas desıntesis.
Atributo Significado
<tipo>’ Indica que el argumento es del tipo <tipo>
<tipo>’base Tipo base de <tipo>
<tipo>’left Primer (mas a la izquierda) valor en <tipo>
<tipo>’right Ultimo (mas a la derecha) valor en <tipo>
<tipo>’low Valor mas pequeno en <tipo>
<tipo>’high Valor mas grande en <tipo>
<vector>’range Rango de ındices de un vector
<vector>’reverse_range Rango de ındices del vector, en orden inverso
<vector>’length Numero de valores en el rango del vector
<array>’range(n) Rango de ındices en la dimension n del array
<array>’reverse\_range(n) Rango de ındices, en la dimension n del array,en orden inverso
<array>’length(n) Numero de valores en el rango de la dimensionn del array
<se~nal>’stable true mientras no hay cambios en <se~nal>
<se~nal>’event true solo cuando hay un cambio en <se~nal>
El primer atributo, <tipo>’, se usa para especificar el tipo de una senal o de
un valor. Por ejemplo,
unsigned’("00")
establece que el string "00" se usa como un vector del tipo unsigned, en lugar
de como bit vector o std logic vector.
Hay atributos para tipos escalares de datos, para arrays de una dimension
(vectores), para arrays de n dimensiones, y para senales. En la Tabla 2.4 se ha
empleado la terminologıa siguiente:
<tipo> un tipo de datos escalar, estandar o definido por el usuario.
<vector> un tipo array unidimensional.
<array> un tipo array.
<se~nal> una senal.
n un valor entero.
Capıtulo 2 Conceptos basicos de VHDL 35
Asimismo, existen atributos que resultan utiles para programar bancos de
prueba y que, por tanto, no necesitan ser sintetizados. Un atributo particular-
mente util es
<tipo>’image(se~nal)
que devuelve un string con el valor del tipo <tipo>de la senal <senal>. Este
atributo se usa para convertir el valor de una senal a un string, de modo que
pueda ser mostrado en la consola (con el fin de depurar o monitorizar).
La lista completa de atributos soportados por VHDL es bastante extensa. No
obstante, solo son necesarios unos pocos para programar la mayor parte de los
tipos de circuitos digitales y bancos de pruebas.
Por ejemplo, en VHDL’87 se emplea
clk’event and ( clk = ’1’ )
para modelar el flanco de subida de la senal de reloj. Sin embargo, puesto que
este predicado es tambien cierto cuando la senal clk cambia del valor U (no
inicializado) o del valor X (desconocido forzado) a 1, en VHDL’93 se usa
rising_edge(clk)
para modelar el flanco de subida de la senal clk.
Otro atributo usado frecuentemente es
<tipo>’range
el cual se emplea para especificar (por ejemplo, en un bucle for) el rango completo
de ındices de un determinado tipo de dato.
2.5.3 Operadores
Los operadores de VHDL’93 estan resumidos en la Tabla 2.5.
En la Tabla 2.6 se muestra el tipo de dato obtenido al realizar operaciones
aritmeticas entre operandos del tipo unsigned, signed, e integer.
Tabla 2.5: Operadores de VHDL’93
Categorıa Operador Significado
Miscelaneos ** Exponenciacion
abs Valor absoluto
not NOT logico
Multiplicacion / Division * Multiplicacion
/ Division
mod Modulo
rem Resto
Unitarios (signo) + Identidad
– Negacion (complemento a 2)
Suma / Resta + Suma
– Resta
& Concatenacion
Desplazamiento sll Desplazamiento logico izquierda
srl Desplazamiento logico derecha
sla Desplazamiento aritmetico izquierda
sra Desplazamiento aritmetico derecha
rol Rotacion logica izquierda
ror Rotacion logica derecha
Relacional = Comprueba igualdad
/= Comprueba desigualdad
< Menor que
<= Menor o igual que
> Mayor que
>= Mayor o igual que
Logico and AND logica
or OR logica
nand NAND logica
nor NOR logica
xor OR exclusiva logica
xnor NOR exclusiva logica
Tabla 2.6: Tipo obtenido como resultado de las operaciones aritmeticas.
Operando 1 Operando 2 Resultado
unsigned unsigned unsigned
unsigned integer unsigned
integer unsigned unsigned
signed signed signed
signed integer signed
integer signed signed
Capıtulo 2 Conceptos basicos de VHDL 37
2.6 Librerías
En VHDL, una librerıa de diseno contiene la definicion de un conjunto de tipos
de datos, ası como la definicion de los operadores y funciones que pueden aplicarse
sobre estos tipos de datos. Existe un buen numero de librerıas de diseno estandar
y de librerıas especıficas, que son proporcionadas junto con las herramientas de
simulacion.
A excepcion de los tipos bit y bit vector, todos los demas tipos precisan de
la inclusion de alguna librerıa de diseno. Por ejemplo, es necesario usar la librerıa
de IEEE (que es proporcionada en todos los simuladores) para poder usar los
tipos de datos std logic, std logic vector, unsigned y signed.
VHDL permite organizar las librerıas, estructurando su contenido en sub-
librerıas denominadas packages. Un beneficio anadido de ello es que incluir
unicamente los tipos de datos necesarios para el diseno reduce el tamano del
codigo y simplifica la simulacion del programa en VHDL.
Por este motivo, ademas de especificar que librerıas deben ser incluidas,
conviene que el disenador indique que paquetes en concreto de la librerıa son
usados en la definicion del circuito. Si no se especifica el paquete, o si un mismo
objeto esta definido en varios paquetes, es preciso referirse a el usando la notacion
punto:
librerıa.paquete.objeto
Entre los paquetes mas comunmente usados, cabe mencionar los siguientes, per-
tenecientes a la librerıa IEEE:
IEEE.std logic 1164 Incluye la definicion de los tipos de datos
std logic y std logic vector, y de las operacio-
nes en las que intervienen estos tipos de datos.
IEEE.numeric std Incluye la definicion de los tipos de datos unsig-
ned y signed, y de las operaciones mas comunes
realizadas sobre estos tipos de datos.
IEEE.math real Incluye la definicion de las operaciones en las que
intervienen numeros reales (tipo real). Estos son
numeros reales en coma flotante de 64 bits segun
el estandar de IEEE.
Ası pues, es frecuente incluir, antes de la definicion de la entidad de diseno,
las tres sentencias siguientes:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
La primera sentencia indica que va a emplearse la librerıa de IEEE. Las otras
dos indican que los paquetes IEEE.std logic 1164 y IEEE.numeric std deben estar
listos para su uso en el codigo VHDL que sigue a continuacion. Por supuesto, si
38 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
en el codigo no se usan los tipos de datos unsigned y signed, entonces puede
omitirse la tercera sentencia.
Las herramientas de simulacion y sıntesis con VHDL suelen incluir otras
librerıas, que pueden ser examinadas desde la propia herramienta.
Existen librerıas y paquetes que son cargados por defecto, con lo cual no
necesitan ser incluidas. Las mas notables son las dos siguientes:
work Librerıa por defecto donde se compilan todos
los tipos, las funciones, entity, architecture,
package, etc. definidos por el usuario.
std Contiene la mayorıa de las definiciones y cons-
trucciones estandar soportadas por VHDL.
2.7 Modelado del retardo
Puesto que los dispositivos y las conexiones entre los dispositivos tienen retardos
asociados, para simular de manera precisa el comportamiento de los circuitos
es necesario modelar adecuadamente su retardo. De hecho, hay circuitos que no
funcionan adecuadamente cuando son simulados si no se toman en consideracion
los retardos que se producen en ellos.
Una recomendacion cuando se modelan circuitos digitales es asignar algun
retardo (incluso un retardo arbitrario, como 1 ns) a todas las operaciones al
nivel de transferencia entre registros usadas en el codigo VHDL que describe el
circuito. Observese, no obstante, que esos retardos no son soportados al realizar la
sıntesis: algunas herramientas de sıntesis simplemente los ignoran, mientras que
otras obligan al disenador a poner esos retardos a cero o a eliminarlos del codigo.
Los retardos pueden ser modelados mediante varios metodos. A continuacion
se describen algunos de ellos.
2.7.1 Sentencia wait
El metodo mas sencillo de modelar un retardo es emplear la sentencia wait,
indicando el numero de unidades de tiempo que debe durar la espera. Por ejemplo,
la sentencia:
wait for 10 ns;
dentro de un bloque process, hace que la ejecucion del bloque se detenga durante
10 nanosegundos.
Pueden usarse otras formas de la sentencia wait. Por ejemplo, la sentencia:
wait;
dentro de un bloque process, hace que este se quede esperando indefinidamente,
con lo cual se detiene la ejecucion del bloque.
Capıtulo 2 Conceptos basicos de VHDL 39
Asimismo, las construcciones:
wait until <condicion>;
wait until <lista de se~nales>;
dentro de un bloque process, detienen la ejecucion del bloque hasta que la
condicion booleana se haga verdadera, o hasta que alguna de las senales de la
lista cambie de valor, respectivamente.
Si la sentencia:
wait until <lista de se~nales>;
es la primera sentencia de un bloque process (esta en concreto es la unica forma
de uso de la sentencia wait permitida para sıntesis), entonces es equivalente a
usar <lista de se~nales> como la lista de senales a las que el bloque process es
sensible.
2.7.2 Retardos en la asignación a señales
Pueden especificarse retardos en las asignaciones a senales usando la palabra
reservada after. Por ejemplo, puede modelarse el comportamiento de una puerta
NAND con un retardo de propagacion de 2 ns mediante la sentencia:
y <= x0 nand x1 after 2 ns;
Cuando se encuentra esta sentencia en la simulacion, se emplean los valores
actuales de x0 y x1 para calcular el resultado de la operacion x0 nand x1. Este
resultado no se asigna a y hasta transcurridos 2 ns.
Sin embargo, esto no implica que la siguiente sentencia no sea ejecutada
hasta que transcurran los 2 ns. Al contrario, la siguiente sentencia es ejecutada
inmediatamente, aun cuando estas sentencias sean parte de un bloque process.
Ası pues, el cambio en la senal y no habra ocurrido en el instante en el cual se
ejecute la siguiente sentencia.
Para especificar que la simulacion se detenga durante un periodo de tiempo
antes de que la siguiente sentencia sea ejecutada, debe usarse el comando wait.
2.7.3 Retardo inercial y de transporte
Cuando se realiza una descripcion jerarquica del circuito, cobran importancia los
conceptos de retardo inercial y retardo de transporte.
Un dispositivo logico real tiene la propiedad de que un glitch en un puerto
de entrada, con una duracion inferior al retardo de propagacion del dispositivo,
no tiene efecto sobre la salida del dispositivo. Se denomina glitch a un cambio
temporal (un pico de subida o bajada) e inesperado en el voltaje.
Por ejemplo, si una puerta NAND tiene un retardo de propagacion de 1 ns,
entonces un glitch de 0.5 ns (un 0 o 1 temporal, de duracion 0.5 ns) en una de
sus entradas no produce ningun cambio en su salida.
40 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Este tipo de comportamiento del retardo se denomina retardo inercial y es el
modelo del retardo usado por defecto para todos los dispositivos en VHDL.
Otro tipo alternativo de modelo del retardo, en el cual todos los glitches a
la entrada se manifiestan en la salida, se denomina retardo de transporte. Este
tipo de comportamiento se modela usando la palabra clave transport tras el
operador de asignacion (<=).
El modo recomendado de modelar el retardo en el codigo VHDL sintetizable
es el retardo inercial.
2.7.4 Retardo delta
Es importante tener en cuenta que todas las operaciones que involucran senales
poseen un retardo, dado que todas las senales en los circuitos fısicos experimentan
retardos cuando pasan a traves de los dispositivos y las conexiones.
En vista de ello, aunque no se especifique de manera explıcita en el codigo
VHDL el retardo, todas las senales son simuladas sometiendolas a un retardo en
cada operacion de asignacion o instanciacion de un subcircuito.
Ası pues, cuando se ejecuta una sentencia en la que se asigna un nuevo
valor a una senal, se aplica por defecto un retardo de valor delta. Es decir, un
retardo infinitesimal, inferior al incremento de tiempo mas pequeno que puede
ser especificado en VHDL, que es un femtosegundo (1 fs = 10−15 s).
Como consecuencia de este metodo de retardo delta empleado en la simula-
cion, cuando se asigna un valor a una senal en VHDL, hay dos eventos de interes:
1. Se calcula el nuevo valor y se planifica el cambio en la senal.
2. Transcurrido un tiempo delta, se asigna a la senal su nuevo valor.
Este comportamiento no tiene un efecto apreciable para las sentencias de
asignacion que estan fuera de bloques process, que en cualquier caso se ejecutan
concurrentemente.
Sin embargo, tiene un efecto importante en las asignaciones a senales que
estan dentro de bloques process:
1. Se planifica el cambio en la senal antes de que se ejecute la siguiente
sentencia.
2. El cambio en el valor de la senal debido a la primera sentencia ocurre despues
de que se haya planificado el cambio debido a la siguiente sentencia, para
lo cual se usan los valores de las senales en el instante actual.
Ası pues, una cadena de asignaciones a senales contenida en un bloque pro-
cess se comporta de manera diferente a un conjunto de sentencias en un lenguaje
de programacion. Por ejemplo, suponga el siguiente fragmento de codigo VHDL:
process (clk) is
begin
if rising_edge(clk) then
b <= a;
Capıtulo 2 Conceptos basicos de VHDL 41
c <= b;
...
Puesto que b y c son senales, existe un retardo delta antes de que se produzca
la asignacion del nuevo valor a b. Antes de que transcurra este retardo, se calcula
el nuevo valor de la variable c, usandose para ello el valor “antiguo” de b. En este
ejemplo, la senal c adquiere el valor que tenıa la senal b en el anterior ciclo de
reloj, dado que el proceso es activado unicamente en los flancos de subida de la
senal de reloj.
La discusion anterior acerca del retardo delta no aplica a las asignaciones a
variables. De hecho, ni siquiera es posible asociar un retardo a una asignacion
a una variable (no pueden usarse sentencias de la forma a := b after c ns;).
Las asignaciones a variables ocurren inmediatamente, sin retardos delta, lo cual es
razonable considerando que las variables en VHDL estan ideadas para ser usadas
como las variables de los programas de los lenguajes de programacion.
Ası pues, dada una cadena de asignaciones a variables contenida dentro de
un bloque process, estas asignaciones a variables se realizan de manera estric-
tamente secuencial (de la misma forma que se ejecutan las sentencias en C o en
Fortran).
2.7.5 Caso práctico
El modelo mostrado a continuacion pretende ilustrar los conceptos relacionados
con el retardo expuestos en esta seccion, ası como la diferencia entre las senales
y las variables en lo que respecta al retardo.
En primer lugar, se muestra el codigo de una puerta NAND con un retardo
inercial del 2 ns, y a continuacion el codigo del banco de pruebas.
-------------------------------------
-- Puerta NAND con retardo inercial
library IEEE;
use IEEE.std_logic_1164.all;
entity nand2 is port
( y0 : out std_logic;
x0, x1 : in std_logic);
end entity nand2;
architecture nand2 of nand2 is
begin
y0 <= x0 nand x1 after 2 ns; -- Retardo inercial de 2 ns
end architecture nand2;
-------------------------------------
42 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
-------------------------------------------
-- Banco de pruebas de diferentes retardos
library IEEE;
use IEEE.std_logic_1164.all;
entity retardo_bp is
end entity retardo_bp;
architecture retardo_bp of retardo_bp is
signal s1, s2, s3, s4 : std_logic;
signal in1, in2 : std_logic;
component nand2 is port
( y0 : out std_logic;
x0, x1 : in std_logic);
end component nand2;
begin
-- Crear el UUT para el test
g0 : component nand2 port map (s1, in1, in2);
s2 <= in1 nand in2 after 2 ns; -- Misma forma de onda que s1
process is
variable var1, var2 : std_logic;
begin
for i in 0 to 4 loop -- Itera 5 veces
var1 := in1 nand in2;
var2 := var1; -- var2 debe ser igual a var1
s3 <= in1 nand in2;
s4 <= s3; -- s4 debe ser igual al valor
-- antiguo de s3
wait for 10 ns; -- Repetir para 0, 10, 20, 30 y 40 ns
end loop;
wait; -- Detiene el proceso
end process;
-- Crear los vectores de test
in1 <= ’1’;
in2 <= ’0’, -- in2 comienza a 0
’1’ after 10 ns, ’0’ after 11 ns, -- Pulso de 1 ns
-- en el instante 10 ns
’1’ after 20 ns, ’0’ after 22 ns, -- Pulso de 2 ns
-- en el instante 20 ns
’1’ after 26 ns, ’0’ after 29 ns; -- Pulso en el instante 26 ns
end architecture retardo_bp;
-------------------------------------------
Capıtulo 2 Conceptos basicos de VHDL 43
Las formas de onda obtenidas de la simulacion se muestran en la Figura 2.5.
La senal in2 comienza con el valor 0 y tiene pulsos en los instantes 10, 20 y 26
ns. Sin embargo, el pulso en el instante 10 ns es mas corto que el retardo de
propagacion de la puerta NAND y de la asignacion a la senal s2. Por ello, las
senales s1 y s2 ignoran ese pulso.
Figura 2.5: Formas de onda obtenidas de simular el banco de pruebas.
Debido al retardo de 2 ns, el valor de las senales s1 y s2 no esta definido
hasta el instante 2 ns. Por ello, estas senales inicialmente tienen el valor U.
Inicialmente, la senal s3 esta indefinida. Toma el valor 0 en el instante 10+∆
ns, puesto que in1 e in2 valen 1 en el instante 10 ns. Finalmente, cambia al valor
1 en el instante 30 + ∆ ns.
La senal s4 va un ciclo retrasada respecto a s3.
La variable var1 toma los mismos valores que s3, excepto que la variable var1
no tiene el retardo delta (∆) de la variable s3.
La variable var2 toma los mismos valores que la variable var1.
2.8 Assert
La sentencia assert se usa para hacer comprobaciones de condiciones logicas que,
dado el valor esperado en ese punto del estado del programa, deberıan valer true.
Se emplea frecuentemente para depurar el codigo. Su sintaxis es:
assert <condicion_booleana> report <string>
severity <valor>;
Mientras la condicion booleana es true, la sentencia no realiza ninguna accion.
Cuando la condicion se hace false, la sentencia muestra el texto <string> en la
consola.
La clausula severity se usa para indicar que gravedad tiene la violacion de
la condicion booleana. Posibles valores de <valor> son:
note No es un error.
warning Aviso.
error Error.
failure Error severo que hace que termine la simulacion.
44 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
2.9 Procedimientos y funciones
Dos construcciones que pueden ser utiles en la descripcion de las arquitecturas
son los procedimientos (bloques procedure) y las funciones (function), ya que
contribuyen a hacer el codigo VHDL mas legible, portable y compacto.
Las funciones son usadas como operadores en las sentencias de asignacion,
mientras que los procedimientos son usandos de forma mas general, para describir
tareas que deben ejecutarse concurrentemente o tareas contenidas en bloques
process.
Las funciones y los procedimientos deben ser definidos dentro de la seccion
de declaracion de una architecture o de un bloque process. Es decir, tras la
sentencia architecture o process y antes del begin de esa arquitectura o bloque
process.
Los bloques procedure permiten a los disenadores manejar pequenos frag-
mentos de codigo reutilizable. Algunas de sus caracterısticas mas destacables son
las siguientes:
– Desde dentro de un procedimiento se puede acceder a todas las senales,
variables y constantes del bloque desde el que es llamado el procedimiento.
– Pueden pasarse argumentos (variables o senales) al procedimiento, que
pueden ser in, out e inout.
· Puede modificarse en el procedimiento el valor de los argumentos decla-
rados como out o inout, pero no el valor de los argumentos declarados
como in.
· Puede leerse en el procedimiento el valor de los argumentos declarados
como in o inout, pero no puede leerse dentro del procedimiento el
valor de los argumentos declarados como out.
· Si no se especifica la direccion de un argumento del procedimiento, se
asume por defecto que es in.
· Un argumento out o inout es por defecto una variable, a menos que
se indique explıcitamente que es una senal.
· Se considera que un argumento in es una constante dentro del bloque
del procedimiento. No obstante, si el argumento in es una senal, enton-
ces los cambios que se produzcan en la senal fuera del procedimiento se
produciran igualmente en el valor de la senal dentro del procedimiento.
– Dentro de un procedimiento pueden definirse variables locales, a las que no
se puede acceder desde fuera del procedimiento.
– A excepcion del uso de las variables locales, el efecto de usar un proce-
dimiento es equivalente a reemplazar la llamada al procedimiento por el
codigo del procedimiento.
Las dos diferencias fundamentales entre los procedimientos y las funciones en
VHDL son las siguientes:
Capıtulo 2 Conceptos basicos de VHDL 45
– La funcion debe devolver un valor al codigo que la llama.
– Los argumentos de la funcion deben ser de tipo in, con lo cual no es necesario
especificar su direccion.
El caso practico descrito en la Seccion 3.4 ilustra el empleo de procedimientos
y funciones.
3Casos prácticos de diseño de
circuitos combinacionales
Objetivos. Una vez estudiado el contenido del tema deberıa saber:
– Disenar circuitos logicos combinacionales empleando VHDL, tales como fun-
ciones logicas, multiplexores, sumadores y restadores binarios, buses, ALUs,
conversores de codigo y decodificadores, describiendo el comportamiento y/o
la estructura del circuito.
– Disenar y simular bancos de pruebas para circuitos combinacionales.
3.1 Síntesis de lógica combinacional
Cuando el objetivo de la descripcion del circuito mediante VHDL es la sıntesis,
es util saber como escribir codigo VHDL para crear determinadas estructuras
circuitales.
El comportamiento y las salidas de un bloque logico combinacional dependen
unicamente del valor actual de las entradas. No dependen del valor pasado de las
entradas, ni tampoco del estado.
Ası pues, el codigo VHDL que describe un circuito combinacional no de-
be tener “historia”, ni tampoco debe describir dependencia respecto al estado.
Tambien, debe evitarse incluir retardos temporales en la descripcion VHDL del
circuito, ya que los retardos del circuito real seran dependientes del hardware en
particular que se emplee para implementar el circuito.
Existen varios metodos para describir circuitos combinacionales en VHDL.
De hecho, el mismo tipo de circuito puede ser descrito empleando diferentes
sentencias VHDL. Por ejemplo, un multiplexor 2:1 puede definirse indicando su
estructura (conexion de las correspondientes puertas logicas) o describiendo su
48 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
comportamiento, mediante una sentencia concurrente de asignacion a una senal,
tal como:
out <= in1 when (sel=’1’) else in0;
A continuacion, se describe un metodo para la descripcion de circuitos combi-
nacionales que es sencillo de entender, aplicable de manera general y ampliamente
usado.
3.1.1 Empleo de sentencias concurrentes
Los circuitos logicos combinacionales pueden ser descritos empleando sentencias
concurrentes de asignacion a senales. Este tipo de sentencias modelan de manera
correcta el comportamiento de los dispositivos combinacionales, que estan activos
durante todo el tiempo de manera concurrente.
– En la parte izquierda de una sentencia de asignacion concurrente debe
aparecer, o bien una senal local de la architecture, o bien una senal de la
interfaz (definida en la entity) del tipo out o inout.
– En la parte derecha de la asignacion concurrente pueden aparecer senales
locales de la architecture y tambien senales de la interfaz, del tipo in o
inout.
Las herramientas de sıntesis pueden sintetizar las puertas logicas simples a
partir de las operaciones logicas primitivas de VHDL. A continuacion, se muestran
dos ejemplos:
Puerta NAND nand_out <= i0 nand i1;
Puerta OR-exclusiva xor_out <= i0 xor i1;
Tambien, pueden sintetizarse arrays de puertas logicas a partir de este mis-
mo tipo de sentencias. Por ejemplo, la siguiente sentencia describe un array de
inversores:
Array de inversores inv_vec <= not i0_vec;
donde inv_vec e i0_vec son std logic vector.
El que la herramienta de sıntesis cree una unica puerta logica o un array de
puertas logicas, depende del tipo de senales usadas en la sentencia de asignacion
concurrente. Por ejemplo, las siguientes sentencias dan lugar a un buffer triestado
y a un array de buffers triestado, respectivamente.
Buffer triestado tri_out <= i0 when (sel=’1’) else ’Z’;
Array de buffers triestado tri_vec <= i0_vec when (sel=’1’)
else (others => ’Z’);
donde tri_vec e i0_vec son std logic vector.
Es posible sintetizar multiplexores y decodificadores que estan descritos me-
diante sentencias condicionales del tipo siguiente:
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 49
Decodificador 2:4 dec_vec <= "0001" when (sel_vec = "00")
else "0010" when (sel_vec = "01")
else "0100" when (sel_vec = "10")
else "1000";
y tambien es posible emplear sentencias with, por ejemplo:
Multiplexor 4:1 with sel_vec select
mux41_out <= i0 when "00",
i1 when "01",
i2 when "10",
i3 when others;
De hecho, es preferible usar clausulas with para describir multiplexores y
decodificadores, ya que el empleo de clausulas condicionales puede dar lugar
a la sıntesis de circuitos innecesariamente complejos. Esto es debido a que las
condiciones de las clausulas condicionales en general no tienen que ser excluyentes
entre sı, cosa que sı sucede siempre con las condiciones de las clausulas with.
Es posible tambien realizar una descripcion del circuito basada unicamente
en la operacion que se desea que realice. Por ejemplo:
Multiplexor 4:1 mux41_out <= i0_vec( TO_INTEGER(unsigned(sel_vec)) );
donde i0_vec y sel_vec son std logic vector.
donde se emplean las funciones de conversion de tipo TO INTEGER y unsig-
ned, que estan definidas en el package IEEE.numeric std.
Finalmente, los circuitos que realizan operaciones aritmeticas pueden ser des-
critos aplicando las correspondientes operaciones aritmeticas a los tipos de datos
adecuados. Por ejemplo, los operandos std logic vector deben ser convertidos
a unsigned antes de emplear los operandos suma o multiplicacion. Por ejemplo:
Sumador add_uvec <= unsigned(i0_vec) + i1_uvec;
donde i1_uvec y add_uvec son unsigned.
Multiplicador mult_uvec <= unsigned(i0_vec) * i1_uvec;
donde i1_uvec y mult_uvec son unsigned.
Sin embargo, este tipo de descripcion da lugar a la sıntesis de los tipos estandar
de circuitos aritmeticos. Dependiendo de la opcion seleccionada en la sıntesis, las
unidades aritmeticas sintetizadas pueden ser circuitos lentos que usan un numero
pequeno de puertas logicas (si se escoge la opcion “optimizar el area”) o bien
circuitos rapidos que utilizan gran numero de puertas logicas (se se escoge la
opcion “optimizar la velocidad”).
Para crear tipos especıficos de unidades aritmeticas, tales como tipos especia-
les de sumadores o multiplicadores rapidos, puede ser necesario describirlos o bien
indicando su estructura, o bien mediante una descripcion de su comportamiento
a mas bajo nivel, tal como se explica a continuacion.
50 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3.1.2 Empleo de bloques process
Aunque las sentencias concurrentes de asignacion a senal son utiles para crear
estructuras combinacionales simples, es necesario disponer de otro metodo para
crear circuitos mas complejos. En concreto, cierto numero de clausulas de VHDL
(tales como if, case, for, etc.) solo pueden ser usadas dentro de bloques process.
Los bloques process pueden ser usados para describir logica combinacional.
Para que el circuito resultante de la sıntesis sea combinacional, deben respetarse
las siguientes reglas:
1. Todas las entradas del circuito deben estar incluidas en la lista de senales
a las que es sensible el bloque process.
2. Ninguna otra senal debe estar incluida en dicha lista.
3. Ninguna de las sentencias internas al bloque process debe ser sensible al
flanco de subida o de bajada de ninguna senal.
A continuacion, se muestran varios ejemplos sencillos de diseno de circuitos
combinacionales, empleando tanto sentencias concurrentes como bloques pro-
cess.
3.2 Funciones lógicas
En esta seccion se describe el modelado de dos funciones logicas y de su banco
de pruebas. Las dos funciones logicas (F y G), que dependen de 3 variables (a, b
y c), son las siguientes:
F = a and b or not c
G = a and b or not b and c
3.2.1 Modelado de las funciones lógicas
A continuacion se muestra el codigo VHDL que describe las funciones logicas.
Observese que el orden en el cual deben realizarse las operaciones booleanas
debe indicarse explıcitamente mediante parentesis en el codigo VHDL (en caso
contrario se obtiene error). Es decir, las funciones logicas deben escribirse de la
forma siguiente:
F = ( a and b ) or not c
G = ( a and b ) or ( not b and c )
--------------------------------------
-- Funciones logicas:
-- F = ab + c’
-- G = ab + b’c
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 51
library IEEE; use IEEE.std_logic_1164.all;
entity funcLog_F_G is port
( F, G : out std_logic;
a, b, c : in std_logic );
end entity funcLog_F_G;
architecture funcLog_F_G of funcLog_F_G is
begin
F <= (a and b) or not c;
G <= (a and b) or (not b and c);
end architecture funcLog_F_G;
--------------------------------------
La interfaz externa del circuito que implementa las funciones logicas es des-
crita en la entity llamada funcLog_F_G. En ella se declaran los dos puertos de
salida (F, G) seguidos de los tres puertos de entrada (a, b, c). Todos los puertos
son del tipo std logic ya que representan senales transmitidas por el cableado
de los circuitos.
La definicion de la architecture comienza especificando el nombre de la
entity. En este caso, se ha dado el mismo nombre a la entity y a la architecture.
En general se les puede dar nombres diferentes.
En el cuerpo de la architecture (es decir, a continuacion de la palabra
reservada begin) se describe como se calculan los puertos de salida a partir de
los puertos de entrada.
3.2.2 Programación del banco de pruebas
Una vez modelado el circuito, debe programarse su banco de pruebas. Puesto que
el banco de pruebas no va a ser sintetizado, puede emplearse para su programa-
cion cualquier instruccion VHDL disponible (incluso aquellas que darıan lugar
a circuitos no sintetizables). Instrucciones utiles de este tipo son wait, assert y
report, que permiten controlar el progreso de la simulacion, comprobar y mostrar
sus resultados.
En este caso, la finalidad del banco de pruebas es unicamente generar las
23 posibles entradas al circuito. Normalmente, los propios programas de test
contienen los algoritmos necesarios para determinar si las salidas del circuito
son las esperadas y muestran los correspondientes mensajes en aquellos casos en
que no lo sean. Por simplicidad, en este caso esta labor la asume el disenador.
Es decir, observando las senales de salida del circuito y comparando con la tabla
de la verdad de las funciones logicas, el disenador determina si el funcionamiento
del circuito es el esperado.
Como programa VHDL, el banco de pruebas es un tipo especial de pareja
entity-architecture, que no tiene ni entradas ni salidas externas. Por este
motivo, la entity del banco de pruebas no contiene ningun puerto.
52 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Internamente, el banco de pruebas tiene conexiones al UUT. Se han definido
senales internas al banco de pruebas para todas las conexiones al UUT:
signal y0, y1 : std_logic; -- Conectar salidas UUT
signal x0, x1, x2 : std_logic; -- Conectar entradas UUT
La conexion del UUT en el banco de pruebas se realiza instanciando el UUT
como un subcircuito dentro del banco de pruebas. En este caso, la conexion se
realiza nombrando explıcitamente los puertos:
uut : component funcLog_F_G port map
( F => y0, G => y1,
a => x0, b => x1, c => x2 );
Observese que la senal y su puerto asociado son incluidos en la lista de
parametros de la forma siguiente:
puerto => se~nal
La architecture del banco de pruebas contiene un proceso (bloque process)
en el cual se generan los vectores de test y se introducen como entradas del UUT.
A continuacion, se muestra el codigo VHDL del banco de pruebas.
--------------------------------------
-- Banco de pruebas
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_funcLog_F_G is
end entity bp_funcLog_F_G;
architecture bp_funcLog_F_G of bp_funcLog_F_G is
signal y0, y1 : std_logic; -- Conectar salidas UUT
signal x0, x1, x2 : std_logic; -- Conectar entradas UUT
component funcLog_F_G is port
( F, G : out std_logic;
a, b, c : in std_logic);
end component funcLog_F_G;
begin
-- Instanciar y conectar UUT
uut : component funcLog_F_G port map
( F => y0, G => y1,
a => x0, b => x1, c => x2 );
gen_vec_test : process
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 53
variable test_in : unsigned (2 downto 0); -- Vector de test
begin
test_in := B"000";
for count in 0 to 7 loop
x2 <= test_in(2);
x1 <= test_in(1);
x0 <= test_in(0);
wait for 10 ns;
test_in := test_in + 1;
end loop;
wait;
end process gen_vec_test;
end architecture bp_funcLog_F_G;
--------------------------------------
El bloque process se emplea para encapsular una secuencia de sentencias que
seran ejecutadas secuencialmente. En el codigo del banco de pruebas, el bloque
process tiene la estructura siguiente:
gen_vec_test : process
variable ...
begin
...
end process gen_vec_test;
donde las variables se declaran antes de la palabra reservada begin, y las senten-
cias a ejecutar secuencialmente se escriben a continuacion de la palabra begin.
Una variable (variable) es conceptualmente diferente a una senal (signal),
puesto que la variable puede no corresponder con una senal fısica. La variable
simplemente se usa como ayuda en la descripcion de la operacion del circuito. La
asignacion a una variable se representa mediante :=, mientras que la asignacion
a una senal se representa mediante <=.
En el codigo del banco de pruebas, la variable test_in se usa para almacenar
en un mismo vector de tres bits las entradas al UUT, de modo que este vector
pueda ser incrementado (con el fin de generar todas las posibles combinaciones de
vectores de test) empleando un bucle for. Observa que la variable test_in se ha
declarado de tipo unsigned ya que se emplea para realizar operaciones aritmeticas.
La longitud del vector se especifica por el rango (2 downto 0). El primer numero
del rango (2) indica el ındice del bit mas significativo del vector, y el segundo
numero del rango (0) indica el ındice del bit menos significativo del vector.
La sentencia for en VHDL tiene el formato siguiente:
for <variable> in <rango> loop
...
end loop;
donde <variable> es una nueva variable temporal, con un rango entero (<rango>),
que no necesita ser definida previamente.
54 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
La sentencia wait se emplea para esperar durante un numero determinado de
unidades de tiempo. En el codigo del banco de pruebas, se emplea
wait for 10 ns;
para esperar hasta que el UUT pueda producir las salidas correspondientes a las
entradas aplicadas. En este caso, podrıa haberse escogido cualquier otro tiempo
de espera, ya que en el modelo del UUT no se especifico ningun retardo.
La segunda sentencia wait, que esta situada al final de codigo, no tiene
ninguna indicacion acerca del tiempo que hay que esperar. Este tipo de sentencia
wait se emplea para detener el proceso, ya que “espera para siempre”.
Como resultado de la simulacion del banco de pruebas, se obtienen las formas
de onda mostradas en la Figura 3.1.
Figura 3.1: Formas de onda obtenidas de simular el banco de pruebas.
3.3 Multiplexor de 4 entradas
En la Figura 3.2 se muestra un multiplexor de 4 entradas (i3, i2, i1, i0), dos
entradas de seleccion (s1, s0) y una salida (d). En esta seccion se describen
diferentes maneras de modelar el multiplexor, ası como bancos de pruebas que
permite simular tests sobre los modelos del circuito.
i0i1i2i3
d
s0 s1
ghijkl
Figura 3.2: Multiplexor de 4 entradas.
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 55
3.3.1 Bloque process, sentencia if
A continuacion, se muestra el codigo VHDL del MUX 4:1 que describe el com-
portamiento del multiplexor mediante una sentencia if incluida en un bloque
process.
--------------------------------------
-- MUX 4x1
library IEEE; use IEEE.std_logic_1164.all;
entity mux_4x1 is port
( d : out std_logic;
i3, i2, i1, i0 : in std_logic;
s1, s0 : in std_logic );
end entity mux_4x1;
architecture mux_4x1 of mux_4x1 is
begin
process (i3, i2, i1, i0, s1, s0)
begin
if (s1=’0’and s0=’0’) then
d <= i0;
elsif (s1=’0’and s0=’1’) then
d <= i1;
elsif (s1=’1’and s0=’0’) then
d <= i2;
else
d <= i3;
end if;
end process;
end architecture mux_4x1;
--------------------------------------
Observese que el bloque process es sensible a las senales i3, i2, i1, i0, s1,
s0. Esto significa que se ejecutara el contenido del bloque cada vez que alguna
de estas senales cambie de valor.
A continuacion, se muestra el codigo de un banco de prueba que aplica algunos
vectores de test al multiplexor (es solo un pequeno ejemplo, no se trata de un
programa de test exhaustivo para este circuito).
--------------------------------------
-- Banco de pruebas
library IEEE;
use IEEE.std_logic_1164.all;
56 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
use IEEE.numeric_std.all;
entity bp_mux_4x1 is
end entity bp_mux_4x1;
architecture bp_mux_4x1 of bp_mux_4x1 is
signal d : std_logic; -- Conectar salida UUT
signal i0, i1, i2, i3,
s0, s1 : std_logic; -- Conectar entradas UUT
component mux_4x1 is port
( d : out std_logic;
i3, i2, i1, i0 : in std_logic;
s1, s0 : in std_logic );
end component mux_4x1;
begin
-- Instanciar y conectar UUT
uut : component mux_4x1 port map
( d => d,
i0 => i0, i1 => i1, i2 => i2, i3 => i3,
s0 => s0, s1 => s1 );
gen_vec_test : process
begin
i0 <= ’0’; i1 <= ’0’; i2 <= ’1’; i3 <= ’0’;
s0 <= ’0’; s1 <= ’0’;
wait for 5 ns;
i0 <= ’1’;
wait for 5 ns;
s0 <= ’1’;
wait for 10 ns;
s0 <= ’0’; s1 <= ’1’;
wait for 10 ns;
s0 <= ’1’;
wait;
end process gen_vec_test;
end architecture bp_mux_4x1;
--------------------------------------
En la Figura 3.3a se muestran las formas de onda obtenidas al simular el
banco de pruebas.
Un error que se comete a veces consiste en olvidar incluir en la lista
alguna de las variables a las que es sensible el bloque process. La consecuencia
de este error es que el bloque process no se ejecutara cuando cambie el valor de
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 57
la variable no incluida en la lista, con lo cual el modelo simulado no reproducira
correctamente el circuito real.
Por ejemplo, supongamos que en el modelo del multiplexor no se incluyen las
entradas i3, i2, i1, i0 en la lista de variables a las que es sensible el bloque
process. Es decir, supongamos que por error la architecture del multiplexor se
define de la forma siguiente:
--------------------------------------
-- MUX 4x1
-- ERROR al definir la sensibilidad del bloque process
architecture mux_4x1 of mux_4x1 is
begin
process (s1, s0) -- Error: no se incluyen i3,i2,i1,i0
begin
if (s1=’0’and s0=’0’) then
d <= i0;
elsif (s1=’0’and s0=’1’) then
d <= i1;
elsif (s1=’1’and s0=’0’) then
d <= i2;
else
d <= i3;
end if;
end process;
end architecture mux_4x1;
--------------------------------------
Este modelo no reproduce adecuadamente el comportamiento de un multi-
plexor, como puede observarse en la Figura 3.3b. Observese que es este caso la
salida d no reproduce el cambio en el valor de la entrada i0 que se produce en
el instante 5 ns. En el instante 5 ns la entrada i0 pasa de valer ’0’ a valer ’1’,
mientras que el valor de la salida d no cambia: sigue siendo ’0’. Esto es debido a
que el cambio en el valor de i0 no dispara la ejecucion del bloque process, con
lo cual el valor de la salida no se actualiza al nuevo valor de la entrada i0.
3.3.2 Bloque process, sentencias if y case
A continuacion, se muestra el codigo VHDL del MUX 4:1 que describe el com-
portamiento del multiplexor mediante sentencias if y case incluidas en un bloque
process.
--------------------------------------
-- MUX 4x1
library IEEE; use IEEE.std_logic_1164.all;
58 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
m n
o nFigura 3.3: Formas de onda obtenidas de simular el banco de pruebas:a) modelo del multiplexor correcto; b) modelo del multiplexor erroneo.
entity mux_4x1 is port
( d : out std_logic;
i3, i2, i1, i0 : in std_logic;
s1, s0 : in std_logic );
end entity mux_4x1;
architecture mux_4x1 of mux_4x1 is
begin
process (i3, i2, i1, i0, s1, s0)
variable sel : integer;
begin
if (s1=’0’and s0=’0’) then
sel := 0;
elsif (s1=’0’and s0=’1’) then
sel := 1;
elsif (s1=’1’and s0=’0’) then
sel := 2;
else
sel := 3;
end if;
case sel is
when 0 =>
d <= i0;
when 1 =>
d <= i1;
when 2 =>
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 59
d <= i2;
when others =>
d <= i3;
end case;
end process;
end architecture mux_4x1;
--------------------------------------
3.3.3 Sentencias concurrentes
A continuacion, se muestra la descripcion del circuito multiplexor usando una
sentencia concurrente, en la cual se asigna valor a la senal d en funcion del valor
que tomen las entradas al circuito.
--------------------------------------
-- MUX 4x1
library IEEE; use IEEE.std_logic_1164.all;
entity mux_4x1 is port
( d : out std_logic;
i3, i2, i1, i0 : in std_logic;
s1, s0 : in std_logic );
end entity mux_4x1;
architecture mux_4x1_concurrente of mux_4x1 is
begin
d <= i0 when (s1=’0’and s0=’0’) else
i1 when (s1=’0’and s0=’1’) else
i2 when (s1=’1’and s0=’0’) else
i3;
end architecture mux_4x1_concurrente;
--------------------------------------
Con el fin de ilustrar el empleo de senales del tipo integer, a continuacion
se muestra una variacion del modelo anterior en el cual se describe el comporta-
miento del circuito mediante dos sentencias concurrentes. En la primera, se asigna
valor a la senal integer sel en funcion del valor de las entradas de seleccion. En
la segunda, se asigna valor a la salida del circuito en funcion de las entradas de
datos y del valor de la senal entera. A continuacion se muestra el codigo.
--------------------------------------
-- MUX 4x1
library IEEE; use IEEE.std_logic_1164.all;
60 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 3.4: Formas de onda obtenidas de simular el banco de pruebas,empleando la descripcion del comportamiento del multiplexor.
entity mux_4x1 is port
( d : out std_logic;
i3, i2, i1, i0 : in std_logic;
s1, s0 : in std_logic );
end entity mux_4x1;
architecture mux_4x1_concurrente of mux_4x1 is
signal sel : integer;
begin
sel <= 0 when (s1=’0’and s0=’0’) else
1 when (s1=’0’and s0=’1’) else
2 when (s1=’1’and s0=’0’) else
3;
d <= i0 when sel = 0 else
i1 when sel = 1 else
i2 when sel = 2 else
i3;
end architecture mux_4x1_concurrente;
--------------------------------------
En la Figura 3.4 se muestran las formas de onda resultado de la simulacion.
3.4 Restador completo de 1 bit
En esta seccion se describe el modelado de un circuito restador completo de 1
bit y de su banco de pruebas. Emplearemos este caso de estudio para introducir
algunos conceptos nuevos.
VDHL permite describir la architecture de un circuito mediante su com-
portamiento y tambien mediante su estructura, es decir, indicando como estan
conectados los subcircuitos que lo componen. En primer lugar se realizara una
descripcion del circuito basada en el comportamiento y, a continuacion, se hara
una descripcion basada en su estructura.
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 61
3.4.1 Descripción del comportamiento
A continuacion se muestra la tabla de la verdad del circuito restador de 1 bit.
Este circuito calcula el resultado (res) y el acarreo (acarreo) obtenidos de realizar
la resta (a–b) de dos bits (a,b).
a b res acarreo
0 0 0 0
0 1 1 1
1 0 1 0
1 1 0 0
Un circuito restador completo de 1 bit tiene una entrada adicional: el acarreo
de entrada. Conectando varios de estos circuitos, puede obtenerse un restador de
numeros de varios bits. A continuacion, se muestra el codigo VHDL de un restador
completo de 1 bit. Observese que la architecture describe el funcionamiento del
circuito, sin entrar en detalles acerca de su implementacion.
-----------------------------------------
-- Restador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity rest_completo is port
( res, acarreo_out : out std_logic;
a, b, acarreo_in : in std_logic);
end entity rest_completo;
architecture rest_completo_comport of rest_completo is
signal result : unsigned ( 1 downto 0 );
begin
result <= (’0’ & a) - (’0’ & b) - (’0’ & acarreo_in);
acarreo_out <= result(1);
res <= result(0);
end architecture rest_completo_comport;
-----------------------------------------
La interfaz externa del restador completo es descrita en la entity llamada
rest_completo. En ella se definen los dos puertos de salida (res, acarreo_out)
seguidos de los tres puertos de entrada (a, b, acarreo_in). Todos los puertos de
entrada y de salida se definen del tipo std logic, con el fin de facilitar el uso del
restador como subcircuito en otros circuitos: se emplean senales del tipo std logic
y std logic vector para modelar las senales transmitidas por el cableado de los
circuitos fısicos.
62 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
La definicion de la architecture incluye el nombre de la entity. Se define
una senal del tipo unsigned de 2 bits (llamada result), con el fin de almacenar
el resultado de la operacion de sustraccion. Al declararla, se indica que la senal
tiene 2 bits, especificando para ello su rango: ( 1 downto 0 ). Si no se especifica
el rango, las senales del tipo unsigned tienen por defecto 32 bits.
El tipo de la senal debe ser unsigned, a fin de permitir el uso del operador
sustraccion (–).
Las senales de entrada, de 1 bit, deben ser extendidas a 2 bits (concatenando
un 0), de modo que el resultado de la resta pueda ser almacenado en una senal
de 2 bits del tipo unsigned.
Finalmente, el resultado de la resta se asigna a res y acarreo_out. Observese
que es posible realizar las asignaciones:
acarreo_out <= result(1);
res <= result(0);
porque cada elemento de una senal del tipo unsigned es del tipo std logic, que
es exactamente el tipo de las senales res y acarreo_out.
3.4.2 Descripción de la estructura
En la Figura 3.5 se muestra un circuito restador completo de 1 bit. Para su
definicion, se emplean puertas OR-exclusiva de 2 entradas (xor2), AND de dos
entradas (and2), OR de tres entradas (or3) e inversor (not1).
pq
p r p s s t u v wxs t y
p r p s s t u v u z {|
t}
rx u { v p
~ �~ �
~ �
~ �
~ �~ �
~ �
Figura 3.5: Diagrama de un circuito restador completo de 1 bit.
Observese que, a fin de facilitar la descripcion del modelo, se han etiquetado
las senales internas (not a, c, d, e, f) y las puertas logicas (g0, ..., g6). La definicion
de la entity y architecture de cada una de estas puertas logicas se muestra a
continuacion.
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 63
--------------------------------------
-- OR exclusiva de 2 entradas: xor2
library IEEE; use IEEE.std_logic_1164.all;
entity xor2 is port
( y0 : out std_logic;
x0, x1 : in std_logic );
end entity xor2;
architecture xor2 of xor2 is
begin
y0 <= x0 xor x1;
end architecture xor2;
--------------------------------------
--------------------------------------
-- Inversor de 1 entrada: not1
library IEEE; use IEEE.std_logic_1164.all;
entity not1 is port
( y0 : out std_logic;
x0 : in std_logic );
end entity not1;
architecture not1 of not1 is
begin
y0 <= not x0;
end architecture not1;
--------------------------------------
--------------------------------------
-- AND de 2 entradas: and2
library IEEE; use IEEE.std_logic_1164.all;
entity and2 is port
( y0 : out std_logic;
x0, x1 : in std_logic );
end entity and2;
architecture and2 of and2 is
begin
y0 <= x0 and x1;
end architecture and2;
--------------------------------------
64 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
--------------------------------------
-- OR de 3 entradas: or3
library IEEE; use IEEE.std_logic_1164.all;
entity or3 is port
( y0 : out std_logic;
x0, x1, x2 : in std_logic );
end entity or3;
architecture or3 of or3 is
begin
y0 <= x0 or x1 or x2;
end architecture or3;
--------------------------------------
Para componer el circuito restador usando las puertas logicas anteriores, es
necesario instanciar los componentes necesarios y conectarlos. Para ello, es preciso
escribir la entity de cada uno de los componentes, instanciar los componentes y
describir la conexion entre ellos. A continuacion, se muestra el codigo del circuito
restador, donde la architecture describe la estructura del circuito.
-----------------------------------
-- Restador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity rest_completo is port
( res, acarreo_out : out std_logic;
a, b, acarreo_in : in std_logic);
end entity rest_completo;
architecture rest_completo_estruc of rest_completo is
signal not_a, c, d, e, f : std_logic;
-- Declaracion de las clases de los componentes
component xor2 is port
( y0 : out std_logic;
x0, x1 : in std_logic );
end component xor2;
component not1 is port
( y0 : out std_logic;
x0 : in std_logic );
end component not1;
component and2 is port
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 65
( y0 : out std_logic;
x0, x1 : in std_logic );
end component and2;
component or3 is port
( y0 : out std_logic;
x0, x1, x2 : in std_logic );
end component or3;
begin
-- Instanciacion y conexion de los componentes
g0 : component xor2 port map (c, a, b);
g1 : component xor2 port map (res, c, acarreo_in);
-- g2 : component not1 port map (not_a, a);
g2 : component not1 port map (y0 => not_a, x0 => a);
g3 : component and2 port map (d, not_a, acarreo_in);
g4 : component and2 port map (e, not_a, b);
g5 : component and2 port map (f, b, acarreo_in);
g6 : component or3 port map (acarreo_out, d, e, f);
end architecture rest_completo_estruc;
-----------------------------------
En el modelo anterior, se realiza la conexion entre los componentes mediante
asociacion posicional. Es posible tambien usar asignacion implıcita. Por ejemplo:
g2 : component not1 port map (y0 => not_a, x0 => a);
3.4.3 Programación del banco de pruebas
En este caso, en el codigo del banco de pruebas se comprueban las salidas ob-
tenidas del UUT con las salidas esperadas. Es decir, el propio banco de pruebas
comprueba si el comportamiento del circuito es correcto y en caso de que no lo
sea generara el correspondiente mensaje. Se usara la descripcion estructural del
restador para modelar el UUT, y su descripcion del comportamiento para obtener
las salidas “correctas”, que se compararan con las salidas del UUT.
La architecture del banco de pruebas contiene un proceso (bloque process)
en el cual se generan los vectores de test, se introducen como entradas del UUT y
se comprueban las salidas del UUT. A continuacion, se muestra el codigo VHDL
del banco de pruebas.
--------------------------------------------------
-- Banco de pruebas del restador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_rest_completo is -- El banco de pruebas no tiene
66 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
end entity bp_rest_completo; -- ni entradas ni salidas
architecture bp_rest_completo of bp_rest_completo is
signal res, acarreo_out : std_logic; -- Para conectar el UUT
signal a, b, acarreo_in : std_logic; -- Para conectar el UUT
component rest_completo is port
( res, acarreo_out : out std_logic;
a, b, acarreo_in : in std_logic);
end component rest_completo;
begin
-- Instanciar y conectar UUT
uut : component rest_completo port map
(res, acarreo_out, a, b, acarreo_in);
-- Crear vectores de test y comprobar salidas del UUT
gen_vec_test : process
variable test_in : unsigned (2 downto 0); -- Vector de test
variable esperado : unsigned (1 downto 0); -- Salida esperada
variable num_errores : integer := 0; -- Numero de errores
begin
test_in := B"000";
for count in 0 to 7 loop
a <= test_in(2);
b <= test_in(1);
acarreo_in <= test_in(0);
wait for 10 ns;
esperado := (’0’ & a) - (’0’ & b) - (’0’ & acarreo_in);
if (esperado /= ( acarreo_out & res )) then -- Comprueba resultado
report "ERROR : Esperado (" & -- Report del error
std_logic’image(esperado(1)) &
std_logic’image(esperado(0)) &
") /= actual (" &
std_logic’image(acarreo_out) &
std_logic’image(res) &
") en el instante " &
time’image(now);
num_errores := num_errores + 1;
end if;
test_in := test_in + 1;
end loop;
report "Test completo. Hay " &
integer’image(num_errores) &
" errores.";
wait;
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 67
end process gen_vec_test;
end architecture bp_rest_completo;
--------------------------------------------------
El banco de pruebas no tiene ni entradas ni salidas externas. Por ese motivo,
la entity del banco de pruebas no contiene ningun puerto (port):
entity bp_rest_completo is
end entity bp_rest_completo;
La conexion del UUT en el banco de pruebas se realiza instanciando el restador
binario como un subcircuito dentro del banco de pruebas. Aunque la conexion
se realiza mediante asociacion posicional, podrıa haberse realizado la asociacion
nombrando explıcitamente los puertos:
uut : component rest_completo port map
(res => res, acarreo_out => acarreo_out,
a => a, b => b, acarreo_in => acarreo_in);
Se han definido senales internas al banco de pruebas para todas las conexiones
al UUT. Aunque en este ejemplo si lo sean, los nombres de las senales no tienen
que ser identicos a los nombres de los puertos del UUT.
Se ha definido un proceso (process) para generar las formas de onda de las
entradas al UUT, y en ese mismo proceso se han incluido las sentencias para
comprobar si las salidas del UUT coinciden con las esperadas.
Es esencial tener en cuenta que el metodo empleado para calcular las sali-
das “esperadas” del UUT debe ser diferente del metodo empleado en el propio
UUT para obtener las salidas. En este ejemplo, el UUT contiene una descripcion
estructural de la arquitectura del restador, mientras que las salidas “esperadas”
(variable esperado) se calculan a partir de una descripcion del comportamiento
del restador:
esperado := (’0’ & a) - (’0’ & b) - (’0’ & acarreo_in);
El comando report se usa para escribir texto en la consola. El argumento
del comando (esto es, el texto a escribir) debe ser del tipo string. Por ejemplo,
cadenas de caracteres concatenadas mediante el operador &. Por ello, todo lo que
se desee mostrar deben ser convertido previamente al tipo string.
Por ejemplo, std_logic’image(res) se usa para convertir el valor de res,
que es del tipo std logic, a un dato del tipo string.
Asimismo, now es una funcion predefinida que devuelve el tiempo simulado
como un dato del tipo time. Puede usarse time’image(now) para obtener una
representacion del tipo string del tiempo actual de la simulacion.
Como resultado de la simulacion del banco de pruebas, se obtienen las formas
de onda y el mensaje en la consola mostrados en la Figura 3.6.
68 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 3.6: Formas de onda y mensaje en la consola obtenidos de simularel banco de pruebas.
3.4.4 Banco de pruebas usando un procedimiento
Frecuentemente, en un banco de pruebas es preciso comparar el valor esperado de
una senal con el valor obtenido de la simulacion del circuito. Si ambos valores no
coinciden, entonces se muestra un mensaje de error y se incrementa el contador
del numero de errores.
A continuacion, se muestra el codigo del banco de pruebas para el circuito
restador completo de 1 bit, programado empleando un procedimiento que realiza
la comparacion entre el valor esperado y el actual, y que, en su caso, muestra los
correspondientes mensajes de error.
--------------------------------------------------
-- Banco de pruebas del restador completo de 1 bit
-- empleando un procedimiento
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_rest_completo is -- El banco de pruebas no tiene
end entity bp_rest_completo; -- ni entradas ni salidas
architecture bp_rest_completo_procedure of bp_rest_completo is
signal res, acarreo_out : std_logic; -- Para conectar el UUT
signal a, b, acarreo_in : std_logic; -- Para conectar el UUT
procedure error_check( esperado, actual : in unsigned;
num_errores : inout integer ) is
begin
if (esperado /= actual) then -- Comprueba resultado
report "ERROR : Esperado (" & -- Report del error
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 69
std_logic’image(esperado(1)) &
std_logic’image(esperado(0)) &
") /= actual (" &
std_logic’image(actual(1)) &
std_logic’image(actual(0)) &
") en el instante" &
time’image(now);
num_errores := num_errores + 1;
end if;
end procedure error_check;
component rest_completo is port
( res, acarreo_out : out std_logic;
a, b, acarreo_in : in std_logic);
end component rest_completo;
begin
-- Instanciar y conectar UUT
uut : component rest_completo port map
(res, acarreo_out, a, b, acarreo_in);
-- Crear vectores de test y comprobar salidas del UUT
gen_vec_test : process
variable test_in : unsigned (2 downto 0); -- Vector de test
variable esperado : unsigned (1 downto 0); -- Salida esperada
variable num_errores : integer := 0; -- Numero de errores
begin
test_in := B"000";
for count in 0 to 7 loop
a <= test_in(2);
b <= test_in(1);
acarreo_in <= test_in(0);
wait for 10 ns;
esperado := (’0’ & a) - (’0’ & b) - (’0’ & acarreo_in);
error_check( esperado, acarreo_out & res, num_errores );
test_in := test_in + 1;
end loop;
report "Test completo. Hay " &
integer’image(num_errores) &
" errores.";
wait;
end process gen_vec_test;
end architecture bp_rest_completo_procedure;
--------------------------------------------------
70 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3.4.5 Banco de pruebas usando una función
El codigo anterior del banco de pruebas puede modificarse con el fin de emplear
una funcion en lugar de un procedimiento. A continuacion, se muestra una posible
forma de modificar el codigo. Observese que se ha sustituido la clausula if, que
compara el valor esperado con el valor actual, por una sentencia assert. El motivo
es unicamente ilustrar el uso de assert.
--------------------------------------------------
-- Banco de pruebas del restador completo de 1 bit
-- empleando un procedimiento
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_rest_completo is -- El banco de pruebas no tiene
end entity bp_rest_completo; -- ni entradas ni salidas
architecture bp_rest_completo_funcion of bp_rest_completo is
signal res, acarreo_out : std_logic; -- Para conectar el UUT
signal a, b, acarreo_in : std_logic; -- Para conectar el UUT
function error_check( esperado, actual : unsigned;
tnow : time ) return integer is
begin
assert ( esperado = actual ) -- Comprobacion usando assert
report "ERROR : Esperado (" & -- Report del error
std_logic’image(esperado(1)) &
std_logic’image(esperado(0)) &
") /= actual (" &
std_logic’image(actual(1)) &
std_logic’image(actual(0)) &
") en el instante " &
time’image(tnow)
severity error; -- Opcion severity
if ( esperado /= actual ) then
return 1; -- Indica error
else
return 0; -- Indica que no hay error
end if;
end function error_check;
component rest_completo is port
( res, acarreo_out : out std_logic;
a, b, acarreo_in : in std_logic);
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 71
end component rest_completo;
begin
-- Instanciar y conectar UUT
uut : component rest_completo port map
(res, acarreo_out, a, b, acarreo_in);
-- Crear vectores de test y comprobar salidas del UUT
gen_vec_test : process
variable test_in : unsigned (2 downto 0); -- Vector de test
variable esperado : unsigned (1 downto 0); -- Salida esperada
variable num_errores : integer := 0; -- Numero de errores
begin
test_in := B"000";
for count in 0 to 7 loop
a <= test_in(2);
b <= test_in(1);
acarreo_in <= test_in(0);
wait for 10 ns;
esperado := (’0’ & a) - (’0’ & b) - (’0’ & acarreo_in);
num_errores := num_errores +
error_check( esperado, acarreo_out & res, now );
test_in := test_in + 1;
end loop;
report "Test completo. Hay " &
integer’image(num_errores) &
"errores.";
wait;
end process gen_vec_test;
end architecture bp_rest_completo_funcion;
--------------------------------------------------
3.5 Sumador binario paralelo con propagación dearrastre
En esta seccion se describe el modelo de un sumador de 4 bits, compuesto a
partir de la conexion de cuatro sumadores completos de 1 bit. En primer lugar se
realizara el modelo del sumador completo de 1 bit mediante la conexion de puertas
logicas AND, OR y XOR. A continuacion, se usara este modelo de sumador
completo para componer el sumador de 4 bits.
72 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3.5.1 Diseño de un sumador completo
Un sumador completo es un circuito con tres bits de entrada (xi, yi, ci) y dos
salida: el bit suma (si) y el bit acarreo (Ci+1). El funcionamiento del circuito esta
descrito por la tabla de la verdad siguiente:
ci xi yi ci+1 si
0 0 0 0 0
0 0 1 0 1
0 1 0 0 1
0 1 1 1 0
1 0 0 0 1
1 0 1 1 0
1 1 0 1 0
1 1 1 1 1
Simplificando las funciones logicas mediante mapas de Karnaugh, se llega a
las expresiones siguientes:
ci+1 = xiyi + xici + yici
si = xi ⊕ yi ⊕ ci
En la Figura 3.7 se muestra el circuito del sumador completo.
������ ��
���+
��
��
��
��
Figura 3.7: Sumador completo.
Las puertas logicas AND, OR y XOR se modelan con un retardo de 10 ns. A
continuacion, se muestran los modelos de las puertas logicas.
--------------------------------------
-- AND de 2 entradas con retardo
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 73
library IEEE; use IEEE.std_logic_1164.all;
entity and2 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end entity and2;
architecture and2 of and2 is
begin
y0 <= ( x0 and x1 ) after DELAY;
end architecture and2;
--------------------------------------
--------------------------------------
-- OR de 3 entradas con retardo
library IEEE; use IEEE.std_logic_1164.all;
entity or3 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1, x2 : in std_logic );
end entity or3;
architecture or3 of or3 is
begin
y0 <= ( x0 or x1 or x2 ) after DELAY;
end architecture or3;
--------------------------------------
-----------------------------------------
-- OR exclusiva de 2 entradas con retardo
library IEEE; use IEEE.std_logic_1164.all;
entity xor2 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end entity xor2;
architecture xor2 of xor2 is
begin
y0 <= ( x0 xor x1 ) after DELAY;
end architecture xor2;
74 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
------------------------------------------
En este caso, en lugar de declarar los componentes en la architecture del
sumador, se han definido los componentes en un package, que se ha llamado
puertasLogicas_package, y este se ha usado en la definicion de la architecture.
La definicion del package se muestra a continuacion.
-----------------------------------
-- package de componentes
-- Puertas logicas
library IEEE;
use IEEE.std_logic_1164.all;
package puertasLogicas_package is
component xor2 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end component xor2;
component and2 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1 : in std_logic );
end component and2;
component or3 is
generic ( DELAY : time := 10 ns );
port ( y0 : out std_logic;
x0, x1, x2 : in std_logic );
end component or3;
end package puertasLogicas_package;
La definicion del sumador completo es la siguiente:
-----------------------------------
-- Sumador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
use work.puertasLogicas_package.all;
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 75
entity sum_completo is port
( s, C_out : out std_logic;
x, y, C_in : in std_logic);
end entity sum_completo;
architecture sum_completo_estruc of sum_completo is
signal n1, n2, n3, n4: std_logic;
begin
-- Instanciacion y conexion de los componentes
XOR2_1 : component xor2 port map
(x0 => x, x1 => y, y0 => n1 );
XOR2_2 : component xor2 port map
(x0 => C_in, x1 => n1, y0 => s );
AND2_1 : component and2 port map
(x0 => x, x1 => y, y0 => n2 );
AND2_2 : component and2 port map
(x0 => x, x1 => C_in, y0 => n3 );
AND2_3 : component and2 port map
(x0 => y, x1 => C_in, y0 => n4 );
OR3_1 : component or3 port map
(x0 => n2, x1 => n3, x2 => n4, y0 => C_out );
end architecture sum_completo_estruc;
-----------------------------------
3.5.2 Banco de pruebas de sumador completo
Para comprobar el correcto funcionamiento de este circuito, se puede emplear
un banco de pruebas muy similar al que se diseno para el restador de 1 bit.
En el banco de pruebas se compara el resultado obtenido de la descripcion de
la estructura del sumador, con el resultado obtenido de la descripcion de su
comportamiento. Se muestra un mensaje si ambos resultados no coinciden y se
lleva la cuenta del numero de errores, mostrando al final de la simulacion un
mensaje con el numero total de errores. A continuacion, se muestra el codigo del
banco de pruebas.
--------------------------------------------------
-- Banco de pruebas del sumador completo de 1 bit
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_sum_completo is -- El banco de pruebas no tiene
end entity bp_sum_completo; -- ni entradas ni salidas
76 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
architecture bp_sum_completo of bp_sum_completo is
signal s, C_out,
x, y, C_in : std_logic; -- Para conectar el UUT
component sum_completo is
port ( s, C_out : out std_logic;
x, y, C_in : in std_logic);
end component sum_completo;
begin
-- Instanciar y conectar UUT
uut : component sum_completo port map
(s => s, C_out => C_out, x => x, y => y, C_in => C_in);
-- Crear vectores de test y comprobar salidas del UUT
gen_vec_test : process
variable test_in : unsigned (2 downto 0); -- Vector de test
variable esperado : unsigned (1 downto 0); -- Salida esperada
variable num_errores : integer := 0; -- Numero de errores
begin
test_in := B"000";
for count in 0 to 7 loop
C_in <= test_in(2);
x <= test_in(1);
y <= test_in(0);
wait for 50 ns;
esperado := (’0’ & x) + (’0’ & y) + (’0’ & C_in);
if (esperado /= ( C_out & s )) then -- Comprueba resultado
report "ERROR : Esperado (" & -- Report del error
std_logic’image(esperado(1)) &
std_logic’image(esperado(0)) &
") /= actual (" &
std_logic’image(C_out) &
std_logic’image(s) &
") en el instante " &
time’image(now);
num_errores := num_errores + 1;
end if;
test_in := test_in + 1;
end loop;
report "Test completo. Hay " &
integer’image(num_errores) &
" errores.";
wait;
end process gen_vec_test;
end architecture bp_sum_completo;
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 77
--------------------------------------------------
En la Figura 3.8 se muestra el resultado de la simulacion del banco de pruebas.
Observese que, debido al retardo de las puertas logicas, desde el instante inicial
hasta el instante 20ns las salidas del sumador toman el valor ’U’ (indefinido).
Asimismo, los cambios en las senales de entrada tardan 20ns en propagarse a las
senales de salida.
Figura 3.8: Simulacion del banco de pruebas del sumador completo.
3.5.3 Diseño del sumador de 4 bits
En la Figura 3.9 se muestra un sumador binario paralelo de 4 bits con propagacion
del arrastre.
� � ��� ��
����
¡¢ +
� � ��� ��
��£¤
¡¢ +
� � �¥¦ §¨
£©£¤
¡¢ +
� � �¥¦ ��
����
¡¢ +
ª« ¬
®¯
°± ²³
´µ
¶· ¸¹
º»
¼± ¼
½¾
¿ À Á ®Ã ÄÅ ºÆ ÇÈÉ
Figura 3.9: Sumador binario paralelo de 4 bits con propagacion del arrastre.
3.6 Bus bidireccional y memorias
Se pretende modelar dos unidades de memoria y un bus que conecta ambas.
Para simplificar, se supone que las unidades de memoria tienen capacidad para
almacenar una unica palabra de N bits. Una de las memorias tiene capacidad de
lectura y escritura. La otra solo lectura. Ademas de las dos memorias, se modela
un bus de N lıneas que puede leer de ambas memorias y escribir en la memoria
que admite escritura. A continuacion, se describe el modelado mediante VHDL
de este sistema.
78 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3.6.1 Memoria de sólo lectura
Los puertos de la memoria son los siguientes:
– Senal de entrada de 1 bit (OE_n). Cuando esta senal se pone a ’0’, habilita
la operacion de lectura de la memoria. Cuando esta a ’1’, la operacion de
lectura esta deshabilitada.
– Vector de salida de N bits (data). Contiene el dato almacenado en me-
moria (palabra de N bits) una vez ejecutada la operacion de lectura. Es-
ta a alta impedancia cuando la operacion de lectura esta deshabilitada
(OE_n = ’1’).
A continuacion, se muestra el codigo VHDL que describe la interfaz y el
funcionamiento de esta memoria. Se definen dos constantes generic: WORD_SIZE,
que contiene el numero de bits de la palabra (N) y READ_DELAY, que contiene el
tiempo de retardo entre que se habilita la senal de lectura hasta que el dato esta
disponible.
-------------------------------------------
-- Fuente de datos unidireccional (lectura)
library IEEE; use IEEE.std_logic_1164.all;
entity fuenteUnidireccional is
generic ( WORD_SIZE : integer := 8; -- Bits por palabra,
-- por defecto 8
READ_DELAY : time := 10 ns); -- Retardo en la lectura,
-- por defecto 10 ns
port ( data : out std_logic_vector(WORD_SIZE-1 downto 0);
-- Datos de salida
OE_n : in std_logic); -- Habilita lectura
end entity fuenteUnidireccional;
architecture fuenteUnidireccional of fuenteUnidireccional is
begin
rom : process (OE_n)
begin
if (OE_n = ’0’) then
data <= ( 0 => ’1’, others => ’0’) after READ_DELAY;
else
data <= (others => ’Z’);
end if;
end process rom;
end architecture fuenteUnidireccional;
-------------------------------------------
La sentencia
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 79
data <= ( 0 => ’1’, others => ’0’ ) after READ_DELAY;
indica que debe asignarse al vector de senales data, una vez transcurrido el
retardo de tiempo READ_DELAY, una palabra del tamano de data, con todos
sus bits igual a ’0’ excepto el menos significativo, que debe valer ’1’ (es decir,
data <= "00...01";). Esta palabra es la que se encuentra almacenada en la
memoria y es la que se lee cada vez que se habilita la operacion de lectura.
Analogamente, la sentencia
data <= (others => ’Z’);
asigna al vector de senales data una palabra, con el mismo numero de bits que
data, con todos sus bits al valor ’Z’ (alta impedancia).
3.6.2 Memoria de lectura y escritura
Los puertos de esta memoria son los siguientes:
– Senal de entrada de 1 bit (OE_n). Cuando esta senal se pone a ’0’, habilita
la operacion de lectura de la memoria. Cuando esta a ’1’, la operacion de
lectura esta deshabilitada.
– Senal de entrada de 1 bit (WE_n). Cuando esta senal se pone a ’0’, habilita
la operacion de escritura en la memoria. Cuando esta a ’1’, la operacion de
escritura esta deshabilitada.
– Vector de entrada y salida de N bits (data).
------------------------------------------------------
-- Fuente de datos bidireccional (lectura y escritura)
library IEEE; use IEEE.std_logic_1164.all;
entity fuenteBidireccional is
generic ( WORD_SIZE : integer := 8; -- Bits por palabra,
-- por defecto 8 bits
READ_DELAY : time := 10 ns; -- Retardo en la lectura,
-- por defecto 10 ns
WRITE_DELAY : time := 10 ns); -- Retardo en la escritura,
-- por defecto 10 ns
port ( data : inout std_logic_vector(WORD_SIZE-1 downto 0);
-- Se~nal de datos bidireccional
OE_n : in std_logic; -- Habilita lectura
WE_n : in std_logic ); -- Habilita escritura
end entity fuenteBidireccional;
architecture fuenteBidireccional of fuenteBidireccional is
80 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
signal data_stored : std_logic_vector(WORD_SIZE-1 downto 0);
-- Datos almacenados internamente
begin
ram : process (OE_n, WE_n, data)
begin
if (OE_n = ’0’) then
data <= data_stored after READ_DELAY;
elsif ( WE_n = ’0’) then
data_stored <= data after WRITE_DELAY;
else
data <= (others => ’Z’);
end if;
end process ram;
end architecture fuenteBidireccional;
------------------------------------------------------
3.6.3 Bus bidireccional
A continuacion, se muestra el codigo del bus de datos que se emplea para realizar
varias operaciones de lectura y escritura sobre las memorias. Al instanciar las
memorias, se asignan nuevos valores al tamano de la palabra, que pasa a ser 16
bits, y a los retardos:
– Memoria de solo lectura: retardo en la lectura de 20 ns.
– Memoria de lectura y escritura: retardo en la lectura de 30 ns y retardo en
la escritura de 40 ns.
Las operaciones que se realizan son las siguientes:
1. tiempo = 0 (instante inicial). Se asigna valor ’1’ a las senales OE1_n,
OE2_n y WE_n, es decir, inicialmente se encuentras deshabilitadas las ope-
raciones de lectura y escritura en las memorias. Tambien, en el instante
inicial, se asigna el valor 0x0fc3 a la senal writeData del banco de pruebas,
cuya finalidad es almacenar el valor que va a ser escrito en la memoria.
2. tiempo = 100 ns. Se habilita la operacion de escritura, para ello se pone
a ’0’ la senal WE_n. A consecuencia de ello, en el instante tiempo = 140 ns
se escribe el valor 0x0fc3 en la memoria.
3. tiempo = 200 ns. Se deshabilita la operacion de escritura, poniendo la
senal WE_n al valor ’1’. Se habilita la operacion de lectura de la memoria de
solo lectura, para lo cual se pone la senal OE2_n a ’0’. A consecuencia de
ello, el valor 0x0001 esta disponible en el bus en el instante tiempo = 220
ns.
4. tiempo = 300 ns. Se deshabilita la lectura de la memoria de solo lectura,
para lo cual se pone la senal OE2_n a ’1’. Finalmente, se habilita la lectura
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 81
de la memoria de lectura y escritura, para lo cual se pone la senal OE1_n a
’0’. A consecuencia de ello, en el instante tiempo = 330 ns el valor 0x0fc3
esta disponible en el bus.
A continuacion, se muestra el codigo VHDL que describe las operaciones
realizadas sobre las memorias mediante el empleo del bus.
-----------------------------------------------
-- Conexion de la fuente de datos bidireccional
-- y la fuente unidireccional mediante un bus
library IEEE; use IEEE.std_logic_1164.all;
entity tb_bus is
constant WORD_SZ : integer := 16; -- Bits por palabra
constant PERIOD : time := 100 ns; -- Periodo ciclo reloj
end entity tb_bus;
architecture tb_bus of tb_bus is
signal data : std_logic_vector(WORD_SZ-1 downto 0);
-- Datos en el bus
signal OE1_n : std_logic; -- Habilita lectura memoria lectura/escritura
signal OE2_n : std_logic; -- Habilita lectura memoria solo lectura
signal WE_n : std_logic; -- Habilita escritura
signal writeData : std_logic_vector(WORD_SZ-1 downto 0);
-- Datos a escribir
component fuenteBidireccional is
generic ( WORD_SIZE : integer := 8; -- Bits por palabra
READ_DELAY : time := 10 ns; -- Retardo en la lectura
WRITE_DELAY : time := 10 ns); -- Retardo en la escritura
port ( data : inout std_logic_vector(WORD_SIZE-1 downto 0);
-- Se~nal de datos bidireccional
OE_n : in std_logic; -- Habilita lectura
WE_n : in std_logic ); -- Habilita escritura
end component fuenteBidireccional;
component fuenteUnidireccional is
generic ( WORD_SIZE : integer := 8; -- Bits por palabra
READ_DELAY : time := 10 ns); -- Retardo en la lectura
port ( data : out std_logic_vector(WORD_SIZE-1 downto 0);
-- Se~nal de datos bidireccional
OE_n : in std_logic); -- Habilita lectura
end component fuenteUnidireccional;
begin
82 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
-- Instanciar las fuentes de datos, asignando valor a sus constantes generic
U1 : component fuenteBidireccional
generic map (WORD_SZ, 30 ns, 40 ns) -- Asigna valor constantes generic
port map (data, OE1_n, WE_n);
U2 : component fuenteUnidireccional
generic map (WORD_SZ, 20 ns ) -- Asigna valor constantes generic
port map (data, OE2_n);
data <= writeData when ( WE_n = ’0’) else ( others => ’Z’);
vectoresTest : process is
begin
OE1_n <= ’1’; OE2_n <= ’1’; WE_n <= ’1’; -- Deshabilita se~nales
writeData <= B"0000_1111_1100_0011"; -- Dato a escribir (=0x0fc3)
wait for PERIOD;
WE_n <= ’0’; -- Habilita escritura (se escribe 0x0fc3)
wait for PERIOD;
WE_n <= ’1’; -- Deshabilita escritura
OE2_n <= ’0’; -- Habilita lectura desde la fuente unidireccional
-- El dato en el bus debe ser 0x0001
wait for PERIOD;
OE2_n <= ’1’; -- Deshabilita lectura de la fuente unidireccional
OE1_n <= ’0’; -- Habilita lectura desde la fuente bidireccional
-- El dato en el bus debe ser 0x0fc3
wait for PERIOD;
wait;
end process vectoresTest;
end architecture tb_bus;
-----------------------------------------------
En la Figura 3.10 se muestra el resultado obtenido de la simulacion.
Figura 3.10: Formas de onda obtenidas de simular el circuito.
3.7 Unidad aritmético lógica (ALU)
Una unidad aritmetico logica (ALU) es un circuito que, dependiendo del valor de
sus entradas de seleccion de funcion, realiza una operacion logica o aritmetica, de
entre un conjunto de operaciones posibles, sobre uno o dos operandos.
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 83
Este tipo de circuito puede ser descrito mediante una asignacion concurrente
a una senal, o bien mediante varias asignaciones incluidas dentro de un bloque
process.
En general, un circuito combinacional puede ser descrito mediante un bloque
process siempre que todas las senales de entrada al circuito combinacional sean
incluidas en la lista de variables a las que es sensible el bloque process.
A continuacion, se muestran dos posibles formas de modelar una ALU: la
primera usando una asignacion concurrente y la segunda usando un bloque pro-
cess. Ambas versiones dan lugar a circuitos combinacionales equivalentes. En la
Tabla 3.1 se muestran las operaciones entre los operandos A y B que realiza la
ALU, en funcion del valor de la entrada de seleccion de funcion de 3 bits mode.
mode Operacion Descripcion
0 0 0 A ∗ 2 Multiplicar por 2 (equivale a desplazamiento a la izqda)
0 0 1 A + B Suma
0 1 0 A−B Resta
0 1 1 −A Complemento a dos
1 0 0 A and B AND logico
1 0 1 A or B OR logico
1 1 0 A xor B XOR logico
1 1 1 not A Complemento de todos los bits
Tabla 3.1: Tabla de operaciones de la ALU
3.7.1 Modelado mediante asignación concurrente
Para ilustrar el empleo de las clases package para almacenar constantes globales,
a continuacion se muestra un package con las las constantes que definen el
tamano de palabra de los operandos y el tamano de la palabra de seleccion de la
operacion.
----------------------------------------------
-- Definicion de constantes globales de la ALU
package ALU_CONSTANTS is
constant WIDTH : integer := 16;
-- Num. bits de los operandos
constant SEL_BITS : integer := 3;
-- Num. bits seleccion de operacion
end package ALU_CONSTANTS;
----------------------------------------------
A continuacion, se muestra el codigo que define el comportamiento de la ALU
mediante una unica sentencia de asignacion concurrente a una senal.
84 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
----------------------------------------------
-- ALU
-- architecture: sentencia concurrente
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.ALU_CONSTANTS.all;
entity ALU is
port ( C : out std_logic_vector (WIDTH-1 downto 0);
A, B : in std_logic_vector (WIDTH-1 downto 0);
mode : in std_logic_vector (SEL_BITS-1 downto 0) );
end entity ALU;
architecture ALU_concurrente of ALU is
begin
C <= std_logic_vector (signed(A)+signed(A)) when (mode="000")
else std_logic_vector (signed(A)+signed(B)) when (mode="001")
else std_logic_vector (signed(A)-signed(B)) when (mode="010")
else std_logic_vector (-signed(A) ) when (mode="011")
else A and B when (mode="100")
else A or B when (mode="101")
else A xor B when (mode="110")
else not A;
end architecture ALU_concurrente;
----------------------------------------------
3.7.2 Modelado mediante bloque process
El comportamiento de la ALU tambien puede ser descrito empleando un bloque
process sensible a tres senales: los dos operandos y la senal de seleccion de la
operacion.
----------------------------------------------
-- ALU
-- architecture: bloque process
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.ALU_CONSTANTS.all;
architecture ALU_bloqueProcess of ALU is
begin
process (A, B, mode) is
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 85
begin
case mode is
when "000" => C <= std_logic_vector(signed(A)+signed(A));
when "001" => C <= std_logic_vector(signed(A)+signed(B));
when "010" => C <= std_logic_vector(signed(A)-signed(B));
when "011" => C <= std_logic_vector(-signed(A));
when "100" => C <= A and B;
when "101" => C <= A or B;
when "110" => C <= A xor B;
when others => C <= not A;
end case;
end process;
end architecture ALU_bloqueProcess;
----------------------------------------------
3.7.3 Programación del banco de pruebas
Como hemos visto en otros ejemplos, el banco de pruebas esta tıpicamente for-
mado por las tres partes siguientes: el dispositivo que va a ser probado (UUT),
el codigo para la generacion de los vectores de test y el codigo para comprobar
los resultados del test.
Aun en el caso de una ALU sencilla como esta, examinar que la ALU realiza
correctamente las operaciones para todos los posibles valores de los operadores
consumirıa bastante tiempo. En la practica esta tecnica serıa inviable, por lo cual
debe seleccionarse un conjunto de vectores de test, por ejemplo, atendiendo a los
criterios siguientes:
– Se escogen valores de los operandos entorno al cero. Por ejemplo: −2, −1,
0, 1 y 2.
– Se escogen valores de los operandos en el lımite inferior de su rango. Si
MIN_NEG_DATA representa el valor mınimo que puede tomar el operando,
entonces se escogen los valores MIN_NEG_DATA, . . . , MIN_NEG_DATA+4para cada
uno de los operandos.
– Se escogen valores de los operandos en el lımite superior de su rango. Si
MAX_POS_DATA representa el valor maximo que puede tomar el operando,
entonces se escogen los valores MAX_POS_DATA-4, . . . , MAX_POS_DATA para cada
uno de los operandos.
– Finalmente, se escogen algunos valores “al azar”, mas o menos distribuidos
uniformemente en el rango de los operandos.
Se ha definido un package con las constantes globales del banco de pruebas,
cuyo valor es calculado a partir de las constantes globales de la ALU.
86 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
----------------------------------------------
-- Definicion de constantes globales
-- del banco de pruebas de la ALU
use work.ALU_CONSTANTS.all;
package TB_ALU_CONSTANTS is
constant SEL_MAX : integer := 2**SEL_BITS - 1;
constant MAX_POS_DATA : integer := 2**(WIDTH-1) - 1;
constant MIN_NEG_DATA : integer := -2**(WIDTH-1);
constant DELAY : time := 10 ns;
end package TB_ALU_CONSTANTS;
----------------------------------------------
A continuacion se muestra el codigo del banco de pruebas.
----------------------------------------------
-- Banco de pruebas para la ALU
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.ALU_CONSTANTS.all;
use work.TB_ALU_CONSTANTS.all;
entity TB_ALU is
constant PERIOD : time := 100 ns;
end entity TB_ALU;
architecture TB_ALU of TB_ALU is
signal A,B,C : std_logic_vector (WIDTH-1 downto 0);
signal mode : std_logic_vector (SEL_BITS-1 downto 0);
component ALU is
port ( C : out std_logic_vector (WIDTH-1 downto 0);
A, B : in std_logic_vector (WIDTH-1 downto 0);
mode : in std_logic_vector (SEL_BITS-1 downto 0) );
end component ALU;
-- Procedure que calcula C (expected_C) y lo compara con el
-- valor de C que se pasa como argumento (actual_C)
-- Si ambos valores no coinciden, se muestra un mensaje y se
-- incrementa el contador de errores (error_count)
procedure check_ALU
( i, j, k : in integer;
actual_C : in std_logic_vector (WIDTH-1 downto 0);
error_count : inout integer ) is
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 87
variable expected_C : integer;
begin
case k is
when 0 => expected_C := i*2;
when 1 => expected_C := i+j;
when 2 => expected_C := i-j;
when 3 => expected_C := -i;
when 4 => expected_C := TO_INTEGER(signed(
std_logic_vector(TO_SIGNED(i,WIDTH)) and
std_logic_vector(TO_SIGNED(j,WIDTH)) ));
when 5 => expected_C := TO_INTEGER(signed(
std_logic_vector(TO_SIGNED(i,WIDTH)) or
std_logic_vector(TO_SIGNED(j,WIDTH)) ));
when 6 => expected_C := TO_INTEGER(signed(
std_logic_vector(TO_SIGNED(i,WIDTH)) xor
std_logic_vector(TO_SIGNED(j,WIDTH)) ));
when others => expected_C := TO_INTEGER(signed(
not std_logic_vector(TO_SIGNED(i,WIDTH)) ));
end case;
expected_C := TO_INTEGER(TO_SIGNED(expected_C,WIDTH));
-- Trunca el resultado a WIDTH bits
assert( expected_C = TO_INTEGER(signed(actual_C)) )
report "ERROR. Ops: " & integer’image(i) & "," & integer’image(j) &
", Operacion: " & integer’image(k) &
", resultado esperado: " &
integer’image(expected_C) &
", resultado actual: " &
integer’image(TO_INTEGER(signed(actual_C))) &
"en el instante " &
time’image(now);
if (expected_C /= TO_INTEGER(signed(actual_C))) then
error_count := error_count + 1;
end if;
end procedure check_ALU;
-- Fin de la definicion del procedure
begin
UUT : component ALU port map (C, A, B, mode);
-- bloque process para generar los vectores de test y
-- comprobar el resultado
main : process is
variable error_count : integer := 0;
begin
88 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
report "Comienza la simulacion";
-- Vectores de test: operandos con valor proximo a cero
for i in -2 to 2 loop
for j in -2 to 2 loop
for k in 0 to SEL_MAX loop
A <= std_logic_vector(TO_SIGNED(i,WIDTH));
b <= std_logic_vector(TO_SIGNED(j,WIDTH));
mode <= std_logic_vector(TO_SIGNED(k,SEL_BITS));
wait for DELAY;
check_ALU(i, j, k, C, error_count);
end loop;
end loop;
end loop;
-- Vectores de test: operandos con valor proximo al mınimo
for i in MIN_NEG_DATA to MIN_NEG_DATA+4 loop
for j in MIN_NEG_DATA to MIN_NEG_DATA+4 loop
for k in 0 to SEL_MAX loop
A <= std_logic_vector(TO_SIGNED(i,WIDTH));
b <= std_logic_vector(TO_SIGNED(j,WIDTH));
mode <= std_logic_vector(TO_SIGNED(k,SEL_BITS));
wait for DELAY;
check_ALU(i, j, k, C, error_count);
end loop;
end loop;
end loop;
-- Vectores de test: operandos con valor proximo al maximo
for i in MAX_POS_DATA-4 to MAX_POS_DATA loop
for j in MAX_POS_DATA-4 to MAX_POS_DATA loop
for k in 0 to SEL_MAX loop
A <= std_logic_vector(TO_SIGNED(i,WIDTH));
b <= std_logic_vector(TO_SIGNED(j,WIDTH));
mode <= std_logic_vector(TO_SIGNED(k,SEL_BITS));
wait for DELAY;
check_ALU(i, j, k, C, error_count);
end loop;
end loop;
end loop;
-- Vectores de test: operandos con valores al azar
for i in 0 to 9 loop
for j in 0 to 9 loop
for k in 0 to SEL_MAX loop
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 89
A <= std_logic_vector(TO_SIGNED(41*i-273,WIDTH));
b <= std_logic_vector(TO_SIGNED(89*j-384,WIDTH));
mode <= std_logic_vector(TO_SIGNED(k,SEL_BITS));
wait for DELAY;
check_ALU(41*i-273, 89*j-384, k, C, error_count);
end loop;
end loop;
end loop;
wait for DELAY;
-- Informe mostrando el resultado del test
if (error_count=0) then
report "Finaliza la simulacion: 0 errores";
else
report "Finaliza la simulacion: " & integer’image(error_count) & "errores";
end if;
wait; -- Termina la simulacion
end process main;
end architecture TB_ALU;
----------------------------------------------
3.8 Conversor de BCD a binario
En los circuitos logicos digitales se emplean diferentes codigos binarios. En oca-
siones, dos circuitos que usan diferente codigo necesitan comunicarse entre sı,
siendo preciso emplear otro circuito para realizar la conversion de un codigo a
otro. Como ejemplo de este tipo de circuitos conversores de codigo, en esta seccion
de describira el diseno de un conversor para numeros en codigo BCD de longitud
fija a codigo binario.
En el codigo BCD (binary-coded decimal), cada grupo de cuatro bits conse-
cutivos es convertido a un dıgito decimal. El numero completo es interpretado
como un numero decimal compuesto por estos dıgitos decimales. Por ejemplo,
0101 1001BCD es interpretado como 5910, ya que los primeros cuatro bits (0101)
corresponden a un 5 decimal y los ultimos cuatro bits (1001) corresponden a un 9
decimal. El equivalente binario al numero 5910 es 0011 10112. El circuito descrito
en esta seccion deberıa realizar la conversion de 0101 1001BCD a 0011 10112.
Existen varios algoritmos de conversion de codigo BCD a binario, los cuales
tıpicamente requieren la realizacion de una secuencia de operaciones sobre el
numero BCD de entrada, que aparentemente deberıan ser implementadas usando
un circuito secuencial. Sin embargo, el algoritmo descrito a continuacion puede
90 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
ser transformado en una secuencia de puertas logicas, y por tanto puede ser
implementado usando un circuito combinacional.
Paso 1. bcd <- bcd_data_input;
bin <- 0 (mismo numero de bits que bcd)
Paso 2. For count <- 1 to bcd_bit_size do begin
Paso 2a. {bcd,bin} <- {bcd,bin} >> 1;
Paso 2b. For cada secuencia de 4 bits en bcd do
If secuencia de 4 bits > 7 then
restar 3 de esa secuencia de 4 bits;
end // del bucle For
Paso 3. bin contiene el numero convertido
3.8.1 Circuito conversor
La constante global que almacena el numero de bits del numero en BCD, se
declara en un package, que sera usado desde la descripcion del circuito y desde
la descripcion del banco de pruebas.
------------------------------------------
-- Definicion de constantes globales
package BCD_CONST is
constant LENGTH : integer := 16;
-- Longitud (# bits) del numero BCD
end package BCD_CONST;
------------------------------------------
A continuacion se muestra la descripcion de un circuito que ejecuta el algo-
ritmo de conversion de BCD a binario descrito anteriormente.
--------------------------------------
-- Circuito conversor de BCD a binario
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.BCD_CONST.all;
entity bcd_to_bin is
port( bin: out std_logic_vector(LENGTH-1 downto 0);
bcd: in std_logic_vector(LENGTH-1 downto 0) );
end entity bcd_to_bin;
architecture bcd_to_bin of bcd_to_bin is
begin
process (bcd) is -- bloque sensible a cambios en la entrada
variable bcd_concat_bin: unsigned(2*LENGTH-1 downto 0);
variable temp : unsigned(3 downto 0);
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 91
begin
bcd_concat_bin := unsigned(bcd) & TO_UNSIGNED(0,LENGTH);
for i in 0 to LENGTH-1 loop -- Paso 2
bcd_concat_bin := bcd_concat_bin srl 1; -- Paso 2a
for j in 0 to (LENGTH/4)-1 loop -- Paso 2b
temp := bcd_concat_bin(LENGTH+j*4+3 downto LENGTH+j*4);
if (temp(3) = ’1’) then -- Si la secuencia de 4 bits
temp := temp - "0011"; -- es mayor que 7, se resta 3
end if;
bcd_concat_bin(LENGTH+j*4+3 downto LENGTH+j*4) := temp;
end loop; -- end for Paso 2b
end loop; -- end for Paso 2
bin <= std_logic_vector(bcd_concat_bin(LENGTH-1 downto 0));
end process;
end architecture bcd_to_bin;
--------------------------------------
Observese que un bloque process puede dar lugar a un circuito combinacional
si en la lista de senales a las cuales el bloque es sensible incluye todas las entradas
al circuito. Dado que ese bloque process serıa activado cada vez que una de las
senales de entrada cambia, este codigo representa un circuito combinacional.
Igualmente, un bucle for no implica necesariamente que el circuito sinteti-
zado deba ser secuencial. En este caso, el bucle for unicamente representa la
interconexion de puertas logicas combinacionales.
3.8.2 Banco de pruebas
A continuacion se muestra el codigo del banco de pruebas del circuito conversor.
Para probar el circuito, se generan todos los posibles numeros en BCD con LENGTH
bits. En este caso, todos los posibles numeros de 16 bits. Puesto que un numero
BCD de 16 bits puede representar cualquier numero entero comprendido entre 0
y 999910, ese sera el rango de numeros que se emplee en el test.
----------------------------------------------
-- Banco de pruebas para el circuito conversor
-- de BCD a binario
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.BCD_CONST.all;
entity bp_bcd_to_bin is
constant MAX_BCD : integer := 9999; -- Valor maximo de entrada
constant DELAY : time := 10ns; -- Retardo usado en el test;
end entity bp_bcd_to_bin;
92 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
architecture bp_bcd_to_bin of bp_bcd_to_bin is
signal bin: std_logic_vector(LENGTH-1 downto 0); -- Salida de UUT
signal bcd: std_logic_vector(LENGTH-1 downto 0); -- Entrada a UUT
-- Declaracion del componente (UUT)
component bcd_to_bin is
port( bin: out std_logic_vector(LENGTH-1 downto 0);
bcd: in std_logic_vector(LENGTH-1 downto 0) );
end component bcd_to_bin;
begin
-- Instancia la unidad a testear
UUT : component bcd_to_bin port map(bin,bcd);
-- Genera vectores de test y comprueba resultados
main: process is
variable temp : unsigned (LENGTH-1 downto 0);
variable digit : unsigned (LENGTH-1 downto 0); -- Un digito BCD
variable digits : unsigned (LENGTH-1 downto 0); -- Todos digitos
variable expected : unsigned (LENGTH-1 downto 0);
variable error_count : integer := 0; -- Numero de errores
begin
report "Comienza la simulacion.";
-- Generar todos los posibles valores
for i in 0 to MAX_BCD loop
temp := TO_UNSIGNED(i,LENGTH);
for j in 0 to (LENGTH/4-1) loop
digit := temp mod 10; -- Obtiene el digito BCD menos significativo
digits(j*4+3 downto j*4) := digit(3 downto 0);
temp := temp/10;
end loop;
bcd <= std_logic_vector(digits); -- Asigna vector de test
expected := TO_UNSIGNED(i, LENGTH);
wait for DELAY;
assert (expected = unsigned(bin))
report "ERROR: Resultado esperado " &
integer’image(TO_INTEGER(expected)) &
", resultado obtenido " &
integer’image(TO_INTEGER(unsigned(bin))) &
" en el instante " & time’image(now);
if (expected /= unsigned(bin)) then
error_count := error_count + 1;
end if;
end loop;
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 93
wait for DELAY;
-- Informe final
if (error_count = 0) then
report "Simulacion finalizada sin errores";
else
report "ERROR: Hay " & integer’image(error_count) & " errores.";
end if;
wait; -- Final de la simulacion
end process main;
end architecture bp_bcd_to_bin;
3.9 Codificador 4:2 con prioridad
Un codificador es un circuito que convierte un valor decimal en su equivalente
binario (realiza la funcion inversa a un decodificador). Este circuito, que tiene 2N
entradas y N salidas, presenta en la salida el codigo binario correspondiente a la
entrada activada.
El codificador no funciona correctamente si en un determinado instante se
produce mas de una entrada al circuito. En aquellos casos en que deba con-
templarse esta situacion, se emplean circuitos codificadores con prioridad, en los
cuales queda definido que entrada debe codificarse cuando se presenten varias en
un determinado instante.
Asimismo, el codificador tiene una salida que se activa cuando hay alguna
entrada al circuito. Observese que cuando no hay ninguna entrada, la salida del
codificador no es valida.
3.9.1 Diseño del circuito
A continuacion, se muestra el codigo VHDL de un codificador 4:2 con prioridad.
La entrada 3 tiene mayor prioridad que la 2, esta mayor que la 1 y finalmente la
entrada 0 es la de menor prioridad. La salida valida se pone a ’1’ cuando hay al
menos una entrada al circuito.
-------------------------------------------
-- Codificador 4:2 con prioridad
library IEEE;
use IEEE.std_logic_1164.all;
entity codificador_4_2_prioridad is
port ( valida : out std_logic; -- ’1’ si hay entrada
codificada : out std_logic_vector(1 downto 0);
i3, i2, i1, i0 : in std_logic );
end entity codificador_4_2_prioridad;
94 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
architecture codificador_4_2_prioridad of codificador_4_2_prioridad is
begin
process (i3, i2, i1, i0) is -- Activado cuando cambia alguna entrada
begin
if ( (i3=’1’) or (i2=’1’) or (i1=’1’) or (i0=’1’) ) then
valida <= ’1’; -- Indica que la salida es valida
else
valida <= ’0’; -- Salida no valida, puesto que no hay entrada
end if;
if (i3=’1’) then codificada <= "11";
elsif (i2=’1’) then codificada <= "10";
elsif (i1=’1’) then codificada <= "01";
else codificada <= "00";
end if;
end process;
end architecture codificador_4_2_prioridad;
-------------------------------------------
Observese que el bloque process es activado cuando cambia cualquiera de las
entradas, ya que el bloque es sensible a estas cuatro senales.
Se emplean sentencias if-elsif para inspeccionar de manera priorizada las
entradas.
3.9.2 Banco de pruebas
A continuacion, se muestra el codigo del banco de pruebas.
-----------------------------------------------------
-- Banco de pruebas del codificador 4:2 con prioridad
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_codificador_4_2 is
constant MAX_COMB : integer := 16; -- Num. combinaciones entrada
constant DELAY : time := 10 ns; -- Retardo usado en el test
end entity bp_codificador_4_2;
architecture bp_codificador_4_2 of bp_codificador_4_2 is
-- Salidas UUT
Capıtulo 3 Casos practicos de diseno de circuitos combinacionales 95
signal valida : std_logic;
signal codificada : std_logic_vector(1 downto 0);
-- Entradas UUT
signal i3, i2, i1, i0 : std_logic;
component codificador_4_2_prioridad is
port ( valida : out std_logic;
codificada : out std_logic_vector(1 downto 0);
i3, i2, i1, i0 : in std_logic );
end component codificador_4_2_prioridad;
begin -- Cuerpo de la arquitectura
UUT : component codificador_4_2_prioridad port map
(valida, codificada, i3, i2, i1, i0);
main : process is
variable temp : unsigned (3 downto 0); -- Usado en los calculos
variable esperado_valida : std_logic;
variable esperado_codificada : std_logic_vector(1 downto 0);
variable error_count : integer := 0;
begin
report "Comienza la simulacion";
-- Generar todos los posibles valores de entrada
for i in 0 to (MAX_COMB-1) loop
temp := TO_UNSIGNED(i,4);
i3 <= std_logic(temp(3));
i2 <= std_logic(temp(2));
i1 <= std_logic(temp(1));
i0 <= std_logic(temp(0));
-- Calcular el valor esperado
if (i=0) then
esperado_valida := ’0’;
esperado_codificada := "00";
else
esperado_valida := ’1’;
if (i=1) then esperado_codificada := "00";
elsif (i<=3) then esperado_codificada := "01";
elsif (i<=7) then esperado_codificada := "10";
else esperado_codificada := "11";
end if;
end if;
wait for DELAY; -- Espera y compara con las salidas de UUT
if ( esperado_valida /= valida ) then
96 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
report "ERROR en la salida valida. Valor esperado: " &
std_logic’image(esperado_valida) &
", valor actual: " &
std_logic’image(valida) &
" en el instante: " &
time’image(now);
error_count := error_count + 1;
end if;
if ( esperado_codificada /= codificada ) then
report "ERROR en la salida codificada. Valor esperado: " &
std_logic’image(esperado_codificada(1)) &
std_logic’image(esperado_codificada(0)) &
", valor actual: " &
std_logic’image(codificada(1)) &
std_logic’image(codificada(0)) &
" en el instante: " &
time’image(now);
error_count := error_count + 1;
end if;
end loop; -- Final del bucle for de posibles valores de entrada
-- Informe del numero total de errores
if (error_count = 0) then
report "Simulacion finalizada sin errores";
else
report "ERROR: Hay " &
integer’image(error_count) &
" errores.";
end if;
wait; -- Final de la simulacion
end process main;
end architecture bp_codificador_4_2;
-----------------------------------------------------
La ejecucion del banco de pruebas indica que no hay ningun error en el
circuito. En la Figura 3.11 se muestra el resultado de la simulacion.
Figura 3.11: Formas de onda obtenidas de simular el banco de pruebas.
4Casos prácticos de diseño de
circuitos secuenciales
Objetivos. Una vez estudiado el contenido del tema deberıa saber:
– Disenar en VHDL maquinas de estado finito de Moore y de Mealy sintetizables,
realizando el diseno en base a la descripcion de su estructura y/o comporta-
miento.
– Disenar y programar en VHDL bancos de pruebas de circuitos secuenciales.
Muchos problemas de diseno pueden ser resueltos usando maquinas de estado
finito. Una maquina de estado finito consiste esencialmente en un conjunto de
estados (codificados usando flip-flops) y transiciones entre estos estados, gober-
nadas por un conjunto de bits de condicion. Es esta seccion trataremos algunos
aspectos del diseno de maquinas de estado finito de Moore y de Mealy usando
VHDL.
– Maquina de Moore. Una maquina de estado finito de Moore (o simplemente,
“maquina de Moore”) es una maquina de estado en la cual las salidas del
circuito dependen del estado actual y no del valor actual de las entradas.
– Maquina de Mealy. Las salidas de una maquina de Mealy dependen del
estado actual y tambien del valor actual de las entradas.
Ambos tipos de maquina pueden ser disenados de manera sistematica usando
un metodo de diseno de maquinas de estado finito descrito en la siguiente seccion.
4.1 Diseño de circuitos secuenciales síncronos
Las maquinas de Moore y Mealy pueden ser disenadas de manera sistematica
siguiendo los pasos descritos a continuacion:
100 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
1. Dibujar el diagrama de estados del circuito.
2. Crear un conjunto de variables de estado y codificar los estados del diagrama
de estados usando estas variables de estado.
3. Escribir la tabla de transicion del estado usando el diagrama dibujado en el
Paso 1 y la codificacion de los estados del Paso 2.
4. Formular, a partir de la tabla de transicion del estado del Paso 3, las
funciones logicas simplificadas para el nuevo estado y las salidas.
5. Disenar el circuito empleando un flip-flop por cada variable de estado, y
logica combinacional para las funciones de transicion del estado y de salida
obtenidas en el Paso 4.
4.1.1 Circuito detector de secuencias
El metodo anterior puede aplicarse al diseno de un circuito que detecte la secuen-
cia 101. El circuito tiene una unica entrada, por la que recibe bits en serie, y una
unica salida, en la que genera un bit 1 cuando detecta la secuencia 101 en los
bits de entrada, y genera un 0 en caso contrario. Observese que tambien deben
detectarse las secuencias cuando se encuentran solapadas, por ejemplo: 10101
El primer paso del diseno es dibujar el diagrama de estados del circuito,
que consiste en un conjunto de estados y (posiblemente) transiciones etiquetadas
entre los estados. En la Figura 4.1 se muestra el diagrama de transicion para el
circuito detector de la secuencia 101.
0s
1s
2s
ÊË Ê
ÌÍ ÎÌÍ Î
ÊË ÊÏË Ï
ÊË Ê
Figura 4.1: Diagrama de estados del circuito detector de la secuencia 101.
Cada estado del diagrama “recuerda” una porcion de la secuencia 101. Las
transiciones entre los estados estan etiquetadas x/y, donde x corresponde con el
valor de la entrada que produce la transicion, e y corresponde con el valor de
la variable de salida dado el estado en el que empieza la transicion y el valor
de entrada x. Dado que la salida depende del estado actual y de la variable de
entrada, este tipo de diagrama corresponde con una maquina de Mealy.
En este tipo de diagrama debe tenerse en cuenta que debe escribirse una
transicion desde cada estado por cada posible valor que puede tomar la entrada
en ese estado.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 101
El segundo paso del metodo de diseno consiste en codificar los estados.
Puesto que hay tres estados, son necesarias dos variables de estado: A y B. Por
simplicidad en la exposicion, realizaremos una codificacion binaria de los estados:
Estado A B
S0 0 0
S1 0 1
S2 1 0
En general, unas codificaciones de los estados conducen a circuitos mas sen-
cillos que otras, aunque las diferencias tıpicamente no son muy grandes.
El tercer paso del metodo de diseno consiste en escribir la tabla de transicion
de estados y salidas. Esto puede hacerse de manera sencilla a partir del diagrama
de transicion de estados mostrado en la Figura 4.1 y de la tabla anterior de
codificacion de los estados. La tabla de transicion de estados y salidas es la
siguiente:
Estado actual Entrada Proximo estado Salida
A B x NA NB y
S0: 0 0 0 S0: 0 0 0
S0: 0 0 1 S1: 0 1 0
S1: 0 1 0 S2: 1 0 0
S1: 0 1 1 S1: 0 1 0
S2: 1 0 0 S0: 0 0 0
S2: 1 0 1 S1: 0 1 1
El cuarto paso consiste en obtener las funciones logicas simplificadas que
relacionan el proximo estado y la salida con el estado actual y la entrada. Estas
funciones son:
NA = x B (4.1)
NB = x (4.2)
y = x A (4.3)
Finalmente, el quinto paso consiste en sintetizar el circuito secuencial sın-
crono que implemente las funciones logicas anteriores. Si se usan flip-flops D, las
entradas al flip-flop corresponden con el nuevo estado (DA = NA, DB = NB),
mientras que las salidas del flip-flop corresponden con el estado actual (QA = A,
QB = B). En la Figura 4.2 se muestra el circuito.
102 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 4.2: Circuito detector de la secuencia 101.
4.2 Síntesis de lógica secuencial
El comportamiento y la salida de un bloque de logica secuencial depende del valor
actual de sus entradas y de sus variables de estado. El valor de las variables de
estado se almacena tıpicamente en elementos de memoria, ya sea en latches o en
flip-flops.
– Suele llamarse latches a aquellos circuitos cuyo estado cambia unicamente
cuando su entrada enable esta a un determinado nivel (’0’ o ’1’). A conti-
nuacion, se muestra parte de la architecture de un latch-D.
process (enable, D) is
begin
if (enable = ’1’) then
q <= D;
end if;
end process;
– Suele llamarse flip-flops a aquellos circuitos cuyo estado cambia o bien en
el flanco de subida del reloj, o bien en el flanco de bajada del reloj.
4.2.1 Sentencias condicionales incompletas
Observese que el latch se define empleando una clausula if-then sin else. Se
denomina sentencias condicionales incompletas a este tipo de sentencias. Este
punto es importante, ya que muestra que las sentencias condicionales incompletas
(if, case, etc. sin else) son sintetizadas mediante latches. Esto es debido a que
la salida debe mantener su valor si ninguna de las condiciones de la clausula se
satisface.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 103
Un motivo por el cual podrıa pensarse en omitir el caso else, es que sea
indiferente el valor que se asigne a las senales en este caso (ya que en la practica
nunca se producira). Si no deseamos que el circuito se sintetice mediante un latch,
debemos incluir el caso else en la sentencia condicional y asignar a las senales el
valor ’X’ (don’t care).
4.2.2 Sentencias condicionales completas
Una caracterıstica inherente a las sentencias if-elsif-else es que las condiciones
no tienen forzosamente que ser excluyentes entre sı. La herramienta se sıntesis
asume, por tanto, que deben comprobarse las condiciones en un cierto orden de
prioridad, generando la logica para ello. Esto da lugar a circuiterıa innecesaria en
el caso en que las condiciones sean excluyentes.
En aquellos casos en que las condiciones de la sentencia condicional completa
sean excluyentes entre sı, es preferible emplear sentencias case o with. Esto
es debido a que las sentencias case y with se sintetizan de manera natural en
multiplexores o estructuras equivalente a multiplexores, que son rapidas y ocupan
relativamente poco area.
4.2.3 Retardos
En la Seccion 3.1 se explico que en la descripcion para sıntesis de los circuitos
combinacionales debe evitarse el uso de retardos. Lo mismo aplica a la descripcion
de circuitos secuenciales. Los retardos en el hardware son dependientes de la
tecnologıa empleada en su fabricacion y estan sujetos a la variabilidad del proceso
de fabricacion, por ello es extremadamente difıcil construir circuitos que presenten
un determinado retardo.
Ası pues, no es posible sintetizar sentencias tales como wait for x ns. Igual-
mente, no es posible sintetizar sentencias que empleen la clausula after. Algunas
herramientas de sıntesis ignoran estas sentencias, mientras que otras muestran
mensajes de error.
Cuando es preciso emplear retardos para describir adecuadamente el circuito,
puede definirse un retardo constante en la parte superior del codigo
constant DEL : time := 1 ns;
y usar este retardo en el codigo del circuito. Por ejemplo:
A <= B after DEL; Puede asignarse un valor positivo a esta constante
de retardo para realizar la simulacion del circuito y posteriormente asignarle el
valor cero cuando vaya a realizarse la sıntesis.
Observese que esta discusion acerca de los retardos aplica a los circuitos, no
a los bancos de prueba, que no necesitan ser sintetizados.
4.2.4 Inicialización
Debe evitarse inicializar las variables y las senales al declararlas, ya que este tipo
de inicializacion no puede ser sintetizada.
104 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
La inicializacion de una variable o senal implica una accion que se realiza
unicamente una vez al comienzo de la simulacion. Si es preciso realizar una accion
al comienzo de la simulacion, entonces debe situarse en la secuencia de acciones
que se ejecutan cuando se activa la senal de reset. Estas acciones se definen
tıpicamente dentro de un bloque process sensible a la senal de reset.
4.2.5 Bloques process
La descripcion de la architecture de los circuitos secuenciales se basa funda-
mentalmente en el empleo de bloques process. Las asignaciones a senales dentro
de los bloques process deben cumplir que:
– La senal en la parte izquierda de la asignacion concurrente debe ser una
senal definida dentro del bloque process, o una senal out o inout de la
interfaz del circuito.
– Las senales en la parte derecha de la asignacion concurrente deben ser
senales definidas dentro del bloque process, o senales in o inout de la
interfaz del circuito.
– No se debe asignar valor a una determinada senal dentro de mas de un
bloque process. Es decir, cada senal debe ser evaluada en un unico bloque
process. Aunque VHDL no impide que se asigne valor a una misma senal en
varios bloques process, esta practica da lugar a circuito difıciles de depurar
y tıpicamente no es soportada por las herramientas de sıntesis comerciales.
Para asignar valor a las salidas de los flip-flops y latches dentro de un bloque
process, pueden emplearse sentencias de asignacion a senal (usan el operador
<=) y sentencias de asignacion a variable (usan el operador :=). Las asignaciones
a variable tienen efecto inmediatamente, mientras que las asignaciones a senal
tienen efecto en un instante de tiempo delta unidades de tiempo posterior al
tiempo simulado actual (suponiendo que no se ha especificado el retraso en la
asignacion empleando la clausula after).
Cuando se emplean bloques process para describir un circuito secuencial,
debe indicarse la lista de sensibilidad de cada bloque process con el fin de con-
trolar cuando se activa el bloque. Cuando se especifica una lista de sensibilidad,
el simulador no ejecuta el bloque process hasta que no se produce un cambio en
alguna de las senales que componen la lista.
Observese que es posible controlar la ejecucion del bloque process mediante
la lista de sensibilidad y tambien mediante el empleo de clausulas wait dentro del
cuerpo el bloque process. Sin embargo, no es recomendable emplear este segundo
metodo (uso de clausulas wait dentro del bloque process), ya que puede dar lugar
a circuitos no sintetizables.
Si un bloque process no tiene lista de sensibilidad, entonces ese bloque se
ejecuta continuamente, con lo cual su simulacion es muy ineficiente. Por este
motivo, es recomendable que todo bloque process tenga su lista de sensibilidad.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 105
4.3 Flip-flop JK
En esta seccion se describe el diseno de un flip-flop JK con reset asıncrono activado
al nivel LOW. Este circuito puede encontrarse en dos estados: Q=’0’ y Q=’1’.
La tabla de verdad del circuito, considerando unicamente las entradas J (entrada
set), K (entrada reset), el estado actual (Qt) y el siguiente estado Qt+1 es la
mostrada a continuacion. Las transiciones de estado se producen en el flanco de
subida del reloj.
J (set) K (reset) Nuevo estado
0 0 Qt+1 = Qt
0 1 Qt+1 = 0
1 0 Qt+1 = 1
1 1 Qt+1 = not Qt
0 1
ÐÑ ÐÑÒÓ
ÒÓFigura 4.3: Transicion de estados de un flip-flop JK. En los arcos deldiagrama se muestra el valor de las senales JK. El bit ’X ’ es“don’t care”(porejemplo, “0X” representa “00” o “01”). La transicion de reset se representamediante una lınea punteada.
Cuando la entrada de reset pasa de valer ’1’ a valer ’0’, el circuito pasa al
estado Q=’0’. Se denomina reset asıncrono porque la transicion al estado ’0’ se
produce en el instante en que cambia la senal de reset, con independencia del
valor de la senal de reloj. La transicion de reset se representa mediante una lınea
punteada en la Figura 4.3.
El circuito tiene dos salidas: Q y Q. La salida Q es igual al estado y la salida
Q es su inversa: Q = not Q.
4.3.1 Diseño del flip-flop
A continuacion, se muestra el codigo VHDL del flip-flop JK con reset asıncrono
activado al nivel LOW. La architecture contiene un bloque process que es
sensible a la senal de reset y a la senal de reloj. En el cuerpo del bloque process
se examina primero la senal de reset, ya que en caso de estar activa esa senal (con
valor ’0’) la maquina debe pasar al estado Q=’0’.
------------------------------------------------
-- Biestable JK con reset asıncrono en nivel LOW
library IEEE;
use IEEE.std_logic_1164.all;
106 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
entity flipflop_JK is
port ( q, q_n : out std_logic;
clk, J, K, reset_n : in std_logic );
end entity flipflop_JK;
architecture flipflop_JK of flipflop_JK is
signal q_interna : std_logic;
begin
q <= q_interna;
q_n <= not q_interna;
process (reset_n, clk) is
variable JK : std_logic_vector(1 downto 0);
begin
if (reset_n = ’0’) then
q_interna <= ’0’;
elsif rising_edge(clk) then
JK := J & K;
case (JK) is
when "01" => q_interna <= ’0’;
when "10" => q_interna <= ’1’;
when "11" => q_interna <= not q_interna;
when others => null;
end case;
end if;
end process;
end architecture flipflop_JK;
------------------------------------------------
4.3.2 Banco de pruebas
En el caso de los circuitos combinacionales, el objetivo del programa de test es
comprobar (cuando esto es posible) todas las posibles combinaciones de valores
de las entradas al circuito. En los circuitos secuenciales, el programa de test debe
recorrer (cuando esto es posible) todos los arcos del diagrama de estado, para
cada uno de los valores de las entradas que producen la transicion.
En el caso del biestable JK, esto implica testear 8 transiciones. En la Figura 4.4
se indica el orden en que el programa de test recorrera los arcos (numero inscrito
en una circunferencia), y que valores de las entradas se aplicara en cada caso para
producir la transicion.
En el banco de pruebas se ha definido un procedure, que comprueba que los
valores actuales de la salida del flip-flop coinciden con los esperados, mostrando
el correspondiente mensaje en caso de que no coincidan.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 107
0 1
ÔÔÕÖ
ÖÕ××
ÔÔÕÖ ÖÕ××
ØÙ
Ú
Û
Ü
ÝÞßà
Figura 4.4: Orden en que el programa de test recorre los arcos del diagramade transiciones.
Observese que la sentencia wait que hay al final del bloque process finaliza
la ejecucion de dicho bloque, pero no la simulacion, ya que la simulacion de
las sentencias de asignacion concurrente a las senales de reset y reloj se realiza
indefinidamente. Por tanto, la simulacion del banco de pruebas no finaliza por sı
misma, siendo preciso fijar su duracion: 900 ns.
--------------------------------------
-- Banco de pruebas del flip-flop JK
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_flipflopJK is
end entity bp_flipflopJK;
architecture bp_flipflopJK of bp_flipflopJK is
constant PERIODO : time := 100 ns; -- Reloj
signal q, q_n : std_logic; -- Salidas UUT
signal clk : std_logic := ’0’; -- Entradas UUT
signal J, K, reset_n : std_logic;
component flipflop_JK is
port ( q, q_n : out std_logic;
clk, J, K, reset_n : in std_logic );
end component flipflop_JK;
-- Procedimiento para comprobar las salidas del flip-flop
procedure comprueba_salidas
( esperado_q : std_logic;
actual_q, actual_q_n : std_logic;
error_count : inout integer) is
begin
-- Comprueba q
if ( esperado_q /= actual_q ) then
report "ERROR: Estado esperado (" &
108 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
std_logic’image(esperado_q) &
"), estado actual (" &
std_logic’image(actual_q) &
"), instante: " &
time’image(now);
error_count := error_count + 1;
end if;
-- Comprueba q_n
if ( (not esperado_q) /= actual_q_n ) then
report "ERROR: q_n esperado (" &
std_logic’image((not esperado_q)) &
"), valor actual (" &
std_logic’image(actual_q_n) &
"), instante: " &
time’image(now);
error_count := error_count + 1;
end if;
end procedure comprueba_salidas;
begin
-- Instanciar y conectar UUT
uut : component flipflop_JK port map
(q, q_n, clk, J, K, reset_n);
reset_n <= ’1’,
’0’ after (PERIODO/4),
’1’ after (PERIODO+PERIODO/4);
clk <= not clk after (PERIODO/2);
gen_vec_test : process is
variable error_count : integer := 0; -- Num. errores
begin
report "Comienza la simulacion";
-- Vectores de test y comprobacion del resultado
J <= ’0’; K <= ’0’; wait for PERIODO; -- 1
comprueba_salidas(’0’,q,q_n,error_count);
J <= ’0’; K <= ’1’; wait for PERIODO; -- 2
comprueba_salidas(’0’,q,q_n,error_count);
J <= ’1’; K <= ’0’; wait for PERIODO; -- 3
comprueba_salidas(’1’,q,q_n,error_count);
J <= ’0’; K <= ’1’; wait for PERIODO; -- 4
comprueba_salidas(’0’,q,q_n,error_count);
J <= ’1’; K <= ’1’; wait for PERIODO; -- 5
comprueba_salidas(’1’,q,q_n,error_count);
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 109
J <= ’0’; K <= ’0’; wait for PERIODO; -- 6
comprueba_salidas(’1’,q,q_n,error_count);
J <= ’1’; K <= ’0’; wait for PERIODO; -- 7
comprueba_salidas(’1’,q,q_n,error_count);
J <= ’1’; K <= ’1’; wait for PERIODO; -- 8
comprueba_salidas(’0’,q,q_n,error_count);
J <= ’0’; K <= ’0’; -- Deja el flip-flop en el estado ’0’
-- Informe final
if (error_count = 0) then
report "Simulacion finalizada sin errores";
else
report "ERROR: Hay " &
integer’image(error_count) &
" errores.";
end if;
wait; -- Final del bloque process, pero como
-- la architecture tiene sentencias de
-- asignacion concurrente, esta sentencia
-- wait no finaliza la simulacion
end process gen_vec_test;
end architecture bp_flipflopJK;
--------------------------------------
La simulacion del banco de pruebas se realiza con cero errores. En la Figura 4.5
se muestra el resultado obtenido de la simulacion.
Figura 4.5: Resultado de la ejecucion del banco de pruebas del flip-flop JK.
4.4 Máquinas de estado finito de Moore
Hay varias maneras de escribir codigo VHDL para una maquina de Moore. En
primer lugar, puede escogerse describir el comportamiento o la estructura del
circuito. En la mayorıa de los casos es preferible describir el comportamiento
110 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
del circuito, ya que este tipo de descripcion suele ser menos propensa a errores
y las herramientas de sıntesis convertiran estos disenos en implementaciones
optimizadas.
En la Figura 4.6 se muestra una maquina de Moore sencilla. La transicion
entre los tres estados depende del valor de la entrada, x. La salida del circuito, z,
vale 1 en el estado S2 y 0 en los demas estados. Este codigo puede ser adaptado
facilmente para la descripcion de otras maquinas de Moore.
á/ 0S
â /1S
ã / 0S
0
1 00
1
1
Figura 4.6: Maquina de estado finito de Moore.
4.4.1 Diseño de la máquina
A continuacion se muestra el codigo VHDL que describe la maquina de Moore
mostrada en la Figura 4.6. En primer lugar, se define un package con las constan-
tes que seran usadas en el circuito y en el banco de pruebas. Definir las constantes
globales de esta manera facilita realizar cambios globales y la legibilidad del
codigo.
-------------------------------------------------------
-- Paquete con la definicion de las constantes globales
library IEEE;
use IEEE.std_logic_1164.all;
package STATE_CONSTANTS is
constant STATE_BITS: integer := 2; -- Bits codifican estado
constant S0: std_logic_vector(1 downto 0) := "00"; -- Estados
constant S1: std_logic_vector(1 downto 0) := "01";
constant S2: std_logic_vector(1 downto 0) := "10";
end package;
-------------------------------------------------------
El codigo VHDL que describe el comportamiento de la maquina de estado
finito mostrada en la Figura 4.6 es el siguiente.
------------------------------------------------------
-- Maquina de Moore
library IEEE;
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 111
use IEEE.std_logic_1164.all;
use work.STATE_CONSTANTS.all;
-- Definicion de la entidad
entity maquinaMooreSimple is
port( z : out std_logic; -- Se~nal de salida
state : out std_logic_vector(STATE_BITS-1 downto 0);
-- Estado actual de la maquina
reset_n : in std_logic; -- Se~nal reset activada en bajo
clk : in std_logic; -- Se~nal de reloj
x : in std_logic); -- Se~nal de entrada
end entity maquinaMooreSimple;
-- Definicion de la arquitectura
architecture maquinaMooreSimple of maquinaMooreSimple is
signal internal_state: std_logic_vector(STATE_BITS-1 downto 0);
begin
state <= internal_state; -- Muestra el estado
-- Genera la salida
salida: process(internal_state) is
begin
case internal_state is
when S0 => z <= ’0’;
when S1 => z <= ’0’;
when S2 => z <= ’1’;
when others => z <= ’X’;
end case;
end process salida;
-- Genera el siguiente estado
proximo_estado: process(reset_n,clk) is
begin
if (reset_n = ’0’) then -- Reset asıncrono
internal_state <= S0;
elsif rising_edge(clk) then -- En flanco subida del reloj
case internal_state is
when S0 => -- Estado actual: S0
if (x = ’1’) then
internal_state <= S1;
else
internal_state <= S2;
end if;
when S1 => -- Estado actual: S1
if (x = ’0’) then
112 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
internal_state <= S2;
end if;
when S2 => -- Estado actual: S2
if (x = ’0’) then
internal_state <= S0;
end if;
when others => -- Por completitud
internal_state <= "XX";
end case;
end if;
end process proximo_estado;
end architecture maquinaMooreSimple;
------------------------------------------------------
En el codigo anterior, puede observarse que:
– La interfaz del circuito esta compuesta por dos puertos de salida (la salida
y el estado actual) y tres puertos de entrada (senal de reset asıncrono, reloj
y entrada). Cuando la senal de reset (reset_n) pasa de valer 1 a valer 0,
entonces la maquina pasa al estado S0.
– Se ha definido una senal interna a la architecture, llamada internal_state,
que almacena el estado actual en que se encuentra la maquina. Cabe pregun-
tarse por que no se usa directamente la senal state, ya que ambas senales
representan lo mismo y, de hecho, la sentencia
state <= internal_state;
hace que ambas tengan el mismo valor. El motivo es que, por ser state
una senal de salida de la interfaz, no puede ser leıda en el cuerpo de la
architecture. Puesto que internal_state es una senal interna, puede ser
leıda y escrita.
– La architecture contiene dos bloques process:
1. El primero, que es activado cuando hay un cambio en internal_state,
describe los cambios en la senal de salida, z.
2. El segundo, que es activado cuando cambia la senal de reset asıncrono
(reset_n) o el reloj (clk), describe los cambios en el estado de la
maquina, actualizando el valor de la senal internal_state.
Puesto que se comprueba antes el valor de reset_n, esta senal tiene
prioridad sobre la senal de reloj.
Se emplea la funcion estandar de VHDL rising edge para representar
que las transiciones en el estado solo se producen en el flanco de subida
de la senal de reloj.
– Se ha anadido una clausula when other al final de los dos bloques case,
con el fin de contemplar todos los casos posibles. Observese que se asigna
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 113
el valor ’X’ (don’t care) a la senal de salida. Esta es una buena practica,
ya que con ello se ayuda a la herramienta de sıntesis a optimizar el circuito
combinacional para la senal de salida (z).
4.4.2 Banco de pruebas
A continuacion, se muestra el codigo VHDL de un banco de pruebas que puede
usarse para comprobar el funcionamiento de la maquina de estado finito. El
programa de test ejercita completamente la maquina: todos los arcos de las
transiciones son recorridos al menos una vez.
En la Figura 4.7 se indica el instante de tiempo en el cual se produce la
transicion entre los estados. La constante T es el periodo de la senal de reloj, que
en el codigo VHDL del banco de pruebas de denomina PERIODO y toma el valor
100 ns. La senal de reloj, que inicialmente vale 0, tiene un periodo (PERIODO)
de T = 100 ns. Esto implica que los flancos de subida de la senal de reloj se
producen en los instantes: 0.5 · T = 50 ns, 1.5 · T = 150 ns, 2.5 · T = 250 ns, . . .
que son precisamente los instantes en que se producen las sucesivas transiciones
en el estado, segun se muestra en la Figura 4.7. Para generar la senal de reloj se
emplea la siguiente sentencia concurrente:
clk <= not clk after ( PERIODO/2 );
donde se asume que la senal de reloj ha sido inicializada al valor ’0’. Observese
que de esta forma se crea una senal de reloj infinitamente larga, con lo cual la
simulacion no finalizara automaticamente, sino que hay que definir el instante de
finalizacion.
ä / 0S
å /1S
æ / 0S çèé ê⋅
ëìí î⋅
ïìí î⋅
ðìí î⋅
íìí î⋅
ñìí î⋅
òóôõö÷ö øùù úûü= =
ýþÿ� �⋅
Figura 4.7: Transiciones en el estado realizadas durante el test.
En el codigo del banco de pruebas, se define un procedimiento para comparar
el valor esperado del estado y la salida de la maquina con los actuales. De esta
forma el codigo se hace mas facilmente comprensible.
------------------------------------------------------
-- Banco de pruebas para la maquina de Moore
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
114 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
use work.STATE_CONSTANTS.all;
-- Definicion de la entity
entity bp_maquinaMooreSimple is
constant PERIODO : time := 100 ns; -- Periodo reloj
end entity bp_maquinaMooreSimple;
-- Definicion de la architecture
architecture bp_maquinaMooreSimple of bp_maquinaMooreSimple is
signal z : std_logic;
signal state : std_logic_vector(STATE_BITS-1 downto 0);
signal reset_n : std_logic;
signal clk : std_logic := ’0’; -- Inicializada a ’0’
signal x : std_logic;
-- Declaracion del componente: UUT
component maquinaMooreSimple is
port( z : out std_logic; -- Se~nal de salida
state : out std_logic_vector(STATE_BITS-1 downto 0);
-- Estado actual de la maquina
reset_n : in std_logic; -- Se~nal reset activada en bajo
clk : in std_logic; -- Se~nal de reloj
x : in std_logic); -- Se~nal de entrada
end component maquinaMooreSimple;
-- Procedimiento para comprobar el resultado
procedure comprueba_state_z
( esperado_state : std_logic_vector(STATE_BITS-1 downto 0);
esperado_z : std_logic;
actual_state : std_logic_vector(STATE_BITS-1 downto 0);
actual_z : std_logic;
error_count : inout integer ) is
begin
-- Comprueba el estado
assert ( esperado_state = actual_state )
report "ERROR : estado esperado (" &
std_logic’image(esperado_state(1)) &
std_logic’image(esperado_state(0)) &
"), estado actual (" &
std_logic’image(actual_state(1)) &
std_logic’image(actual_state(0)) &
") en el instante " &
time’image(now);
if ( esperado_state /= actual_state ) then
error_count := error_count + 1;
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 115
end if;
-- Comprueba la salida
if ( esperado_z /= actual_z ) then
report "ERROR: salida esperada (" &
std_logic’image(esperado_z) &
"), salida actual (" &
std_logic’image(actual_z) &
") en el instante " &
time’image(now);
error_count := error_count + 1;
end if;
end procedure comprueba_state_z;
-- Cuerpo de la architecture
begin
-- Instancia UUT
UUT : component maquinaMooreSimple port map
( z, state, reset_n, clk, x );
-- Genera un unico pulso LOW para reset_n
-- En el instante PERIODO/4 se resetea la maquina
reset_n <= ’1’,
’0’ after ( PERIODO/4 ),
’1’ after ( PERIODO + PERIODO/4 );
-- Genera se~nal clk, asumiendo que se inicializo a 0
-- Flanco de subida en los instantes:
-- PERIODO/2, PERIODO+PERIODO/2, 2*PERIODO+PERIODO/2, ...
clock : clk <= not clk after ( PERIODO/2 );
-- main process:
-- genera vectores de test y comprueba resultados
main : process is
variable error_count : integer := 0; -- Num. errores
begin
report "Comienza la simulacion";
x <= ’0’; -- Valor inicial de entrada a UUT
wait for PERIODO;
-- En el instante PERIODO, el estado deberıa ser S0
comprueba_state_z(S0, ’0’, state, z, error_count);
wait for PERIODO;
-- En el instante 2*PERIODO, el estado deberıa ser S2
comprueba_state_z(S2, ’1’, state, z, error_count);
x <= ’1’;
wait for PERIODO;
116 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
-- En el instante 3*PERIODO, el estado deberıa ser S2
comprueba_state_z(S2, ’1’, state, z, error_count);
x <= ’0’;
wait for PERIODO;
-- En el instante 4*PERIODO, el estado deberıa ser S0
comprueba_state_z(S0, ’0’, state, z, error_count);
x <= ’1’;
wait for PERIODO;
-- En el instante 5*PERIODO, el estado deberıa ser S1
comprueba_state_z(S1, ’0’, state, z, error_count);
wait for PERIODO;
-- En el instante 6*PERIODO, el estado deberıa ser S1
comprueba_state_z(S1, ’0’, state, z, error_count);
x <= ’0’;
wait for PERIODO;
-- En el instante 7*PERIODO, el estado deberıa ser S2
comprueba_state_z(S2, ’1’, state, z, error_count);
x <= ’1’; -- El estado final es S2
wait for PERIODO;
if (error_count = 0) then
report "Simulacion finalizada con 0 errores";
else
report "ERROR: hay " &
integer’image(error_count) &
" errores.";
end if;
wait; -- Final de la ejecucion del bloque process.
-- La simulacion continua debido a la sentencia de
-- asignacion a la se~nal clk
end process main;
end architecture bp_maquinaMooreSimple;
En la Figura 4.8 se muestran las formas de onda obtenidas al ejecutar el banco
de pruebas. El test de ejecuta con cero errores.
Figura 4.8: Resultado de la ejecucion del test.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 117
4.4.3 Modelado estructural
Ahora veremos como describir la maquina de estado finito de la Figura 4.6
empleando codigo VHDL estructural. Usando codigo estructural se tiene mayor
control acerca de la logica que se emplea en el diseno, con lo cual pueden conse-
guirse circuitos mas optimizados que los dados por las herramientas de sıntesis a
partir de la descripcion del comportamiento. Sin embargo, implica realizar parte
del diseno manualmente, con el consiguiente riesgo de cometer errores.
Para emplear codigo VHDL estructural, en primer lugar hay que decidir que
componentes van a usarse en el diseno. Emplearemos puertas logicas basicas
(AND, OR, inversor, NAND, NOR y XOR), ası como flip-flops tipo D tales como
el descrito en el Ejemplo 2.3.4.
A continuacion, debemos obtener las funciones logicas para el calculo de la
salida y del siguiente estado. La tabla de transicion de estados y salidas para la
maquina descrita en la Figura 4.6 es la siguiente:
Estado actual Entrada Proximo estado Salida
A B x NA NB z
S0: 0 0 0 S2: 1 0 0
S0: 0 0 1 S1: 0 1 0
S1: 0 1 0 S2: 1 0 0
S1: 0 1 1 S1: 0 1 0
S2: 1 0 0 S0: 0 0 1
S2: 1 0 1 S2: 1 0 1
Las funciones logicas simplificadas que relacionan el proximo estado (NA,
NB) y la salida (z), con el estado actual (A, B) y la entrada (x) son:
NA = x A + x A (4.4)
NB = x A (4.5)
z = A (4.6)
Puede escribirse el siguiente codigo VHDL estructural a partir de la funciones
logicas anteriores. Se define una nueva architecture para la entity del circuito
anteriormente definida.
------------------------------------------------------
-- Maquina de Moore, dise~no estructural
library IEEE;
use IEEE.std_logic_1164.all;
-- Definicion de la arquitectura
architecture maquinaMooreSimple_estruc of maquinaMooreSimple is
signal A, B : std_logic; -- Variables de estado actuales
signal NA, NB : std_logic; -- Proximas variables de estado
118 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
-- Componente: flip-flop D
component flipflop_D is
port ( q, q_n : out std_logic;
d, clk, reset_n : in std_logic);
end component flipflop_D;
begin
state <= A & B; -- Muestra estado actual en el puerto de salida
-- Conexiones de los flip-flops
-- Las salidas q_n se dejan sin conectar
dff_A: component flipflop_D port map
( q => A, d => NA, clk => clk, reset_n => reset_n );
dff_B: component flipflop_D port map
( q => B, d => NB, clk => clk, reset_n => reset_n );
-- Funciones para el calculo del nuevo estado y la salida
NA <= ((not x) and (not A)) or (x and A);
NB <= x and (not A);
z <= A;
end architecture maquinaMooreSimple_estruc;
------------------------------------------------------
Puede emplearse el banco de pruebas descrito en la Seccion 4.4.2 para testear
esta descripcion del circuito. Se obtienen los mismos resultados que se obtuvieron
cuando se hizo el test de la descripcion del comportamiento (vease la Figura 4.8).
Los resultados del test se muestran en la Figura Figura 4.9.
Figura 4.9: Resultado de la ejecucion del test.
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 119
4.5 Máquinas de estado finito de Mealy
En las maquinas de Mealy, las salidas del circuito dependen del estado actual y
del valor actual de las entradas. Ası pues, aunque la maquina permanezca en un
determinado estado, sus salidas pueden cambiar si cambian las entradas.
Como ejemplo de implementacion de una maquina de Mealy, consideremos
la maquina para el reconocimiento de la secuencia de bits 0110 mostrada en la
Figura 4.10. Observese que se permite el solapamiento de secuencias (por ejemplo,
0110110).
La salida de la maquina es un ’1’ logico cada vez que se detecta el patron
0110 en la secuencia de bits de entrada, que se supone que esta sincronizada con
el reloj de la maquina. El tiempo que transcurre entre la entrada del ultimo ’0’
del patron y la salida del ’1’ es igual al retardo de una puerta logica. Para los
demas bits de la secuencia de entrada, la salida de la maquina es ’0’.
���
���
���
���
�S
�S
S
S
���
���
���
���
Figura 4.10: Diagrama de estado de una maquina de Mealy para elreconocimiento de la secuencia 0110.
4.5.1 Diseño de la máquina
Ademas de la entrada serie de la secuencia de bits (x) y la entrada del reloj (clk),
la maquina tiene una entrada de reset sıncrono activada en ’0’ (reset_n). Esto
significa que si cuando se produce un flanco de subida de la senal del reloj, la
entrada reset_n vale ’0’, entonces se resetea la maquina, es decir, pasa al estado
S0.
La maquina tiene dos salidas: el estado actual de la maquina (state) y la
salida de deteccion del patron 0110 (z).
Las constantes globales, que son usadas tanto en el diseno del circuito como
en el banco de pruebas, son definidas en el package mostrado a continuacion.
----------------------------------------
-- Definicion de las constantes globales
library IEEE;
use IEEE.std_logic_1164.all;
120 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
package seq0110_CONST is
constant STATE_BITS : integer := 2; -- Num. bits del estado
constant S0 : std_logic_vector(1 downto 0) := "00";
constant S1 : std_logic_vector(1 downto 0) := "01";
constant S2 : std_logic_vector(1 downto 0) := "10";
constant S3 : std_logic_vector(1 downto 0) := "11";
end package seq0110_CONST;
----------------------------------------
A continuacion se muestra el codigo VHDL que describe el comportamiento
de la maquina. Observese que se han definido dos bloques process: uno para
generar la salida, que es sensible al estado y a la entrada, y otro para generar el
proximo estado y resetear al maquina, que es sensible unicamente a la senal de
reloj. Puesto que la maquina tiene reset sıncrono, este segundo bloque process
no es sensible a la senal de reset.
--------------------------------------------------
-- Maquina de Mealy detectora de la secuencia 0110
library IEEE;
use IEEE.std_logic_1164.all;
use work.seq0110_CONST.all;
-- Definicion de la entity
entity seq0110 is
port ( z : out std_logic; -- Se~nal de salida
state : out std_logic_vector(STATE_BITS-1 downto 0);
-- Estado actual
reset_n : in std_logic; -- Reset sıncrono activado LOW
clk : in std_logic; -- Se~nal de reloj
x : in std_logic ); -- Bit de entrada
end entity seq0110;
-- Definicion de la architecture
architecture seq0110 of seq0110 is
signal internal_state : std_logic_vector(STATE_BITS-1 downto 0);
begin
state <= internal_state;
-- Calculo de la salida
calculo_salida: process (internal_state, x) is
begin
if ( (internal_state = S3) and (x = ’0’) ) then
z <= ’1’;
else
z <= ’0’;
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 121
end if;
end process calculo_salida;
-- Calculo del proximo estado
proximo_estado: process (clk) is
begin
if ( (reset_n = ’0’) and rising_edge(clk) ) then -- Reset sıncrono
internal_state <= S0;
elsif rising_edge(clk) then -- Flanco de subida del reloj
case internal_state is
when S0 =>
if (x = ’0’) then -- Primer bit del patron
internal_state <= S1;
else
internal_state <= S0;
end if;
when S1 =>
if (x = ’1’) then -- Segundo bit del patron
internal_state <= S2;
else
internal_state <= S1;
end if;
when S2 =>
if (x = ’1’) then -- Tercer bit del patron
internal_state <= S3;
else
internal_state <= S1;
end if;
when others =>
if (x = ’0’) then -- Cuarto bit del patron
internal_state <= S1;
else
internal_state <= S0;
end if;
end case;
end if;
end process proximo_estado;
end architecture seq0110;
--------------------------------------------------
El bloque process usado para generar el proximo estado corresponde di-
rectamente con el diagrama mostrado en la Figura 4.10. La senal de reset no
se ha incluido en la lista de senales a las que es sensible el bloque. Ası pues,
este bloque solo es activado cuando se produce un cambio en la senal de reloj:
la condicion if ( (reset_n = ’0’) and rising_edge(clk) ) solo se comprueba
122 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
cuando se produce un cambio en la senal de reloj. De esta forma, se implementa
un reset sıncrono.
El bloque process usado para generar la senal de salida podrıa reemplazarse
por la siguiente sentencia concurrente:
z <= ’1’ when ( (internal_state = S3) and (x = ’0’) ) else ’0’;
que es activada cada vez que se produce un cambio en alguna de las senales de
la parte derecha de la asignacion.
Puesto que este es un bloque combinacional, la duracion de la senal ’1’ de
salida puede ser mas pequena que un ciclo de reloj, ya que su duracion depende
del tiempo durante el cual la entrada x siga valiendo ’0’ mientras la maquina
permanezca en el estado S3.
Para garantizar que la salida ’1’ tiene una duracion de al menos un ciclo de
reloj, es necesario hacer pasar la senal de salida por un flip-flop D. Esto puede
hacerse anadiendo a la descripcion de la arquitectura el siguiente bloque process:
ffD_salida: process (clk) is
begin
if ( rising_edge(clk) ) then
z_long <= z;
end if;
end process ffD_salida;
y haciendo que z_long sea la salida del circuito. La definicion del circuito, modi-
ficada de la forma descrita anteriormente, es mostrada a continuacion.
--------------------------------------------------
-- Maquina de Mealy detectora de la secuencia 0110
library IEEE;
use IEEE.std_logic_1164.all;
use work.seq0110_CONST.all;
-- Definicion de la entity
entity seq0110 is
port ( z_long : out std_logic; -- Se~nal de salida
state : out std_logic_vector(STATE_BITS-1 downto 0);
-- Estado actual
reset_n : in std_logic; -- Reset sıncrono activado LOW
clk : in std_logic; -- Se~nal de reloj
x : in std_logic ); -- Bit de entrada
end entity seq0110;
-- Definicion de la architecture
architecture seq0110 of seq0110 is
signal internal_state : std_logic_vector(STATE_BITS-1 downto 0);
signal z : std_logic; -- Se~nal de salida obtenida
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 123
-- a partir del estado actual
-- y la entrada actual, mediante
-- un circuito combinacional
begin
state <= internal_state;
-- Calculo de la salida
-- z <= ’1’ when ( (internal_state = S3) and (x = ’0’) ) else ’0’;
calculo_salida: process (internal_state,x) is
begin
if ( (internal_state = S3) and (x = ’0’) ) then
z <= ’1’;
else
z <= ’0’;
end if;
end process calculo_salida;
-- Se hace pasar la salida por un flip-flop D para garantizar que
-- se mantiene su valor un ciclo de reloj
ffD_salida: process (clk) is
begin
if ( rising_edge(clk) ) then
z_long <= z;
end if;
end process ffD_salida;
-- Calculo del proximo estado
proximo_estado: process (clk) is
begin
if ( (reset_n = ’0’) and rising_edge(clk) ) then -- Reset sıncrono
internal_state <= S0;
elsif rising_edge(clk) then -- Flanco de subida del reloj
case internal_state is
when S0 =>
if (x = ’0’) then -- Primer bit del patron
internal_state <= S1;
else
internal_state <= S0;
end if;
when S1 =>
if (x = ’1’) then -- Segundo bit del patron
internal_state <= S2;
else
internal_state <= S1;
end if;
124 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
when S2 =>
if (x = ’1’) then -- Tercer bit del patron
internal_state <= S3;
else
internal_state <= S1;
end if;
when others =>
if (x = ’0’) then -- Cuarto bit del patron
internal_state <= S1;
else
internal_state <= S0;
end if;
end case;
end if;
end process proximo_estado;
end architecture seq0110;
--------------------------------------------------
Para mostrar el funcionamiento del circuito, puede disenarse un pequeno
banco de pruebas que introduzca algunos vectores de test. A continuacion, se
muestra un ejemplo de este tipo de banco de pruebas.
------------------------------------------------------
-- Banco de pruebas que introduce algunos vectores de
-- test en la maquina detectora de la secuencia 0110
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.seq0110_CONST.all;
entity bp1_seq0110 is
constant PERIODO : time := 100 ns; -- Periodo reloj
end entity bp1_seq0110;
architecture bp1_seq0110 of bp1_seq0110 is
signal z_long : std_logic; -- Salida de la maquina
signal state : std_logic_vector(STATE_BITS-1 downto 0);
-- Estado actual
signal reset_n : std_logic; -- Reset sıncrono activado LOW
signal clk : std_logic := ’0’; -- Se~nal de reloj
signal x : std_logic; -- Entrada a la maquina
-- Declaracion del componente
component seq0110 is
port ( z_long : out std_logic;
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 125
state : out std_logic_vector(STATE_BITS-1 downto 0);
reset_n : in std_logic;
clk : in std_logic;
x : in std_logic );
end component seq0110;
begin
-- Instanciar UUT
UUT: component seq0110 port map
( z_long, state, reset_n, clk, x );
-- Generar un pulso LOW en la entrada de reset
reset_n <= ’1’,
’0’after ( PERIODO/4 ),
’1’after ( PERIODO + PERIODO/4 );
-- Generar la se~nal de reloj,
-- asumiendo que ha sido inicializada a ’0’
clk <= not clk after ( PERIODO/2 );
-- Generar algunos vectores de test
main : process is
begin
report "Comienza la simulacion";
x <= ’0’; wait for 2*PERIODO;
x <= ’1’; wait for PERIODO;
x <= ’1’; wait for PERIODO;
x <= ’0’; wait for PERIODO;
x <= ’1’; wait for PERIODO;
x <= ’1’; wait for PERIODO;
x <= ’0’; wait for PERIODO;
x <= ’1’; wait for PERIODO;
wait; -- Detiene este bloque process, pero no
-- finaliza la simulacion debido a que
-- hay asignaciones concurrentes
end process main;
end architecture bp1_seq0110;
Ejecutando este banco de pruebas durante 1200 ns, se obtienen las senales
mostradas en la Figura 4.11. Observese que la senal z vale ’1’ mientras el circuito
se encuentra en el estado S3 y la entrada vale ’0’. La senal z esta conectada a la
entrada de un flip-flop D, cuya salida es la senal z_long, que mantiene su valor a
’1’ durante un ciclo completo de reloj.
126 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura 4.11: Resultado de la simulacion del circuito detector del patron0110.
4.5.2 Banco de pruebas
El banco de pruebas anterior da cierta informacion acerca del comportamiento del
circuito, pero no lo prueba de manera sistematica. A continuacion, se muestra el
codigo de un banco de pruebas que testea sistematicamente el circuito, pasando
al menos una vez por cada uno de los arcos de transicion entre estados de la
maquina. El orden en el cual el banco de pruebas recorre los arcos de transicion
de la maquina es mostrado en la Figura 4.12. El codigo del banco de pruebas es
mostrado a continuacion.
�S
�S
S
�S
1
2
3
4
5
6
7
89
10 11
12
13
Figura 4.12: Orden en que el programa de test recorre los arcos del diagramade estado de la maquina.
------------------------------------------------------
-- Banco de pruebas - Maquina detectora secuencia 0110
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.seq0110_CONST.all;
entity bp_seq0110 is
constant PERIODO : time := 100 ns; -- Periodo reloj
end entity bp_seq0110;
architecture bp_seq0110 of bp_seq0110 is
signal z_long : std_logic; -- Salida de la maquina
signal state : std_logic_vector(STATE_BITS-1 downto 0);
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 127
-- Estado actual
signal reset_n : std_logic; -- Reset sıncrono activado LOW
signal clk : std_logic := ’0’; -- Se~nal de reloj
signal x : std_logic; -- Entrada a la maquina
-- Declaracion del componente
component seq0110 is
port ( z_long : out std_logic;
state : out std_logic_vector(STATE_BITS-1 downto 0);
reset_n : in std_logic;
clk : in std_logic;
x : in std_logic );
end component seq0110;
-- Procedimiento para comprobar si se produce error
procedure comprueba_estado_salida
( esperado_state : std_logic_vector(STATE_BITS-1 downto 0);
esperado_z : std_logic;
actual_state : std_logic_vector(STATE_BITS-1 downto 0);
actual_z : std_logic;
error_count : inout integer) is
begin
-- Comprueba el estado
assert( esperado_state = actual_state )
report "ERROR: Estado esperado (" &
std_logic’image(esperado_state(1)) &
std_logic’image(esperado_state(0)) &
"), estado actual (" &
std_logic’image(actual_state(1)) &
std_logic’image(actual_state(0)) &
"), instante: " &
time’image(now);
if ( esperado_state /= actual_state ) then
error_count := error_count + 1;
end if;
-- Comprueba salida
assert( esperado_z = actual_z )
report "ERROR: Salida esperada (" &
std_logic’image(esperado_z) &
"), salida actual (" &
std_logic’image(actual_z) &
"), instante: " &
time’image(now);
if ( esperado_z /= actual_z ) then
128 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
error_count := error_count + 1;
end if;
end procedure comprueba_estado_salida;
begin
-- Instanciar UUT
UUT: component seq0110 port map
( z_long, state, reset_n, clk, x );
-- Generar un pulso LOW en la entrada de reset
reset_n <= ’1’,
’0’after ( PERIODO/4 ),
’1’after ( PERIODO + PERIODO/4 );
-- Generar la se~nal de reloj,
-- asumiendo que ha sido inicializada a ’0’
clk <= not clk after ( PERIODO/2 );
-- Generar vectores de test y comprobar el resultado
main : process is
variable error_count : integer := 0; -- Num. errores
begin
report "Comienza la simulacion";
x <= ’0’; wait for PERIODO; -- Comprueba reset, empieza en S0
comprueba_estado_salida(S0,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Sigue en S0
comprueba_estado_salida(S0,’0’,state,z_long,error_count);
x <= ’0’; wait for PERIODO; -- Va a S1
comprueba_estado_salida(S1,’0’,state,z_long,error_count);
x <= ’0’; wait for PERIODO; -- Sigue en S1
comprueba_estado_salida(S1,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Va a S2
comprueba_estado_salida(S2,’0’,state,z_long,error_count);
x <= ’0’; wait for PERIODO; -- Va a S1
comprueba_estado_salida(S1,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Va a S2
comprueba_estado_salida(S2,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Va a S3
comprueba_estado_salida(S3,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Va a S0
comprueba_estado_salida(S0,’0’,state,z_long,error_count);
x <= ’0’; wait for PERIODO; -- Va a S1
comprueba_estado_salida(S1,’0’,state,z_long,error_count);
x <= ’1’; wait for PERIODO; -- Va a S2
comprueba_estado_salida(S2,’0’,state,z_long,error_count);
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 129
x <= ’1’; wait for PERIODO; -- Va a S3
comprueba_estado_salida(S3,’0’,state,z_long,error_count);
x <= ’0’; wait for PERIODO/4; -- Va a S1
comprueba_estado_salida(S3,’0’,state,z_long,error_count);
-- Salida ’0’ en S3
wait for 3*(PERIODO/4);
comprueba_estado_salida(S1,’1’,state,z_long,error_count);
-- Salida ’1’ en S1
wait for PERIODO; -- Sigue en S1
comprueba_estado_salida(S1,’0’,state,z_long,error_count);
wait for PERIODO; -- Tests finalizados
if (error_count = 0) then
report "Simulacion finalizada sin errores";
else
report "ERROR: Hay " &
integer’image(error_count) &
" errores.";
end if;
wait; -- Detiene este bloque process, pero no
-- finaliza la simulacion debido a que
-- hay asignaciones concurrentes
end process main;
end architecture bp_seq0110;
El test se ejecuta durante 1500 ns, sin que se produzca ningun error. En la
Figura 4.13 se muestra la evolucion de las senales durante los primeros 1400 ns.
Figura 4.13: Resultado de la simulacion del programa de test.
130 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
4.6 Descripción VHDL de alto nivel
Las herramientas de sıntesis actuales son capaces de generar circuitos eficientes
a partir de una descripcion RTL (register-transfer level) del circuito. De hecho, a
menos que el disenador este muy familiarizado con la arquitectura hardware en la
que va a implementarse el circuito, generalmente se obtienen mejores circuitos si
se realiza una descripcion VHDL de alto nivel del circuito y se emplea una buena
herramienta de sıntesis, en lugar de disenar manualmente (al nivel de puertas
logicas o transistores) el circuito.
Debido a esto, el metodo de diseno de hardware recomendado actualmente
es realizar una descripcion VHDL de alto nivel del circuito y emplear una buena
herramienta de sıntesis para obtener la netlist para la arquitectura hardware de la
implementacion. Cuando se describe el comportamiento del circuito a alto nivel,
la herramienta de sıntesis tiene mayor libertad para optimizar su estructura,
produciendo circuitos mas eficientes.
Por ejemplo, si el disenador realiza una descripcion estructural basada en
puertas NAND, o emplean una secuencia de ecuaciones logicas para describir
el circuito, entonces la herramienta de sıntesis solo puede eliminar las puertas
redundantes y simplificar las funciones logicas. En cambio, si el disenador describe
el comportamiento esperado de ese mismo circuito, la herramienta de sıntesis
puede producir un diseno logico completamente diferente que sea mas eficiente
que el considerado originalmente por el disenador.
Para ilustrar como puede realizarse una descripcion VHDL de alto nivel a
partir de una descripcion algorıtmica, consideraremos nuevamente el diseno de
un circuito detector de patrones en una secuencia de bits.
4.6.1 Circuito detector de secuencia
Supongamos que deseamos disenar un circuito para la deteccion de la siguiente
secuencia de entrada serie: 0111 1110 (esta secuencia de emplea frecuentemente
como marcadora de final de paquete). El siguiente algoritmo permite resolver este
problema:
Paso 1. prev_data <- 1111 1111; /* Almacena 8 bits anteriores */
Paso 2. while (true) do /* Se repite indefinidamente */
data_in <- siguiente dato de entrada;
prev_data <- prev_data << 1 /* Desplazamiento izqda */
prev_data[0] <- data_in; /* Se almacena data_in en LSB */
if (prev_data == 0111 1110) then
detectado <- 1; /* Secuencia detectada */
else
detectado <- 0; /* Secuencia no detectada */
end while
El codigo VHDL del circuito detector de secuencia puede escribirse direc-
tamente basandose en el algoritmo anterior. A continuacion, se muestran dos
versiones de la descripcion del circuito: una en la cual prev_data es una variable
Capıtulo 4 Casos practicos de diseno de circuitos secuenciales 131
y otra en la cual es una senal. Ambas descripciones de la arquitectura son
igualmente validas.
-------------------------------------------
-- Circuito detector de secuencia 0111 1110
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity detector_sec is
port ( detectado : out std_logic;
reset_n : in std_logic;
clk : in std_logic;
data_in : in std_logic );
end entity detector_sec;
architecture detector_sec1 of detector_sec is
begin
process (reset_n, clk) is
variable prev_data : unsigned (7 downto 0);
begin
if (reset_n = ’0’) then
prev_data := B"1111_1111";
elsif rising_edge(clk) then
prev_data := prev_data sll 1;
prev_data(0) := data_in;
if (prev_data = B"0111_1110") then
detectado <= ’1’;
else
detectado <= ’0’;
end if;
end if;
end process;
end architecture detector_sec1;
-------------------------------------------
La unica diferencia entre la descripcion en VHDL y la descripcion algorıtmica,
aparte del uso de la sintaxis de VHDL, es que en el codigo VHDL no se ha incluido
la sentencia
data_in <- siguiente dato de entrada;
En el codigo VHDL no es necesario realizar la asignacion del siguiente bit de
la secuencia de entrada a data_in porque se supone que los bits de datos entran
en sincronıa con el flanco de subida de la senal de reloj.
A continuacion, se muestra otra forma de describir la architecture del cir-
cuito. En este caso, prev_data es una senal.
132 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
-------------------------------------------
architecture detector_sec2 of detector_sec is
signal prev_data : unsigned (7 downto 0);
begin
process (reset_n, clk) is
begin
if (reset_n = ’0’) then
prev_data <= B"1111_1111";
elsif rising_edge(clk) then
prev_data <= (prev_data(6 downto 0) & data_in);
if ((prev_data(6 downto 0) & data_in) = B"0111_1110") then
detectado <= ’1’;
else
detectado <= ’0’;
end if;
end if;
end process;
end architecture detector_sec2;
-------------------------------------------
La sentencia
prev_data <= (prev_data(6 downto 0) & data_in);
realiza un desplazamiento logico de un bit hacia la izquierda e inserta data_in en
el bit menos significativo.
Puesto que la asignacion a senales no tiene efecto inmediatamente, sino un
delta de tiempo posterior al tiempo simulado actual, esta operacion de des-
plazamiento se ejecuta concurrentemente con la sentencia if que comprueba la
igualdad con B"0111_1110". Puesto que el valor de prev_data todavıa no ha sido
actualizado en el momento en que se realiza la comparacion, es necesario realizar
la comparacion usando el valor de prev_data anterior al desplazamiento.
AVeriBest VB99.0
Objetivos. Instalar en su propio ordenador y realizar las operaciones basicas demanejo del entorno de simulacion de VHDL’93 VeriBest. Estas operaciones basicasincluyen al menos:
– Edicion y compilacion de modelos.
– Simulacion y visualizacion de los resultados.
– Depurado usando el debugger.
A.1 Instalación
La version de evaluacion VB99.0 presenta la limitacion siguiente: el modelo no
puede superar las 2000 lıneas o las 2000 referencias a componentes. Para instalar
Veribest VB99.0, pueden seguirse los pasos siguientes:
1. Ejecute el fichero setup.exe, que se encuentra dentro del directorio VHDL Si-
mulator.
2. Acepte los terminos de la licencia.
3. Escoja el directorio en el cual desea que se instale el simulador.
4. Seleccione para su instalacion “VeriBest VHDL Simulator”, que es la opcion
senalada por defecto.
5. El programa de instalacion copia todos los ficheros necesarios en el disco,
creando en el grupo de programas de Windows un nuevo grupo llamado
VeriBest VB99.0. Dentro de este hay una carpeta, “VeriBest VHDL Simu-
lator”, en la que se encuentra el simulador VHDL (VeriBest VHDL), un
tutorial y la documentacion en lınea.
134 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
A.2 Circuito digital ejemplo: buffer triestado
Va a emplearse el modelo de un buffer triestado para ilustrar las explicaciones
acerca del manejo del simulador. Este tipo de componente se emplea comunmente
para conectar varios dispositivos a un mismo bus. Tal como se muestra en la
Figura A.1, el buffer triestado tiene dos entradas (d y E) y una salida (y). La
salida puede tomar tres valores: 0, 1 y Z (alta impedancia). El estado de alta
impedancia es equivalente a un interruptor abierto. Dependiendo del valor de la
entrada E, la salida puede tomar el valor de la entrada o el valor Z.
E
ydd1
Z0
YE
b)a)
Figura A.1: Buffer triestado: a) sımbolo logico; b) tabla de verdad.
A.2.1 Modelo VHDL del buffer triestado
-------------------------------------------
-- Buffer triestado
library IEEE;
use IEEE.std_logic_1164.all;
entity Buffer_TriEstado is port
( E : in std_logic;
d : in std_logic;
y : out std_logic);
end entity Buffer_TriEstado ;
architecture Behavioral of Buffer_TriEstado is
begin
process (E, d)
begin
if (E = ’1’ ) then
y <= d ;
else
y <= ’Z’;
end if;
end process;
end architecture Behavioral;
-------------------------------------------
Apendice A VeriBest VB99.0 135
A.2.2 Banco de pruebas
El siguiente banco de pruebas genera las 22 posibles combinaciones de entradas
al buffer.
--------------------------------------
-- Banco de pruebas
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_Buffer_TriEstado is
end entity bp_Buffer_TriEstado;
architecture bp_Buffer_TriEstado of bp_Buffer_TriEstado is
signal y : std_logic; -- Conectar salida UUT
signal d, E : std_logic; -- Conectar entradas UUT
component Buffer_TriEstado is port
( E, d : in std_logic;
y : out std_logic);
end component Buffer_TriEstado;
begin
-- Instanciar y conectar UUT
uut : component Buffer_TriEstado port map
( E => E, d => d, y => y);
gen_vec_test : process
begin
E <= ’0’;
d <= ’0’;
wait for 5 ns;
d <= ’1’;
wait for 5 ns;
E <= ’1’;
wait for 10 ns;
d <= ’0’;
wait;
end process gen_vec_test;
end architecture bp_Buffer_TriEstado;
--------------------------------------
136 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
A.3 Edición y compilación de un modelo
En esta seccion se describe como editar y compilar modelos con el simulador
VeriBest VHDL.
A.3.1 Arranque del simulador VeriBest VHDL
Seleccione el icono VeriBest VHDL del grupo de programas Inicio → Programas
→ Veribest VB99.0 → Veribest VHDL Simulator.
A.3.2 Creación de un espacio de trabajo
Para crear un espacio de trabajo, puede seguir una de las dos opciones siguientes:
1. Despliegue el menu “Workspace” y seleccione la opcion “New... ”
2. Seleccione el comando “New...” del menu “File”. Se mostrara una ventana
en la que tiene que seleccionar la opcion “VHDL Workspace”.
Tras seguir una de estas dos opciones, se mostrara una ventana (vease la
Figura A.2). Teclee en dicha ventana el nombre del espacio de trabajo, que en
este caso se ha llamado bufferTriestado.
Figura A.2: Espacio de trabajo.
Aparecera en el lateral izquierdo de la ventana principal del simulador una
nueva ventana con el tıtulo bufferTriestado.vpd. Inicialmente, la ventana solo
muestra una carpeta vacıa, denominada bufferTriestado source (vease la Figura
A.3).
En dicha ventana ubicaremos todos los ficheros necesarios para simular el
buffer triestado, que en este caso son dos: la descripcion del circuito (bufferTries-
tado.vhd) y de su banco de pruebas (bp bufferTriestado.vhd). Al igual que el buffer
Apendice A VeriBest VB99.0 137
Figura A.3: Entorno de simulacion tras crear el espacio de trabajo.
se ha definido en un unico fichero, podrıa haberse definido en dos: un fichero con
el codigo de la interfaz y otro con el codigo de la arquitectura.
A.3.3 Edición de un fichero
Puede crearse un nuevo fichero utilizando el comando “New...” del menu “File”.
Obtendra una ventana en blanco en la que puede teclear el codigo VHDL. Escriba
el codigo que se muestra en la seccion A.2.1. Una vez haya concluido, guardelo con
el nombre bufferTriestado.vhd mediante el comando “Save”, situado en el menu
“File”.
A.3.4 Añadir un fichero al espacio de trabajo
Incluya el fichero bufferTriestado.vhd en el espacio de trabajo bufferTriestado.vpd.
Hay dos formas equivalentes de hacerlo:
1. Haga clic con el puntero del raton sobre el boton “+”, situado en la esquina
superior derecha de la ventana del espacio de trabajo bufferTriestado.vpd.
2. O bien, utilice el comando“Add Files into Workspace...” situado en el menu
“Workspace”.
Tras realizar este paso obtendra una ventana para la seleccion de un fichero.
Seleccione el fichero bufferTriestado.vhd. La ventana principal del simulador tiene
que quedar tal y como se muestra en la Figura A.4.
138 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura A.4: Entorno de simulacion tras incluir el fichero bufferTriestado.vhdel espacio de trabajo.
A.3.5 Compilación de un fichero
Para establecer las opciones de compilacion, seleccionamos la opcion “Settings...”
del menu “Workspace”, o bien recurrimos al icono “Workspace Settings” que esta
situado en la barra de herramientas. Con ello se mostrara una ventana, en la
cual seleccionamos la pestana “Compile”. De este modo, accedemos al cuadro de
dialogo donde se muestran, entre otras, las siguientes opciones de compilacion:
“Debug” Activando esta opcion el archivo seleccionado sera compilado
con la opcion de depuracion. Con esta opcion activa antes de
una compilacion, es posible utilizar todos los comandos del
menu Debug durante la fase de simulacion. Si se desea que
todos los archivos del espacio de trabajo sean compilados con
esta opcion, basta con seleccionar la carpeta del espacio de
trabajo en la ventana y activar la opcion.
“Index Checks” Si esta opcion se encuentra activa, el compilador comprueba la
existencia de errores en los ındices de los arrays.
“Range Checks” Si esta opcion se encuentra activa, el compilador comprueba la
existencia de errores en los rangos de los subtipos que se hayan
definido.
Apendice A VeriBest VB99.0 139
Compile el fichero. Para ello seleccione el comando“Compile”, que esta situado
en el menu “Workspace”.
El resultado de la compilacion se muestra en la ventana de informacion,
situada en la parte inferior de la ventana principal. Observe que la ventana de
informacion contiene las tres pestanas siguientes:
“General” Proporciona informacion sobre cualquier accion que se realice
en la herramienta.
“Build” Muestra la informacion referente al proceso de compilacion
de ficheros. En el caso de que haya habido errores en la
compilacion muestra la lınea de codigo donde aparece cada
error y el tipo de error que es.
“Simulate” Proporciona informacion sobre la fase de simulacion.
Cuando el proceso no da errores, lo guardamos (“Save”). La unidad compilada
se almacena en la librerıa WORK. Para ver su ubicacion, se selecciona el comando
“Library Browser” ubicado en el menu “Library”, o se pincha en el icono corres-
pondiente. Aparecen las diferentes librerıas, IEEE, STD, VB, y en rojo WORK,
WORKLIB. Si pinchamos en esta, aparecen la interfaz (entity) y arquitectura
(architecture) de los diferentes circuitos que hayamos compilado. Podemos ver
informacion de fecha y opciones de compilacion en la parte derecha de la ventana
(ver Figura A.5). Observe que el chip asociado a la interfaz aparece en color
blanco y el asociado a la arquitectura en color rojo.
Se puede reinicializar la librerıa en la que se esta trabajando mediante el
comando “Reinitialize Lib environment” situado en el menu “Workspace”. Al
reinicializar la librerıa, desaparecen las unidades compiladas.
Figura A.5: Library Browser.
140 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
A.3.6 Banco de pruebas
1. Cree un nuevo fichero con el codigo que se muestra en la seccion A.2.2. Una
vez haya concluido, guardelo con el nombre bp bufferTriestado.vhd.
2. Incluya el fichero bp bufferTriestado.vhd en el espacio de trabajo buffer-
Triestado.vpd. La ventana principal del simulador tiene que quedar tal y
como se muestra en la Figura A.6. El orden de compilacion de un fichero se
puede modificar mediante las flechas situadas en la esquina superior derecha
de la ventana del espacio de trabajo bufferTriestado.vpd.
Figura A.6: Entorno de simulacion tras incluir el banco de pruebas en elespacio de trabajo.
3. Compile el fichero bp bufferTriestado.vhd.
A.4 Simulación y visualización de los resultados
En esta seccion se describen los pasos a seguir para realizar la simulacion y la
visualizacion de resultados, usando el buffer triestado como ejemplo.
A.4.1 Establecer las condiciones de la simulación
Para fijar las condiciones de la simulacion, siga los pasos siguientes:
1. Seleccione la opcion “Settings...” del menu “Workspace” o haga clic sobre
el icono correspondiente, denominado “Workspace Settings”, de la barra de
Apendice A VeriBest VB99.0 141
Figura A.7: Opciones de simulacion.
herramientas. A continuacion, se abrira la ventana mostrada en la Figura
A.7.
2. Para acceder al cuadro de dialogo con las opciones de simulacion, seleccione
la pestana “Simulate” de la ventana.
3. Despliegue la carpeta “WORK” para visualizar los elementos sobre los que
se puede realizar una simulacion. Obtendra las interfaces (entity) y ar-
quitecturas (architecture) que ha programado en los pasos anteriores.
Para realizar la prueba de la puerta logica debe seleccionar la arquitectura
BP BUFFER TRIESTADO (que es la que contiene la prueba) y la interfaz
que lleva asociada esa arquitectura (BP BUFFER TRIESTADO). Para
ello, seleccione la arquitectura BP BUFFER TRIESTADO de la interfaz
BP BUFFER TRIESTADO con el cursor del raton (haga clic sobre ella)
y pulse el boton “Set”. Tras esta accion, los campos “Entity” y “Arch” se
rellenaran automaticamente con los nombres de la interfaz y de la arqui-
tectura. Por ultimo, activamos la opcion “Trace On” (que nos permite vi-
sualizar las formas de onda resultantes). Esto tambien se logra desplegando
Simulate→Trace.
4. Fijadas las condiciones de simulacion, pulse el boton “Aceptar”.
A.4.2 Activación del simulador
Para realizar la simulacion hay que arrancar el simulador. Esto se puede realizar
de dos formas: mediante la opcion “Execute Simulator” del menu “Workspace”, o
mediante el icono correspondiente, denominado “Execute Simulator”, situado en
la barra de herramientas.
Mediante cualquiera de las dos opciones, el simulador se activa. Durante
el proceso de activacion del simulador aparecera una ventana de aviso (vease
142 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
la Figura A.8) en la que se indica que, al no encontrar una licencia, se esta
utilizando el simulador en modo limitado. Pulse el boton“Aceptar”para continuar
trabajando.
Figura A.8: Mensaje de aviso sobre la ausencia de licencia.
Tras la activacion del simulador, en la ventana denominada “Simulate”, situa-
da en la parte inferior del espacio de trabajo, aparece un texto. En la ultima lınea
del texto se indica si ha habido errores o avisos (warnings).
A.4.3 Simulación y visualización de resultados
Una vez activada la simulacion, ya puede empezar a realizar simulaciones. Para
realizar simulaciones puede elegir una de las siguientes opciones:
1. Presionar el boton de color verde, denominado “Run”, que esta situado en
la barra de herramientas (vease la Figura A.9).
2. Seleccionar la opcion “Run” o “Run Forever” del menu “Simulate”.
Los siguientes controles de la barra de herramientas del entorno (ver Figura
A.9) nos permiten controlar la simulacion:
Run Tiempo de simulación
StopUnidades del tiempo de simulación
Quit
Figura A.9: Botones para controlar la simulacion.
– Lista desplegable. Permite seleccionar las unidades del tiempo de simula-
cion. Por defecto, la unidad de tiempo es nanosegundos (ns).
Apendice A VeriBest VB99.0 143
– Casilla numerica (junto al boton “Run”). Permite indicar el tiempo de
simulacion.
– Boton “Run”. Permite ejecutar una simulacion.
– Boton “Stop”. Permite detener la simulacion.
– Boton “Quit”. Permite salir del simulador.
Para visualizar los resultados de la simulacion, podemos o bien pinchar con
el raton sobre el icono “WaveForm Window”, que esta situado en la barra de
herramientas, o bien ejecutar el comando “New WaveForm Window”, que se
encuentra en el menu “Tools...”
Obtendra una ventana con una escala de tiempos, en la que no se visualiza
ninguna senal. Para seleccionar las senales, pulse el boton “Add signals” en la
ventana de visualizacion de senales. Dicho boton se encuentra indicado en la
Figura A.10.
Add signals
Figura A.10: Seleccion de las senales a visualizar.
Obtendra una nueva ventana, mostrada tambien en la Figura A.10, en la que
puede seleccionar las senales que desea representar. Pueden seleccionarse senales
tanto de la arquitectura del banco de pruebas (E, d e y), como de la arquitectura
del buffer (E, d e y).
Para seleccionar las senales que corresponden a la arquitectura del banco de
pruebas, pulse sobre el boton “Add All”. Pulse “Close” para cerrar la ventana. Se
obtiene una ventana como la mostrada en la Figura A.11.
Para salir del simulador, podemos hacer clic con el raton sobre el icono“Quit”,
que se encuentra indicado en la Figura A.9.
144 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura A.11: Resultados de la simulacion.
A.5 Depurado usando el debugger
Para poder hacer uso del depurador se tienen que haber compilado los ficheros
con la opcion “Debug” habilitada y se ha de activar el simulador.
Una vez activado el simulador, aparece el menu “Debug”. Hasta que no se
inicie la simulacion no apareceran habilitados todos los comandos del depurador.
Entre los comandos del depurador habilitados antes de iniciar la simulacion, cabe
destacar los siguientes (vease la Figura A.12):
Insert/remove breakpoint
Clear all breakpoint
Examine
New watch window
Show breakpoints
Call stack
Figura A.12: Opciones de depuracion antes del inicio de la simulacion.
– “Insert/Remove a breakpoint”: nos permite introducir un punto de ruptura
(breakpoint) o eliminar un punto de ruptura que habıamos introducido
previamente.
Apendice A VeriBest VB99.0 145
– “Clear all breakpoints”: nos permite eliminar todos los puntos de ruptura
que estaban introducidos.
– “New watch window”: abre una ventana que nos permite observar la evolu-
cion de las senales de forma numerica. Esta ventana, mostrada en la Figura
A.13, dispone de hasta 4 paneles de observacion independientes (“Watch1”
a “Watch4”).
Para anadir a uno de los cuatro paneles los elementos a observar, pulse el
boton “Add Watch...” y obtendra una ventana cuyo tıtulo es “Add watch”
(vease la Figura A.13), en la que puede seleccionar tanto las senales de
forma independiente (se selecciona la senal y se pulsa el boton “Watch”),
como todas las senales de un elemento (se selecciona el componente o bloque
en la parte izquierda de la ventana y se pulsa el boton “Watch block”).
Figura A.13: Ventanas para observar la evolucion de las senales.
– “Show Breakpoints”: abre una ventana que tiene como tıtulo “Breakpoints”,
en la que se muestran todos los puntos de ruptura existentes. En la ventana
“Breakpoints” existe un boton denominado “Condition...” Pulsando este
boton se abre una ventana, denominada “Source Breakpoint Condition”, en
la que puede establecer condiciones de activacion para un punto de ruptura
determinado.
Desde la ventana“Source Breakpoint Condition”podra indicar que el punto
de ruptura permanezca activo unicamente para una instancia o proceso
especıfico. De esta forma, cuando se establecen condiciones, el simulador
se detiene unicamente en el punto de ruptura que hay dentro del proceso
especificado, no en todos los procesos en los que esta el punto de ruptura.
– “Call stack”: nos permite conocer la proxima lınea de codigo VHDL que se
ejecutara cuando se continue con la simulacion. Si se realiza doble clic sobre
146 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
una de las entradas que aparecen en la “Call Stack”, se obtendra una nueva
ventana en la que se muestra el codigo fuente VHDL que se indica en la
entrada que ha seleccionado.
En el caso de que el diseno que esta ejecutando contenga subprogramas
anidados, en el momento en que se entre a ejecutar un subprograma, la ven-
tana “Call Stack” se incrementara con una nueva entrada correspondiente a
la llamada al subprograma. Cuando concluya la ejecucion del subprograma,
la correspondiente entrada en la ventana sera eliminada.
Para empezar el proceso de depuracion hay que comenzar la simulacion. Una
vez comenzada la simulacion, se habilitaran, entre otros, los siguientes comandos
de depuracion (vease la Figura A.14):
– “Continue”: continua la ejecucion de la simulacion hasta el siguiente punto
de ruptura o hasta que concluya el tiempo de simulacion.
– “Step”: avanza la simulacion una lınea del codigo fuente VHDL.
ContinueStep
Figura A.14: Opciones de depuracion una vez iniciada la simulacion.
BModelSim PE Student Edition
Objetivos. Instalar en su propio ordenador y realizar las operaciones basicas demanejo del entorno de simulacion ModelSim PE Student Edition. Estas operacionesbasicas incluyen al menos:
– Edicion y compilacion de modelos.
– Simulacion y visualizacion de los resultados.
– Depurado de modelos.
B.1 Instalación
El grupo Mentor Graphics, desarrollador de ModelSim, ofrece de manera gratuita
una version de evaluacion temporal (180 dıas) del simulador. El simulador Model-
Sim es una herramienta muy completa y potente, de hecho varias herramientas
de sıntesis desarrolladas por fabricantes de circuitos FPGA ofrecen la posibilidad
de simular los modelos usando ModelSim.
Los pasos a seguir para la descarga e instalacion se describen a continuacion.
Durante todo el proceso debe disponerse de conexion a Internet.
1. Descargar el fichero ejecutable de instalacion (aproximadamente 60MB) de
la direccion:
http://www.model.com/resources/student edition/download.asp
para lo cual en primer lugar tendra que rellenar un formulario electronico
con sus datos y senalar una casilla que indica que solo va a usar la herra-
mienta para fines educativos.
2. Ejecutar dicho fichero, el cual realiza la instalacion del simulador. En la fase
final de la instalacion, el programa de instalacion se conecta a una pagina
web en la cual hay un formulario para la solicitud de la licencia.
148 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
3. En la hoja de solicitud de licencia, debemos indicar a que direccion de
correo electronico deseamos que nos envıen el fichero de licencia. En esa
direccion de correo recibiremos un correo con el fichero de licencia y las
indicaciones de donde debe guardarse. La licencia tiene una validez de 180
dıas, transcurridos los cuales debe repetirse la instalacion y la solicitud de
la licencia. La licencia solo es valida para el ordenador en el que se hizo la
descarga del ejecutable. Si se quiere instalar ModelSim en otro ordenador,
debe repetirse el proceso de descarga del ejecutable y solicitud de la licencia.
B.2 Circuito digital ejemplo: buffer triestado
Va a emplearse el modelo de un buffer triestado para ilustrar las explicaciones
acerca del manejo del simulador. Este tipo de componente se emplea comunmente
para conectar varios dispositivos a un mismo bus. Tal como se muestra en la
Figura B.1, el buffer triestado tiene dos entradas (d y E) y una salida (y). La
salida puede tomar tres valores: 0, 1 y Z (alta impedancia). El estado de alta
impedancia es equivalente a un interruptor abierto. Dependiendo del valor de la
entrada E, la salida puede tomar el valor de la entrada o el valor Z.
E
ydd1
Z0
YE
b)a)
Figura B.1: Buffer triestado: a) sımbolo logico; b) tabla de verdad.
B.2.1 Modelo VHDL del buffer triestado
-------------------------------------------
-- Buffer triestado
library IEEE;
use IEEE.std_logic_1164.all;
entity Buffer_TriEstado is port
( E : in std_logic;
d : in std_logic;
y : out std_logic);
end entity Buffer_TriEstado ;
architecture Behavioral of Buffer_TriEstado is
begin
process (E, d)
Apendice B ModelSim PE Student Edition 149
begin
if (E = ’1’ ) then
y <= d ;
else
y <= ’Z’;
end if;
end process;
end architecture Behavioral;
-------------------------------------------
B.2.2 Banco de pruebas
El siguiente banco de pruebas genera las 22 posibles combinaciones de entradas
al buffer.
--------------------------------------
-- Banco de pruebas
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity bp_Buffer_TriEstado is
end entity bp_Buffer_TriEstado;
architecture bp_Buffer_TriEstado of bp_Buffer_TriEstado is
signal y : std_logic; -- Conectar salida UUT
signal d, E : std_logic; -- Conectar entradas UUT
component Buffer_TriEstado is port
( E, d : in std_logic;
y : out std_logic);
end component Buffer_TriEstado;
begin
-- Instanciar y conectar UUT
uut : component Buffer_TriEstado port map
( E => E, d => d, y => y);
gen_vec_test : process
begin
E <= ’0’;
d <= ’0’;
wait for 5 ns;
d <= ’1’;
wait for 5 ns;
150 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
E <= ’1’;
wait for 10 ns;
d <= ’0’;
wait;
end process gen_vec_test;
end architecture bp_Buffer_TriEstado;
--------------------------------------
B.3 Edición y compilación de un modelo
En esta seccion se describe como editar y compilar modelos con el simulador
ModelSim. Para ilustrar las explicaciones, se va a usar el modelo del buffer
triestado descrito anteriormente.
B.3.1 Arranque del simulador
Seleccione el icono ModelSim PE del grupo de programas Inicio → Programas
→ ModelSim PE Student Edition 6.3c → ModelSim. Inicialmente aparecera la
ventana de bienvenida. Si desea que no vuelva a aparecer marque la casilla “Don’t
show this dialog again”. Para cerrar esta ventana y acceder a la aplicacion pulse
el boton “Close”.
Workspace
Transcript
MenúsIconos
Figura B.2: Ventana principal de ModelSim.
Se abrira entonces la ventana principal del entorno (vease la Figura B.2), que
cuenta con los elementos siguientes:
Apendice B ModelSim PE Student Edition 151
“Workspace” Panel situado a la izquierda de la ventana principal. Al
arrancar la aplicacion este panel tiene una unica pestana
denominada “Library”. En esta pestana aparecen los nombres
logicos de las librerıas de recursos.
“Transcript” Panel de texto situado en la parte inferior de la ventana
principal. Este panel tiene una doble finalidad:
1. Mostrar los mensajes producidos por la ejecucion de
comandos.
2. Permitir teclear comandos en lınea. Se mantiene un
historico de todos los comandos ejecutados. Usando las
teclas ↑ y ↓ se puede acceder a comandos anteriores y
posteriores para ejecutarlos de nuevo.
Barra de menus
Barra de iconos
B.3.2 Creación de un proyecto
Para crear un proyecto, debe seguir los pasos siguientes:
1. Seleccione la opcion File→ New→ Project. Aparecera la ventana de dialogo
para la creacion de proyectos (vease la Figura B.3). En dicha ventana se
establece el nombre del proyecto, el directorio en el que desea ubicarse y el
nombre de la librerıa por defecto.
Figura B.3: Ventana de dialogo para la creacion de un proyecto.
2. En la casilla “Project Name” teclee bufferTriestado como nombre del pro-
yecto.
3. En la casilla “Project Location”, seleccione el directorio donde va a ubicar
los ficheros del proyecto. Puede ayudarse del boton “Browse...” para mo-
verse por el disco. Si el directorio introducido no existe, la herramienta le
pedira confirmacion para su creacion. En este directorio se creara el fichero
bufferTriestado.mpf.
152 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura B.4: Entorno de simulacion tras crear un nuevo proyecto.
4. En la casilla “Default Library Name”, se escribe el nombre de la librerıa
de trabajo. Por defecto aparece work y, en general, puede emplearse este
nombre. El nombre dado a la librerıa sera el que, una vez creado el proyecto,
la herramienta asigne automaticamente a un directorio ubicado debajo del
indicado en el cuadro “Project Location”. En este directorio se almacenaran
las unidades de diseno VHDL compiladas. En la Figura B.3 se muestra el
cuadro de dialogo una vez realizados estos pasos.
5. Pulse el boton “OK”.
B.3.3 Añadir ficheros al proyecto
Al crear un proyecto, se producen los siguientes cambios en el entorno de simu-
lacion (vease la Figura B.4):
– Aparece una nueva pestana en el panel “Workspace” denominada“Project”.
En dicha pestana se muestran los ficheros que forman parte del proyecto.
Observe que si la pestana “Project” esta seleccionada se muestra un menu
llamado“Project”. Por el contrario, si la pestana“Library”esta seleccionada
no se muestra el menu “Project” sino un menu denominado “Library”.
– Se muestra el nombre del proyecto en la barra de estado de la parte inferior
izquierda de la ventana principal.
– Se abre una ventana de dialogo denominada“Add items to the Project”. Es-
ta ventana, que permite anadir elementos al proyecto, incluye las siguientes
opciones (vease la Figura B.4):
Apendice B ModelSim PE Student Edition 153
“Create New File” Permite crear un nuevo fichero de diseno.
“Add Existing File” Permite incluir un fichero ya existente en el proyecto
actual copiandolo al directorio del proyecto o referen-
ciandolo desde su ubicacion actual.
“Create Simulation” Permite crear configuraciones para simulacion.
“Create New Folder” Permite crear directorios virtuales. Estos directorios tie-
nen, sobre la pestana “Project” del panel “Workspace”,
un aspecto similar al de los directorios del sistema
operativo. Estos directorios son internos al proyecto y
no se crean realmente en el disco.
Para crear un nuevo fichero se pueden usar las opciones de la ventana de
dialogo “Add items to the Project”. Se pueden acceder a estas mismas opciones
a traves del menu Project → Add to Project.
Inserción de un fichero nuevo en el proyecto
Para crear un fichero nuevo se pueden seguir los siguientes pasos:
1. Realizar una de las dos siguientes opciones:
– Seleccionar el icono “Create New File” en el cuadro de dialogo “Add
items to the Project” mostrado en la Figura B.4.
– O bien, seleccionar del menu el comando Project → Add to Project
→ New File... Para poder usar el menu, si esta abierta la ventana de
dialogo “Add items to the Project”, hay que cerrarla presionando el
boton “Close”.
Aparece una ventana de dialogo denominada “Create Project File”. Esta
ventana tiene los siguientes elementos (ver Figura B.5):
“File Name” Permite especificar la ubicacion y nombre del fichero
fuente. El boton “Browse...” nos permite especificar la
ubicacion del fichero navegando a traves de las carpetas
del sistema. Si especificamos un nombre del fichero,
sin indicar ningun directorio, este se guardara en el
directorio del proyecto.
“Add File As Type” Nos permite seleccionar el tipo de fichero.
“Folder” Lista desplegable donde aparecen todos los directorios
existentes en el proyecto. En el caso de que no se
haya creado ningun directorio esta lista solo tendra un
elemento: “Top Level”.
2. Complete los cuadros de la ventana de dialogo “Create Project File” del
siguiente modo:
– En el cuadro“File Name”escriba bufferTriestado.vhd o bufferTriestado.
154 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
– En la lista desplegable “Add file as type” seleccione VHDL.
– Pulse “OK”. Si ha anadido el fichero a traves del cuadro de dialogo
“Add items to the Project” y no quiere anadir por el momento mas
elementos al proyecto cierre dicha ventana. Ello lo puede hace pulsando
el boton “Close”.
Figura B.5: Ventana de dialogo“Create Project File”.
Una vez finalizado este proceso se crea un fichero denominado bufferTriesta-
do.vhd en el directorio del proyecto. En la Figura B.6 se muestra la ventana
principal tras seguir estos pasos. Observe que en la pestana “Project” del
panel “Workspace” aparece la informacion sobre el fichero creado. La infor-
macion mostrada es la siguiente:
“Name” Nombre del fichero.
“Status” Sımbolo que refleja el estado del fichero. Existen los siguientes
tres sımbolos:
– ?: El fichero aun no ha sido compilado.
– X: El fichero se ha compilado y contiene errores.
–√
: El fichero ha sido compilado con exito.
“Type” Indica el tipo de fichero (VHDL, Verilog, Folder, Simulation).
“Order” Indica la posicion del fichero en la secuencia de compilacion
cuando hay varios ficheros fuente. El primer fichero de la
secuencia de compilacion es aquel con un numero menor.
“Modified” Muestra la fecha y hora en que el fichero fue modificado por
ultima vez.
3. Al crear el fichero, se abre automaticamente una ventana del editor de texto
del entorno con el fichero vacıo como muestra la Figura B.6.
4. Edite, empleando la ventana del editor de texto mostrada en la Figura B.6,
el codigo VHDL mostrado en la Seccion B.2.1.
5. Salve el fichero seleccionando la opcion File→ Save del menu de la ventana
del editor o bien pulsando el icono correspondiente. De al fichero el nombre
bufferTriestado.vhd.
Apendice B ModelSim PE Student Edition 155
Figura B.6: Entorno de simulacion tras crear un nuevo fichero.
Figura B.7: Ventana de dialogo“Add File to Project”.
Inserción de un fichero existente en el proyecto
A continuacion, se describen los pasos que habrıa que seguir para incorporar al
proyecto un fichero ya existente:
– Seleccionar del menu el comando Project → Add to Project → Existing
File... Tambien se puede realizar la misma accion desde la ventana de dialogo
“Add items to the Project” seleccionando la opcion “Add Existing File”.
Aparece una ventana de dialogo denominada “Add File to Project” (vease
la Figura B.7). Esta ventana tiene los siguientes elementos:
156 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
“File Name” Permite seleccionar el fichero fuente. El boton “Brow-
se...” nos facilita la seleccion de dicho fichero navegando
a traves de las carpetas del sistema.
“Add File As Type” Nos permite seleccionar el tipo de fichero.
“Folder” Lista desplegable donde aparecen todos los directorios
existentes en el proyecto. En el caso de que no se
haya creado ningun directorio esta lista solo tendra un
elemento: “Top Level”.
“Copy to project direc-
tory”
Realiza una copia fısica del fichero desde su localizacion
al directorio del proyecto.
“Reference from current
location”
El fichero se incluye en el proyecto, pero no se copia al
directorio del mismo.
– Localice y seleccione el fichero en el cuadro “File Name” (puede ayudarse
del boton “Browse...”). Seleccione VHDL de la lista deplegable “Add file as
type” y “Top Level” de “Folder”. Por ultimo, seleccione la opcion “Copy to
project directory” y pulse “OK”.
B.3.4 Compilación de un fichero
Para verificar que el codigo VHDL es correcto, es necesario compilar el fichero.
Al compilar el fichero se genera el fichero binario que posteriormente se empleara
en la simulacion. Para compilar el fichero podemos seguir una de las opciones
siguientes:
– Seleccionar la opcion Compile → Compile All. Mediante esta opcion se
compilan todos los ficheros del proyecto. El orden de compilacion que se
sigue es el indicado en la columna “Order” del panel “Workspace”.
– Seleccionar la opcion Compile → Compile Selected. Mediante esta opcion
se compila unicamente el fichero seleccionado.
– Situar el raton en el panel “Workspace” de la ventana principal y pulsar el
boton derecho. Aparece un menu contextual con varias opciones para lanzar
directamente la compilacion. Mediante la opcion Compile → Compile Out-
of-Date de este menu se compila unicamente los ficheros que no hayan sido
compilados con exito anteriormente. Es decir, todos los que no presenten el
icono√
en la columna “Status”.
– Teclear vcom bufferTriestado.vhd en el panel “Transcript”.
La unidad compilada se almacena en la librerıa work. Para ver su ubicacion,
se selecciona la pestana “Library” del panel ”Workspace”. Pulsando sobre el signo
“+” que aparece a la izquierda de la librerıa work podemos ver su contenido
(vease la Figura B.8). En la librerıa existe una interfaz (entity) denominada
bufferTriestado y una arquitectura (architecture) llamada behavioral.
Apendice B ModelSim PE Student Edition 157
Figura B.8: Contenido de la librerıa work tras compilar el fichero buffer-Triestado.vhd.
Errores de compilación
A continuacion, se describe que ocurre cuando existen errores de compilacion en
un fichero. Para ello vamos a modificar el fichero bufferTriestado.vhd. Introduci-
mos un error quitando el ; de la lınea 15 del fichero. Al guardar el fichero su nuevo
“status” es ?. Al compilar el fichero su “status” cambia a X (vease la Figura B.9).
Tambien aparece un mensaje de error en color rojo en el panel “Transcript”.
El mensaje de error del panel “Transcript” nos informa de que existen errores
de compilacion en el fichero bufferTriestado.vhd. Si hacemos doble clic con el raton
sobre el mensaje de error se muestra una ventana de dialogo (vease la Figura B.9).
Dicha ventana contiene en color rojo un mensaje con informacion sobre el tipo de
error que se ha producido y el numero de lınea en que aparece. Si hacemos doble
clic con el raton sobre dicho mensaje se abre la ventana de edicion con la lınea del
codigo que ha producido el error marcada en color naranja (vease la Figura B.9).
En este caso, la lınea 16 aparece en color naranja debido a que hemos eliminado
el ; que debiera haber al final de la lınea 15.
B.3.5 Banco de pruebas
Se va a crear un nuevo fichero con el codigo del banco de pruebas, que se va a
guardar con el nombre bp bufferTriestado.vhd. El codigo del banco de pruebas se
muestra en la Seccion B.2.2. Para crear el fichero, siga los siguientes pasos:
– Seleccione del menu el comando Project→ Add to Project → New File · · ·
– Complete la ventana de dialogo denominada “Create Project File” del si-
guiente modo:
158 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Figura B.9: Entorno de simulacion cuando hay errores de compilacion en elfichero bufferTriestado.vhd.
– En el cuadro “File Name” escriba bp bufferTriestado.
– En la lista desplegable “Add file as type” seleccione VHDL.
– Pulse “OK”.
Tras seguir estos pasos, el panel “Workspace” queda tal como se muestra
en la Figura B.10. La columna “Status” del fichero bp bufferTriestado.vhd
tiene el icono ?, ya que aun no ha sido compilado. El fichero tiene el
numero 1 en la columna “Order”. Esto indica que si usamos la opcion de
compilacion Compile → Compile All, el fichero bp bufferTriestado.vhd se
compilara despues que el fichero bufferTriestado.vhd. Compile el fichero
bp bufferTriestado.vhd siguiendo algunas de las opciones descritas en la
seccion B.3.4.
Existen ocasiones en que el orden de compilacion de los ficheros puede
no ser el correcto en funcion de la estructura del codigo VHDL y de las
reglas que el lenguaje impone. Por ejemplo, considere el caso de que haya
un fichero llamado paquete.vhd donde se defina un paquete, y otro fichero,
denominado uso paquete.vhd, que use dicho paquete. El fichero paquete.vhd
ha de ser compilado antes que el fichero uso paquete.vhd. En caso contrario,
se produce un error de compilacion.
Se puede modificar el orden de compilacion del siguiente modo:
– Situar el raton en el area del panel “Workspace”.
– Apretar el boton derecho del raton. Aparece ası un menu textual.
– Seleccionar la opcion Compile → Compile Order... del menu. Aparece
una ventana denominada “Compile Order” (ver Figura B.11).
– Puede cambiar el orden de posicion del fichero en la secuencia de
compilacion seleccionando dicho fichero en la ventana“Compile Order”
y pulsando sobre los botones (ver Figura B.11).
Figura B.10: Panel “Workspace” tras insertar el ficherobp bufferTriestado.vhd.
Botones para cambiar el orden en la secuencia de compilación
Figura B.11: Ventana“Compile Order”.
160 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
B.4 Simulación y visualización de los resultados
En esta seccion se describen los pasos a seguir para realizar la simulacion y la
visualizacion de los resultados, usando el buffer triestado como ejemplo.
B.4.1 Activación del modo simulación
Para iniciar el simulador se selecciona en la pestana “Library” la interfaz (entity)
que queremos simular. En este caso, seleccionamos bp bufferTriestado. Con el
boton derecho de raton sobre esta interfaz seleccionamos la opcion “Simulate”
(vease la Figura B.12).
Observe que la ventana principal del simulador se modifica. Cabe destacar los
cambios siguientes:
– Aparecen las tres pestanas siguientes en el panel “Workspace”:
“sim” Muestra la jerarquıa de diseno.
“Files” Muestra los ficheros fuente.
“Memories” Herramienta de analisis para los arrays de registros del
sistema (si hay alguno).
– Aparece el panel “Objects”. Este panel muestra las variables, registros, etc.,
su valor y sus caracterısticas.
Para interaccionar con el simulador y visualizar los resultados de la simulacion,
la herramienta dispone de un conjunto de paneles. Estos paneles pueden formar
parte de la ventana principal del simulador o pueden ser separados de dicha venta-
na haciendo clic con el raton sobre el boton “undocked” (vease la Figura B.13a).
Puede volver a insertar el panel en la ventana principal presionando el boton
“docked” (vease la Figura B.13b). Podemos seleccionar los paneles a mostrar
usando el menu “View”. A continuacion, se comenta brevemente la funcionalidad
de algunos paneles:
“Dataflow” Permite visualizar, de modo grafico, la conectividad entre
los elementos (procesos, sentencias de asignacion concurrente,
etc.) del modelo y rastrear eventos.
“List” Muestra, en modo texto, los valores de las senales y variables
en un formato tabular.
“Process” Muestra la lista de procesos junto con informacion sobre su
estado.
“Objects” Muestra la lista de senales de la interfaz (entity) seleccionada
en la pestana “Sim”.
“Wave” Permite visualizar la forma de onda de las senales y variables.
Apendice B ModelSim PE Student Edition 161
Figura B.12: Activacion del modo simulacion.
a) b)
Figura B.13: Botones: a)“undocked”; y b)“docked”.
B.4.2 Visualización de los resultados
Las senales se pueden visualizar en el panel “Wave”. Este panel se puede separar
de la ventana principal pulsando el boton “undocked” (vease la Figura B.13a).
Podemos anadir senales de interes al panel “Wave” siguiendo uno de los dos
siguientes procedimientos:
– Seleccionar todas las senales que queremos visualizar del panel “Objects”.
Arrastrar la seleccion con el raton y llevarla hasta el panel “Wave”.
– Pulsar sobre el panel “Objects” con el boton derecho del raton. En el menu
que aparece podemos realizar las dos siguiente acciones:
1. Incluir en el panel “Wave” todas las senales que aparecen en el panel
“Objects”. Para ello hacemos clic en la opcion Add to Wave→ Signals
in Region.
2. Mostrar una seleccion de las senales del panel. Para ello hacemos clic
en la opcion Add to Wave → Selected Signals. Para seleccionar un
162 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
conjunto de senales pulsamos el boton “Shift” del teclado al mismo
tiempo que hacemos clic con el raton sobre las senales que queremos
seleccionar. Para quitar senales del conjunto seleccionado mantenemos
pulsado el boton “Control” mientras hacemos clic con el raton sobre
las senales que queremos quitar.
Caben destacar las siguientes caracterısticas del panel “Wave” (vease la Figu-
ra B.14):
– Se puede adaptar la informacion visualizada en el panel “Wave” usando los
diferentes iconos de zoom. A continuacion se describe la funcionalidad de
los iconos de zoom:
“Zoom In” Amplia la escala de tiempos.
“Zoom Out” Reduce la escala de tiempos.
“Zoom Full” Cambia el rango de la escala de tiempo de modo que vaya desde
el instante inicial hasta el instante actual de simulacion.
– Podemos anadir cursores presionando el boton “Insert Cursor”. Al pie del
cursor se indica el instante de tiempo en que se encuentra situado. Ademas,
aparece el valor de cada senal en dicho instante de tiempo en el area que hay
junto a los nombres de las senales. Se puede eliminar un cursor presionando
el boton “Delete Cursor” una vez hayamos seleccionando dicho cursor.
B.4.3 Ejecución de la simulación
Los siguientes botones nos permiten controlar la simulacion y realizar el depurado
del modelo (ver Figura B.15):
“Run” Ejecuta la simulacion durante el tiempo indicado por defecto
en el cuadro de la ventana principal (la simulacion puede
detenerse antes, si se han introducido puntos de ruptura, o
manualmente o por la ejecucion de alguna sentencia del banco
de pruebas).
“Continue Run” Continua la simulacion en curso hasta agotar el tiempo de
simulacion por defecto (la simulacion puede detenerse antes
por los motivos indicados en el parrafo anterior).
“Run - All”: Ejecuta la simulacion durante tiempo indefinido. Esta podra
detenerse si se han incluido puntos de ruptura en el codigo o
si se interrumpe con el boton siguiente. En la zona de estado
de la ventana principal (parte inferior) se muestra el tiempo
de simulacion.
Apendice B ModelSim PE Student Edition 163
Zoom In Zoom Out Zoom Full Zoom In On Active Cursor
Insert cursor
Delete cursor
Find Previous Transition
Find Next Transition
Figura B.14: Panel“Wave”.
“Break” Detiene la simulacion en curso.
“Restart” Reinicia la simulacion. Carga de nuevo el modelo binario,
situa el tiempo de simulacion en cero y, opcionalmente, puede
mantener el formato dado a algunas ventanas, los puntos de
ruptura, etc.
“Step” Ejecuta la simulacion hasta la siguiente sentencia de codigo.
El valor de las variables en ese punto se puede visualizar en el
panel “Objects”.
“Step Over” Ejecuta funciones y procedimientos en un solo paso.
B.4.4 Inserción de puntos de ruptura
A continuacion, se describen los pasos a seguir para insertar punto de ruptura
(breakpoint) en el codigo:
– Seleccionamos la unidad de diseno en cuyo codigo queremos introducir el
punto de ruptura. Las unidades de diseno se muestran en la pestana “Sim”
del panel “Workspace”.
164 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Restart Run Length Run Continue Run
Run All Step Step Over
Figura B.15: Botones para la simulacion y depurado del modelo.
– Hacemos doble clic sobre la unidad de diseno seleccionada. Aparece ası un
panel con el codigo de dicha unidad de diseno.
– En el codigo mostrado en el panel podemos insertar puntos de ruptura
usando el raton. Las lıneas en las que podemos introducir puntos de ruptura
son aquellas cuyo numero de lınea esta en color rojo. Para introducir el
punto de ruptura hacemos clic con el raton en la columna BP de la lınea
donde queremos introducir el punto de ruptura.
Para modificar los puntos de ruptura podemos acceder a una ventana de dia-
logo denominada “Modify Breakpoints”. Para ello, seguimos los pasos siguientes:
– Hacemos clic con el boton derecho del raton en el area del panel donde se
muestra el codigo de la unidad de diseno seleccionada.
– En el menu textual que aparece seleccionamos la opcion “Breakpoints...”.
A continuacion, se describen los pasos a dar para introducir un punto de rup-
tura en la lınea numero 15 del fichero bufferTriestado.vhd (vease la Figura B.16):
– Hacemos doble clic sobre la unidad de diseno uut. Aparece ası un panel que
muestra el codigo del fichero bufferTriestado.vhd.
– Hacemos clic con el raton a la izquierda del numero de lınea 15. Aparecera
un cırculo rojo indicando la existencia del punto de ruptura. Para poder
modificar el punto de ruptura podemos situarnos con el raton sobre el cırculo
y hacer clic con el boton derecho. Se despliega un menu de texto que nos
permite deshabilitar el punto de ruptura (“Disable Breakpoint”) y quitar el
punto de ruptura (“Remove Breakpoint”).
Figura B.16: Insercion de puntos de ruptura.
Índice alfabético
after, 103
Alta impedancia, 134, 148
Arbol de buffers, 7
Architecture, 20, 21
comportamiento, 21, 55, 61
estructura, 21, 62, 117
Register-Transfer Level, 130
Asignacion concurrente, 22, 48, 59, 83
Atributos, 34
Banco de pruebas, 16, 51, 55, 65, 75, 85,
91, 94, 106, 113, 124, 126
Buffer triestado, 48, 134, 148
Bus bidireccional, 80
CAD, 3
Calendario de eventos, 8
case, 57, 103
Ciclo de diseno, 4
Circuito integrado
ASIC, 5
FPGA, 5
PLD, 5
Codificador
4:2 con prioridad, 93
Configuracion, 28
Constantes generic, 28, 78
Conversor
BCD a binario, 89
Decodificador, 48
Descripcion del hardware
mediante esquematico, 3
mediante lenguaje, 3
modular y jerarquica, 24
Detector de secuencias, 100, 130
Diagrama de estados, 100
downto, 53
Ejecucion concurrente, 6
Entidad de diseno, 20
Entity, 20
Estandar IEEE
1067-1987 (VHDL’87), 4
1076-1993 (VHDL’93), 4
1076-2001 (VHDL-AMS), 4
1076.6 (VHDL sintetizable), 20
1364-1995 (Verilog), 3
1666-2005 (SystemC), 4
Fallo
Abierto, 12
Acoplo, 13
Corto, 13
Modelo, 13
Patron, 13
Flip-flop, 102
JK, 105
for, 53
Funcion, 44, 70
logica, 50
168 A. Urquıa, C. Martın Villalba Casos Practicos de Diseno de Circuitos Digitales con VHDL
Glitch, 39
HDL, 2
ventajas, 3
if, 55, 102
Inicializacion, 103
Latch, 102
Ley de Moore, 1
Librerıas VHDL, 37
IEEE.math real, 37
IEEE.numeric std, 37
IEEE.std logic 1164, 37
Literales, 31
Memoria
de lectura y escritura, 79
de solo lectura, 78
Modelo de fallos, 13
Multiplexor, 48
4:1, 54
Maquina de estado finito, 99
de Mealy, 99, 119
de Moore, 99, 109
metodo de diseno, 99
Netlist, 4
now, 32, 67
Operadores, 35
package, 37, 74, 85, 90, 110
Palabras reservadas, 21
Parametrizacion, 28
Procedimiento, 44, 68
procedure, 106
process, 23, 50, 55, 84, 104
Puerto, 20
in, 20
inout, 20
out, 20
Reloj de la simulacion, 8
Rendimiento, 12
report, 32, 67
Restador
completo de 1 bit, 61
de 1 bit, 61
Retardo, 38, 103
de Transporte, 39
Inercial, 39
scan flip-flops, 14
Sumador
completo de 1 bit, 72
de 4 bits, 77
SystemC, 4
Sıntesis, 4
de logica secuencial, 102
Tabla de transicion de estados, 100
Test, 12
Calidad, 14
Cobertura de fallos, 13
Funcional, 14
Manufactura, 14
Modelo de fallos, 13
Programa, 12
Programa de test, 3
Vector, 12
Vector de test, 3
Tipo de datos
bit, 30
enumerado, 32
integer, 59
std logic, 30
string, 32
time, 32
Unidad Aritmetico Logica, 82
UUT (Unit Under Test), 16
Verificacion
de tiempos, 4
funcional, 4
Verilog HDL, 3
VHDL, 2
VHDL sintetizable, 20
wait, 38, 54, 103, 104
when, 48
with, 49, 103
Bibliografía
Armstrong, J. & Gray, F. (2000), VHDL Design, Representation and Synthesis,
Prentice Hall.
Brown, S. & Vranesic, Z. (2006), Fundamentos de Logica Digital con Diseno
VHDL, Mc Graw-Hill.
Lee, S. (2006), Advanced Digital Logic Design: Using VDHL, State Machines and
Syntesis for FPGAs, Thomsom Canada Limited.
Mentor Graphics Corporation (2008), ModelSim LE/PE User’s Manual. Software
Version 6.3e. Disponible en: http://www.model.com/resources/resources\
_manuals.asp.
Pardo, F. & Boluda, J. A. (2004), VHDL, Lenguaje de Sıntesis y Modelado de
Circuitos, RA-MA.
Perry, D. L. (2002), VHDL: Programming by Example, McGraw-Hill.
Salcic, Z. & Smailagic, A. (2000), Digital Systems Design and Prototyping, Kluwer
Academic Publishers.
Vahid, F. & Lysecky, R. (2007), VHDL for Digital Design, Wiley.
VeriBest Inc. (1998), Documentacion en lınea de VeriBest VB99.0. Suministrada
con VeriBest VB99.0.