Casos prácticos de diseño
de circuitos digitales con VHDL
Texto de problemas de la asignatura
“Estructura y Tecnología de los Computadores III” Curso 2007/08
Alfonso Urquía
Carla Martín Villalba
Departamento de Inform´atica y Autom´atica, UNED Juan del Rosal 16, 28040 Madrid, Espa˜na
{aurquia,carla}@dia.uned.es http://www.euclides.dia.uned.es
1 Fundamentos 1
1.1. Lenguajes para la descripci´on de hardware . . . 1
1.2. Ciclo de dise˜no de los circuitos digitales . . . 4
1.3. Propiedades de los circuitos digitales . . . 5
1.4. Simulaci´on 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. Definici´on de la entidad de dise˜no . . . 20
2.2. Entity . . . 20 2.3. Architecture . . . 21 2.3.1. Asignaciones concurrentes . . . 22 2.3.2. Bloque process . . . 23 2.3.3. Descripci´on de la estructura . . . 24 2.3.4. Constantes generic . . . 28 2.4. Configuration . . . 28
2.5. Se˜nales, 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 asignaci´on a se˜nales . . . 39
2.7.3. Retardo inercial y de transporte . . . 39
2.7.4. Retardo delta . . . 40
2.7.5. Caso pr´actico . . . 41
2.8. Assert . . . 43
3 Casos prácticos de diseño de circuitos combinacionales 47
3.1. S´ıntesis de l´ogica combinacional . . . 47
3.1.1. Empleo de sentencias concurrentes . . . 48
3.1.2. Empleo de bloques process . . . 50
3.2. Funciones l´ogicas . . . 50
3.2.1. Modelado de las funciones l´ogicas . . . 50
3.2.2. Programaci´on 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. Descripci´on del comportamiento . . . 61
3.4.2. Descripci´on de la estructura . . . 62
3.4.3. Programaci´on del banco de pruebas . . . 65
3.4.4. Banco de pruebas usando un procedimiento . . . 68
3.4.5. Banco de pruebas usando una funci´on . . . 70
3.5. Sumador binario paralelo con propagaci´on de arrastre . . . 71
3.5.1. Dise˜no de un sumador completo . . . 72
3.5.2. Banco de pruebas de sumador completo . . . 75
3.5.3. Dise˜no del sumador de 4 bits . . . 77
3.6. Bus bidireccional y memorias . . . 77
3.6.1. Memoria de s´olo lectura . . . 78
3.6.2. Memoria de lectura y escritura . . . 79
3.6.3. Bus bidireccional . . . 80
3.7. Unidad aritm´etico l´ogica (ALU) . . . 82
3.7.1. Modelado mediante asignaci´on concurrente . . . 83
3.7.2. Modelado mediante bloque process . . . 84
3.7.3. Programaci´on 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. Dise˜no del circuito . . . 93
3.9.2. Banco de pruebas . . . 94
4 Casos prácticos de diseño de circuitos secuenciales 99 4.1. Dise˜no de circuitos secuenciales s´ıncronos . . . 99
4.1.1. Circuito detector de secuencias . . . 100
4.2. S´ıntesis de l´ogica secuencial . . . 102
4.2.1. Sentencias condicionales incompletas . . . 102
4.2.2. Sentencias condicionales completas . . . 103
4.2.3. Retardos . . . 103
4.2.4. Inicializaci´on . . . 103
4.3. Flip-flop JK . . . 105
4.3.1. Dise˜no del flip-flop . . . 105
4.3.2. Banco de pruebas . . . 106
4.4. M´aquinas de estado finito de Moore . . . 109
4.4.1. Dise˜no de la m´aquina . . . 110
4.4.2. Banco de pruebas . . . 113
4.4.3. Modelado estructural . . . 117
4.5. M´aquinas de estado finito de Mealy . . . 119
4.5.1. Dise˜no de la m´aquina . . . 119
4.5.2. Banco de pruebas . . . 126
4.6. Descripci´on VHDL de alto nivel . . . 130
4.6.1. Circuito detector de secuencia . . . 130
AP ´ENDICES 133 A VeriBest VB99.0 133 A.1. Instalaci´on . . . 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. Edici´on y compilaci´on de un modelo . . . 136
A.3.1. Arranque del simulador VeriBest VHDL . . . 136
A.3.2. Creaci´on de un espacio de trabajo . . . 136
A.3.3. Edici´on de un fichero . . . 137
A.3.4. A˜nadir un fichero al espacio de trabajo . . . 137
A.3.5. Compilaci´on de un fichero . . . 138
A.3.6. Banco de pruebas . . . 140
A.4. Simulaci´on y visualizaci´on de los resultados . . . 140
A.4.1. Establecer las condiciones de la simulaci´on . . . 140
A.4.2. Activaci´on del simulador . . . 141
A.4.3. Simulaci´on y visualizaci´on de resultados . . . 142
A.5. Depurado usando el debugger . . . 144
B ModelSim PE Student Edition 147 B.1. Instalaci´on . . . 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. Edici´on y compilaci´on de un modelo . . . 150
B.3.1. Arranque del simulador . . . 150
B.3.2. Creaci´on de un proyecto . . . 151
B.3.3. A˜nadir ficheros al proyecto . . . 152
B.3.4. Compilaci´on de un fichero . . . 156
B.3.5. Banco de pruebas . . . 157
B.4.1. Activaci´on del modo simulaci´on . . . 160
B.4.2. Visualizaci´on de los resultados . . . 161
B.4.3. Ejecuci´on de la simulaci´on . . . 162
B.4.4. Inserci´on de puntos de ruptura . . . 163
Índice alfabético 167
1
Fundamentos
Objetivos. Una vez estudiado el contenido del tema, deber´ıa saber:
– Discutir la finalidad de los lenguajes para la descripci´on del hardware (HDL) y algunas de las principales ventajas que presenta su uso.
– Discutir el ciclo de dise˜no del hardware digital y el papel que desempe˜nan en el ciclo de dise˜no los HDL.
– Discutir los conceptos fundamentales de la simulaci´on de eventos discretos, en particular la gesti´on del reloj de la simulaci´on y del calendario de eventos. – Realizar, con “l´apiz y papel”, la simulaci´on de eventos discretos de circuitos
digitales, tal como se muestra en el Caso Pr´actico de la Secci´on 1.4.
– Discutir las siguientes propiedades de los circuitos digitales: el retardo de los dispositivos, su ejecuci´on concurrente, la marginalidad en el dise˜no y la fortaleza de las se˜nales.
– Discutir qu´e son los ´arboles de buffers y cu´al es su finalidad.
– Discutir el prop´osito y los fundamentos del test en dise˜no y manufactura, as´ı como los conceptos: modelo de fallos, cobertura del test y calidad del test. – Discutir la utilidad y composici´on de los bancos de pruebas.
– Instalar en su propio ordenador y realizar las operaciones b´asicas de manejo de alg´un entorno de simulaci´on de VHDL’93, tal como ModelSim (preferible) o VeriBest. Estas operaciones b´asicas incluyen al menos: edici´on de modelos y depurado usando el debugger, simulaci´on y visualizaci´on de los resultados.
1.1 Lenguajes para la descripción de hardware
Los sistemas digitales se han ido haciendo m´as y m´as complejos durante las pasadas d´ecadas. Este incremento en la complejidad responde, a grandes rasgos, a la Ley de Moore, que establece que el avance tecnol´ogico posibilita que cada aproximadamente 18 meses se doble el n´umero de transistores que es posible alojar en un circuito integrado.
De esta forma, en la d´ecada de 1970 un circuito integrado t´ıpico conten´ıa decenas de miles de transistores. En la d´ecada de 1980, la capacidad aument´o a cientos de miles de transistores, y en la d´ecada de 1990 fue del orden de decenas de millones. En la d´ecada de 2000, la capacidad de los circuitos integrados es del orden de miles de millones de transistores.
En los a˜nos 70, cuando se fabricaba un circuito integrado, se documentaba su funcionamiento empleando una combinaci´on de esquem´aticos (representaci´on gr´afica de los componentes del circuito), diagramas de transici´on de estados y lenguaje natural (por ejemplo, ingl´es). Esta documentaci´on pod´ıa consistir en varios cientos de p´aginas. Los ingenieros, que compraban el circuito integrado para usarlo en sus propios dise˜nos, ten´ıan que leer esta documentaci´on para entender el funcionamiento del circuito integrado. Sin embargo, leer cientos de p´aginas no era tarea f´acil. Adem´as, en ocasiones la documentaci´on conten´ıa errores o ambig¨uedades. 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 situaci´on, el Departamento de Defensa de EE.UU. busc´o un procedimiento mediante el cual los fabricantes de circuitos integrados pudieran es-pecificar de forma precisa el funcionamiento de los circuitos. Con esta motivaci´on, el Departamento de Defensa de EE.UU. inici´o el desarrollo de un lenguaje para la descripci´on del hardware, para lo cual estableci´o un grupo de trabajo compuesto por expertos de varias disciplinas, pertenecientes a diferentes compa˜n´ıas.
Un lenguaje para la descripci´on del hardware o HDL (siglas que provienen del ingl´es: Hardware Description Language) es un lenguaje, legible tanto por las m´aquinas como por los seres humanos, ideado para permitir la descripci´on 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 simulaci´on por ordenador permite ob-tener el valor de las se˜nales de salida del circuito integrado para una determinada secuencia de se˜nales de entrada.
El HDL que el Departamento de Defensa de EE.UU. cre´o en los a˜nos 80 se llam´o VHDL. Las siglas VHDL provienen de VHSIC Hardware Description Language. VHSIC es un acr´onimo 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 programaci´on ADA. En 1987, el Institute of Electrical and Electronics Engineers (IEEE) adopt´o VHDL como el est´andar n´umero 1076. El establecimiento de un est´andar del lenguaje tiene una ventaja fundamental: las compa˜n´ıas desarrolladoras de software de simulaci´on tienen una definici´on claramente establecida del lenguaje al que deben dar soporte.
Ventajas de los HDL
En la actualidad, la casi totalidad de los dise˜nadores de circuitos digitales de cierta complejidad usan para realizar sus dise˜nos lenguajes para la descripci´on del hard-ware. El empleo de HDL presenta ventajas respecto al empleo de descripciones basadas en esquem´aticos. Algunas de ellas son las siguientes:
1. Puesto que una descripci´on HDL es simplemente un fichero de texto, es mucho m´as portable que un dise˜no esquem´atico, que debe ser visualizado y editado empleando la herramienta gr´afica espec´ıfica del entorno de CAD (Computer-Aided Design - Dise˜no asistido por ordenador) con el que se ha creado.
2. Una descripci´on esquem´atica ´unicamente describe el dise˜no de manera es-tructural, mostrando los m´odulos y la conexi´on entre ellos. Por el contrario, la descripci´on 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 autom´aticamente la estructura del circuito l´ogico a partir de la descripci´on de su comportamiento.
3. El mismo HDL que se ha usado para la descripci´on 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 se˜nales 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 dise˜na el propio circuito, pudi´endose con ello ir realizando diferentes pruebas a medida que se avanza en el dise˜no. Como ventajas a˜nadidas, la descripci´on de los programas de test usando HDL es altamente portable y repetible.
HDL más ampliamente usados
En la actualidad, los HDL m´as ampliamente usados son Verilog HDL y VHDL. Ambos son lenguajes est´andar de IEEE para el modelado y simulaci´on de hard-ware.
– Verilog se cre´o, a principios de los a˜nos 80, como un lenguaje propiedad de la compa˜n´ıa Philip Moorby, compa˜n´ıa que a˜nos m´as tarde fue adquirida por Cadence Design Systems. Posteriormente, Verilog se hizo de dominio p´ ubli-co y se promovi´o como un est´andar de IEEE en el a˜no 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 est´andar para la descripci´on de hardware. En el a˜no 1987
se convirti´o en un est´andar de IEEE (IEEE 1067-1987). Posteriormente, se incorporaron mejoras al lenguaje que dieron lugar a dos actualizaciones del est´andar: la primera en 1993 (IEEE 1076-1993) y la segunda en 2001 (IEEE 1076-2001).
A principios del a˜no 2000 se desarroll´o otro HDL denominado SystemC, el cual consiste en un conjunto de librer´ıas en C++. SystemC se convirti´o en el est´andar 1666 de IEEE en el a˜no 2005.
1.2 Ciclo de diseño de los circuitos digitales
El empleo de HDL es pr´actica habitual en las diferentes fases del ciclo de dise˜no de circuitos digitales. En la Figura 1.1 se muestra el ciclo de actividades que se realizan durante el ciclo de dise˜no e implementaci´on de circuitos digitales de relativa complejidad.
En primer lugar, el dise˜nador debe establecer las especificaciones del dise˜no, en t´erminos de qu´e se espera que haga el circuito y qu´e restricciones debe satisfacer (frecuencia de reloj, retardos, tama˜no, etc.).
A continuaci´on, el dise˜nador debe crear un dise˜no de alto nivel del circuito, para lo cual puede emplear un lenguaje para la descripci´on de hardware (HDL), por ejemplo VHDL o Verilog. Seguidamente, debe desarrollar un conjunto de programas de test (usando tambi´en VHDL o Verilog) y, si es posible, usar estos programas para testear el dise˜no de alto nivel, usando para ello una herramienta de simulaci´on (verificaci´on funcional). En funci´on de los resultados de la simula-ci´on de los tests, puede ser preciso modificar el dise˜no de alto nivel, repiti´endose los pasos anteriores tantas veces como sea preciso.
Una vez el dise˜no de alto nivel funciona adecuadamente, debe traducirse al nivel de puertas l´ogicas o de transistores. Este proceso se denomina s´ıntesis. S´ın-tesis es la generaci´on autom´atica del dise˜no del circuito a partir de la descripci´on de su comportamiento. El resultado obtenido de la s´ıntesis, denominado netlist, es una descripci´on de todas las conexiones y componentes que deben componer el circuito.
La descripci´on a nivel de puertas o transistores obtenida a partir de una descripci´on 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 dise˜nador especificar c´omo debe realizarse. En particular, permiten especificar el nivel de esfuerzo a emplear por la herramienta en la optimizaci´on autom´atica del circuito, tanto en lo que respecta a la reducci´on del ´area del circuito como en lo que respecta a sus prestaciones. Asimismo, las herramientas de s´ıntesis permiten especificar qu´e m´odulos del circuito no deben ser optimizados.
El dise˜no a nivel de puertas o transistores debe ser vuelto a testear mediante simulaci´on (verificaci´on de tiempos), usando, si es posible, el mismo conjunto de tests que se realizaron sobre el dise˜no de alto nivel. El objetivo es estudiar si el dise˜no se comporta como debe y si satisface todas las restricciones que se
! "!# $
Figura 1.1: Ciclo de dise˜no del hardware digital.
impusieron en la fase de especificaci´on. Si se detecta un problema a este nivel, debe volverse al correspondiente paso del ciclo de dise˜no.
Una vez el dise˜no 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 l´ogico 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 dise˜nados. Estas caracter´ısticas son debidas tanto a los transistores que componen las puertas l´ogicas como a las conexiones entre ellos. Entre las m´as importantes est´an las siguientes.
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 el´ectrico 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 est´a en una nave espacial rumbo a J´upiter. 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 despu´es que el comando para encenderlo, causando que el motor estuviese encendido durante dos minutos. La se˜nal 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 se˜nal, ya que la se˜nal en s´ı misma no se modifica.
El retardo inercial es adecuado para modelar los retardos a trav´es de dispo-sitivos tales como los transistores y las puertas l´ogicas. 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 act´uan 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 duraci´on no provoca cambios en su salida, pero si los provoca un pulso de 5 ns. Si la primera transici´on 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 trav´es de dispositivos con poca inercia, tales como las l´ıneas de metal construidas en el chip para conectar los dispositivos.
Ejecución concurrente
Los m´odulos l´ogicos se ejecutan concurrentemente. Cuando cambia el valor de una se˜nal de entrada a varios m´odulos, todos estos m´odulos 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 simulaci´on de eventos discretos.
Diseños marginales
Los retardos de los dispositivos dependen de la condiciones de fabricaci´on del chip. En general, existen variaciones en el valor de los retardos de los chips fabricados
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 dise˜nar 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 se˜nales simuladas llegan a los m´odulos 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 se˜nales depende del valor de los retardos, y los retardos simulados no se corresponden con los existentes en el dise˜no f´ısico, entonces ese dise˜no producir´a chips que no funcionen, o que funcionen s´olo una parte del tiempo.
Fortaleza de las señales
Las se˜nales de los circuitos digitales reales poseen una determinada “fortaleza”, que determina en qu´e medida las transiciones en el valor de la se˜nal son abruptas (y, por tanto, los retardos debidos a esa se˜nal), y el n´umero y tipo de entradas a m´odulos que pueden ser conectados a esa se˜nal.
Esta caracter´ıstica de las se˜nales, que puede ser modelada en VHDL y en Verilog, viene determinada por los niveles de tensi´on del ‘0’ y del ‘1’ l´ogicos (por ejemplo, para un ‘1’ l´ogico, en qu´e medida est´a el voltaje de la se˜nal pr´oximo al voltaje de la alimentaci´on), y por la cantidad de corriente que puede proporcionar y aceptar el dispositivo que genera la se˜nal.
En un circuito digital t´ıpico, la transferencia de un valor l´ogico desde un pin de salida de un m´odulo, a varios pines de entrada de otros m´odulos, precisa de la transferencia de carga el´ectrica hacia los pines de entrada (en el caso de ‘1’ l´ogico) o hacia el pin de salida (en el caso de ‘0’ l´ogico). 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 pr´actico, esto implica que la salida de un m´odulo puede ser conectada como m´aximo a un determinado n´umero de entradas de otros m´odulos. En aquellos casos en que la se˜nal deba conectarse a un n´umero de m´odulos superior a este n´umero m´aximo, entonces debe emplearse un ´arbol de buffers. En la Figura 1.2 se muestra un ´arbol de buffers que lleva una se˜nal (out) a 16 m´odulos (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 a˜nadido: igualar los retardos de las se˜nales de entrada a todos los m´odulos, ya que el ´arbol de buffers est´a dise˜nado 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 se˜nal de reloj a los flip-flops en los circuitos secuenciales s´ıncronos, en los cuales es importante que la se˜nal de reloj llegue a todos los flip-flops aproximadamente en el mismo instante.
Figura 1.2: ´Arbol de buffers para llevar una se˜nal a 16 m´odulos.
1.4 Simulación de eventos discretos
A la hora de escribir c´odigo en cualquier lenguaje para la descripci´on de hardware, resulta ´util saber de qu´e manera se realizar´a la simulaci´on de ese c´odigo. La mayor´ıa de las herramientas de simulaci´on de HDL emplean una metodolog´ıa denominada simulaci´on de eventos discretos. En la simulaci´on 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 se˜nal e instante de tiempo en que est´a planificado que se realice esta asignaci´on. Los eventos est´an ordenados de menor a mayor instante de ejecuci´on en el calendario.
A continuaci´on se describe el algoritmo de la simulaci´on, que consta de los siguientes pasos:
Paso 1. En el instante de inicio de la simulaci´on, se activa el evento “Inicio de la Simulaci´on”. Como parte de las acciones asociadas a la ejecuci´on de este evento, se pone el reloj de la simulaci´on a cero y se registran los nuevos eventos en el calendario de eventos.
Paso 2. Se extrae el primer evento del calendario.
Paso 4. Se ejecuta el evento y, si procede, se actualiza el calendario de eventos. Paso 5. Se comprueba si existen m´as eventos en el calendario de eventos. Si
existen m´as eventos se vuelve al paso 1. En caso contrario, se avanza al paso 6.
Paso 6. Fin de la simulaci´on.
El anterior algoritmo de la simulaci´on no describe c´omo se actualiza el ca-lendario de eventos. Los pasos a seguir para actualizar el caca-lendario 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 se˜nal se reduce al caso de un evento con retardo (ya sea inercial o de trasporte) haciendo el valor del retardo cero.
A continuaci´on se describen los pasos a seguir para actualizar el calendario de eventos cuando en el nuevo evento sobre la se˜nal existe un retardo inercial. Vamos a considerar que la se˜nal sobre la que se produce el evento se denomina A, el nuevo valor de la se˜nal es Anew, el valor del retardo inercial es ret y el instante
actual de simulaci´on es tactual. Para actualizar el calendario de eventos hay que
seguir los siguientes pasos:
1. Se borran aquellos eventos sobre A cuyo instante de ejecuci´on 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 ejecuci´on est´e 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 se˜nal 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 ejecuci´on 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)
s
Figura 1.3:Circuito ejemplo.
A continuaci´on se describen los pasos en la simulaci´on de dicho circuito: Paso 1. En el instante inicial el reloj de la simulaci´on vale 0 ns y se asigna nuevo
valor a las se˜nales x1 y x2. Debido a ello, se ejecutan las asignaciones que
tienen en su lado derecho x1o x2. En este caso, se ejecutan las asignaciones
correspondientes a la puerta NAND (asignaci´on 1.1) y a la puerta OR (asignaci´on 1.2). Se producen dos nuevos eventos, denominados E0 y E1:
– El evento E0, planificado para el instante 1 ns, se debe a la ejecuci´on
de la asignaci´on de la puerta NAND. En este evento se asigna a s el valor ‘0’.
– El evento E1 se debe a la ejecuci´on de la asignaci´on de la puerta OR.
En este evento se asigna a y el valor ‘1’ en el instante 2 ns. Observa que la asignaci´on y ← x1 or 1 es equivalente a y ← 1 independientemente
del valor de x1. Si la se˜nal x2 valiese ‘0’ en lugar de ‘1’ el valor de y
ser´ıa indefinido hasta que s tuviese un valor definido.
Adem´as, se incorpora al calendario de eventos un evento, llamado E2,
programado para el instante 5 ns, y cuya acci´on es: x2 ← 0. Los valores
de las se˜nales y el calendario de eventos en el instante 0 ns se presentan en las tablas siguientes:
Se˜nal 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 se˜nal s pasa a ser cero y el reloj de la simulaci´on vale 1 ns. El cambio en la
se˜nal s produce que se ejecute la asignaci´on 1.2 y se genere un nuevo evento (E3). A continuaci´on se muestran los valores de las se˜nales y el calendario
de eventos en el instante 1 ns. Se˜nal Valor x1 ’1’
x2 ’1’
s ’0’
y ’U’ (valor indefinido)
Calendario de eventos E1 2 ns y ← 1
E3 3 ns y ← 1
Paso 3. El simulador extrae el evento E1 del calendario y lo ejecuta. Entonces,
el valor de la se˜nal y pasa a ser uno y el reloj de la simulaci´on vale 2 ns.
El cambio en la se˜nal y no genera ning´un evento. Los valores de las se˜nales y el calendario de eventos en el instante 2 ns se muestran a continuaci´on.
Se˜nal 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 simulaci´on vale 3 ns y los valores de las se˜nales y el contenido del calendario de eventos son los siguientes:
Se˜nal 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 se˜nal x2pasa a ser cero y el reloj de la simulaci´on
vale 5 ns. Como resultado, se ejecutan las asignaciones 1.1 y 1.2 y se
generan dos eventos (E4 y E5). A continuaci´on se muestran los valores
de las se˜nales y el calendario de eventos en el instante 5 ns. Se˜nal 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 se˜nal s pasa as´ı a ser uno y el reloj de la simulaci´on pasa a valer
6 ns. Cuando esto sucede, se ejecuta la asignaci´on 1.2. El evento E5 se
borra del calendario de eventos ya que E5 y el nuevo evento (E6) afectan
a la misma se˜nal asign´andole valores distintos y el lapsus de tiempo entre ambos eventos es inferior a 2 ns. Los valores de las se˜nales y el calendario de eventos en el instante 6 ns se muestran a continuaci´on.
Se˜nal Valor x1 ’1’ x2 ’0’ s ’1’ y ’1’ Calendario de eventos E6 8 ns y ← 1
Figura 1.4:Cronomagrama de las se˜nales 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 ejecuci´on. El cronomagrama de las se˜nales 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 dise˜no de circuitos integrados. No s´olo se emplea para verificar el correcto funcionamiento del circuito ya completamente dise˜nado, sino que tambi´en es una ayuda esencial para el dise˜nador durante la fase de dise˜no del circuito.
Finalmente, el test se emplea en manufactura, para determinar qu´e 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 s´olo funcionan a baja velocidad (cada tipo es vendido a diferente precio). Si el dise˜no se ha realizado correctamente, los chips defectuosos en los test de manufactura se deben a problemas en los procesos de fabricaci´on 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 compa˜n´ıa fabricante de los chips.
Esencialmente, el test consiste en fijar valores en todas las entradas del circuito y observar qu´e valores se obtienen en sus salidas. A cada asignaci´on 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 fabricaci´on. Las causas de mal funcionamiento de los chips m´as com´ un-mente observadas en la pr´actica son:
– Abiertos. Conexiones entre los dispositivos que se encuentran abiertas debido a alg´un problema, por ejemplo, debido a la rotura de la l´ınea de metal que establece la conexi´on.
– Cortos. Conexiones que se han establecido entre diferentes dispositivos, cuando no deber´ıan haberse producido.
– Acoplos. Valores l´ogicos en una parte del circuito que inadvertidamente cambian el valor l´ogico 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 fabricaci´on 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 n´umero muy elevado de patrones de fallo. Un patr´on de fallo es una determinada selecci´on 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 consideraci´on que existen patrones de fallo que dan lugar a un comportamiento equivalente (defectuoso) del circuito, el n´umero 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 conexi´on 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 detecci´on 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, habr´a otros tipos de fallos que dar´an 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.
Seg´un se van usando m´as y m´as 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 m´as complicado, ya que las salidas del circuito dependen no s´olo de las entradas, sino tambi´en 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 inicializaci´on (secuencia de valores de las entra-das del circuito), se lleva el circuito al estado deseado. A continuaci´on, se aplica el vector de test para probar el circuito en ese estado.
Mediante este procedimiento, un ´unico test consiste en una secuencia de inicializaci´on, seguida de otro vector de test. Este procedimiento conduce a usar un gran n´umero de vectores de test, muchos de los cuales son simplemente secuencias de inicializaci´on. Adem´as, en algunos casos puede no ser posible fijar todos los flip-flops a los valores deseados.
2. El segundo m´etodo consiste el usar en el dise˜no scan 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 n´umero de vectores de test.
Cuanto mayor sea la cobertura de fallos, menor ser´a el n´umero de chips defectuosos que superar´an con ´exito el proceso de inspecci´on. Cuanto menor sea el n´umero de vectores de test, menor ser´a el tiempo necesario para ejecutar el programa de test, con lo cual podr´an testearse mayor n´umero de chips por unidad de tiempo.
Test funcional
El test funcional se emplea en todas las etapas del proceso de dise˜no del circuito. Su objetivo es verificar que el circuito realiza todas las operaciones como debiera. En los dise˜nos grandes, que normalmente se dise˜nan de manera jer´arquica, todos los subcircuitos de bajo nivel deben ser comprobados funcionalmente, usan-do programas de test espec´ıficos para cada uno, antes de ser incluiusan-dos en los subcircuitos de m´as alto nivel.
Aunque todos los subcircuitos sean comprobados por separado, el subcircuito obtenido de la composici´on de todos ellos debe tambi´en ser comprobado, us´andose para ello su propio programa de test.
A continuaci´on, 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 simulaci´on. Habitualmente, el primer prototipo hardware contiene errores. La comparaci´on de los resultados del test, con los resultados de las simulaciones para esos mismos tests, puede ayudar a identificar errores de dise˜no y de fabricaci´on.
Programas de test funcional
Un m´etodo 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
porque el n´umero de posibles vectores es muy grande, o bien porque algunas combinaciones de valores de las entradas no son v´alidas para ese determinado circuito. Adem´as, algunas funciones requieren de una determinada secuencia de vectores de entrada.
En conclusi´on, 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 n´umero de posibles vectores de entrada es muy grande (se tardar´ıa meses o a˜nos en probarlos todos), existen varios m´etodos heur´ısticos que pueden aplicarse para reducir el n´umero de vectores de entrada.
1. Puede emplearse el conocimiento sobre el funcionamiento de circuito para descartar aquellos vectores de entrada que no tienen ninguna funci´on en el circuito, o que nunca ocurrir´an en la pr´actica.
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 continuaci´on, 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 autom´atica 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 m´etousan-do diferente al empleausan-do en el test, y comparar los resultausan-dos. Cuando no es posible aplicar un m´etodo de c´alculo 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 n´umeros, puede comprobarse que el resultado obtenido sea mayor o igual que el menor de los n´umeros del conjunto, y menor o igual que el mayor de los n´umeros del conjunto.
Banco de pruebas
Muchas herramientas de simulaci´on incluyen men´us que permiten asignar valores a las entradas del circuito. Sin embargo, el uso de este tipo de interfaces gr´aficas de usuario puede resultar lento y el programa de test desarrollado puede no ser exportable a otras herramientas de simulaci´on.
%&'()&*+ ,-.(+ /0 1')0,-2 3456786479: ;<=< 8>?:8? < @:AB < 69:8 < A? < 9 < A9
UUT
3456786479: ? < 6:CD8:5>67E = ? < @:A8 < A4@9>?:A ? < @ 9 < A9 FGHIJKJL JMNNO P JMQKJL KRMNNOFigura 1.5:Diagrama de bloques del modelo de un banco de pruebas.
Una alternativa mucho m´as ventajosa consiste en codificar el programa de test usando un HDL. Es decir, implementar el programa de test en otro m´odulo de c´odigo HDL, que es denominado banco de pruebas.
El banco de pruebas contendr´a el circuito que est´a siendo probado (denomi-nado abreviadamente UUT, del ingl´es “Unit Under Test”) como un subcircuito. Todas las entradas al UUT ser´an generadas dentro del banco de pruebas, y todas las salidas del circuito ser´an comprobadas dentro del banco de pruebas.
En resumen, el banco de pruebas debe incluir (v´ease el diagrama de bloques en la Figura 1.5):
– Un subcircuito generador de los vectores de test. – El circuito que est´a siendo probado (UUT).
– Un subcircuito de comprobaci´on de los resultados obtenidos del test. Como m´odulo de c´odigo en HDL, el banco de pruebas es un m´odulo 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 instrucci´on disponible en el HDL para generar los vectores de test y analizar las salidas del UUT, pudi´endose llegar a crear programas extremadamente complejos.
Finalmente, recalcar que cuando se dise˜na un circuito digital, es conveniente dise˜nar tambi´en su banco de pruebas. Si el circuito se dise˜na jer´arquicamente, entonces cada subcircuito debe ser testeado separadamente antes de ser combi-nado con otros subcircuitos para integrar un circuito de nivel jer´arquico superior. Asimismo, deber´a 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 dise˜no 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 secci´on se proporcionan algunas indicaciones b´asicas para la instala-ci´on y manejo de dos simuladores de VHDL’93: VeriBest VHDL y ModelSim PE
Student Edition. Cualquiera de los dos puede emplearse para la simulaci´on de los modelos planteados en este texto.
El simulador VeriBest VHDL fue desarrollado por la compa˜n´ıa VeriBest Inc. Cuando esta compa˜n´ıa pas´o a formar parte de la corporaci´on Mentor Graphics, dej´o 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 a˜no 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 s´olo a la simulaci´on, sino tambi´en a la s´ıntesis, entre las que cabe destacar Quartus II Web Edition, que puede descargarse gratuitamente del sitio web de la compa˜n´ıa Altera Corporation.
Se sugiere al alumno que escoja en este punto qu´e entorno de simulaci´on va a emplear. Si decide usar VeriBest, la gu´ıa de instalaci´on y uso del Ap´endice A puede serle ´util. Por el contrario, si decide usar ModelSim (lo cual recomendamos), encontrar´a la correspondiente gu´ıa en el Ap´endice B.
2
Conceptos básicos de VHDL
Objetivos. Una vez estudiado el contenido del tema deber´ıa saber: – Declarar una entidad de dise˜no en VHDL.
– Declarar los elementos sint´acticos b´asicos de VHDL.
– Discutir las principales caracter´ısticas de la asignaci´on concurrente y las diferencias entre la asignaci´on secuencial y concurrente. – Definir el comportamiento de un circuito mediante instanciaci´on
y conexi´on de otros circuitos.
– Discutir la utilidad de la parametrizaci´on en la descripci´on de un circuito. – Discutir las principales caracter´ısticas de las se˜nales, variables y constantes
en VHDL. Usar adecuadamente cada una de ellas.
– Tipos de datos b´asicos en VHDL y sus principales atributos.
– Declarar y usar librer´ıas VHDL y conocer las librer´ıas m´as com´unmente usadas. – Discutir las principales caracter´ısticas de los tipos de retardo
y modelar los distintos tipos de retardo en VHDL.
– Realizar, con “l´apiz y papel”, el cronograma de las se˜nales de un circuito conocido el c´odigo 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 programaci´on (tales como C o Fortran), incluyendo estructuras record, funciones, procedimientos y soporte a bloques de c´odigo compilados separadamente.
Pese a lo anterior, para la mayor parte de las aplicaciones de VHDL al modelado y simulaci´on de circuitos digitales, es suficiente con emplear un peque˜no subconjunto de las estructuras y capacidades proporcionadas por el lenguaje. En particular, se ha definido un subconjunto del lenguaje VHDL, denominado VHDL
synthesis interoperability subset (est´andar IEEE 1076.6), que contiene los tipos de datos, operadores y otras capacidades de VHDL que deber´ıan ser usados para crear c´odigo VHDL sintetizable. Esto es, c´odigo a partir del cual las herramientas de CAD puedan generar autom´aticamente circuitos hardware que funcionen.
Siguiendo estas reglas y centr´andonos en pr´acticas “simples” para la codifi-caci´on de alto nivel, en este cap´ıtulo se introducen los conceptos b´asicos para el modelado y la simulaci´on empleando VHDL.
2.1 Definición de la entidad de diseño
Se denomina entidad de dise˜no al bloque constitutivo b´asico para la descripci´on del hardware en VHDL. Consta de las dos partes siguientes:
1. Entity: interfaz con el exterior, en la que se definen los puertos de conexi´on (se˜nales de entrada y/o salida) de la entidad de dise˜no.
2. Architecture: define el comportamiento o la estructura de la entidad de dise˜no. Es decir, c´omo los puertos de salida de la entidad de dise˜no se relacionan con sus puertos de entrada.
A continuaci´on, se explica c´omo 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 dise˜no. Incluye: – El nombre de la entidad de dise˜no.
– La lista de las se˜nales de salida y de entrada que componen la interfaz (normalmente se aplica el convenio de escribir primero las salidas y a con-tinuaci´on las entradas). A cada una de estas se˜nales se le denomina puerto (port). Existen tres tipos de puertos: in (entrada), out (salida) e inout (bidireccional).
Ejemplo2.2.1. En la Figura 2.1 se muestra la definici´on de las interfaces de las puertas l´ogicas 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 definici´on de la interfaz.
A continuaci´on, se especifica el nombre de cada uno de los puertos, su direc-ci´on (in, out o inout) y su tipo. En el ejemplo mostrado en la Figura 2.1, todos los puertos son se˜nales del tipo std logic.
Finalmente, las palabras reservadas end entity, seguidas del nombre de la interfaz, indican el final de la definici´on.
y0 x0 x0 y0 x1 y0 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 may´usculas o en min´usculas, puesto que en VHDL no se diferencia entre los caracteres en may´uscula y en min´uscula. Por ejemplo, es equivalente escribir entity, ENTITY y EnTiTy, as´ı como tambi´en es equivalente escribir not1 y NoT1.
Los nombres definidos por el usuario deben comenzar por una letra, seguida opcionalmente por cualquier secuencia de letras, n´umeros y caracteres gui´on bajo, con la limitaci´on de que ni pueden aparecer dos guiones bajos seguidos, ni el gui´on bajo puede ser el ´ultimo caracter del nombre.
2.3 Architecture
La architecture describe el comportamiento o la estructura de la entidad de dise˜no. Esta definici´on puede emplear:
– Una descripci´on estructural, en la cual el componente es descrito mediante la conexi´on de componentes de m´as bajo nivel.
– Una descripci´on de su comportamiento, en la que se describe el comporta-miento que debe tener el componente.
– Una descripci´on mixta de la estructura y del comportamiento, que incluya componentes de m´as bajo nivel y c´odigo describiendo el comportamiento. Ejemplo2.3.1. En la Figura 2.2 se muestran las architecture que describen el comportamiento de las puertas l´ogicas NOT, XOR y AND. Las correspondientes entityson 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 dise˜no. En general, se les puede dar nombres diferentes.
A grandes rasgos, la definici´on de la architecture tiene la sintaxis siguiente:
architecture <nombre architecture> of <nombre entity> is <Declaraci´on de se~nales, variables y constantes locales>
y0 x0 x0 y0 x1 y0 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.
<Declaraci´on de la entity de los componentes> begin
<Instanciaci´on 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 se˜nales, variables y constantes, todas ellas locales a la definici´on de la archi-tecture, as´ı como tambi´en las entity de los componentes usados en la definici´on 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 ejecuci´on de las sentencias no est´a determinado por el orden en que se han escrito.
El instante de ejecuci´on de una sentencia de asignaci´on concurrente viene determinado por los eventos en las se˜nales a las cuales la sentencia es “sensible”. Ejemplo 2.3.2. La sentencia de asignaci´on concurrente
y0 <= not x0;
es ejecutada cada vez que se produce un cambio en el valor de la se˜nal x0, calcul´andose el nuevo valor de la se˜nal y0. En la terminolog´ıa de VHDL, se dice que esta sentencia, de la cual se calcula y0, es “sensible” a la se˜nal x0.
Ejemplo2.3.3. Dado el c´odigo mostrado a continuaci´on, se producir´a un cambio en la se˜nal a cada vez que cambie b, y se producir´a un cambio en la se˜nal c cada vez que cambie u o v.
architecture archEjemplo of ... ...
begin
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 se˜nal en un determinado instante de tiempo, entonces la se˜nal toma el valor X. Obs´ervese que en un circuito real una situaci´on de ese tipo podr´ıa producir un da˜no en el circuito o resultar en la asignaci´on del valor 1 ´o 0 a la se˜nal de manera impredecible.
2.3.2 Bloque process
Para describir la operaci´on 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 ejecut´andolas de manera secuencial.
Por otra parte, los bloques process se ejecuta concurrentemente unos res-pecto a los otros (s´olo las sentencias dentro de cada bloque process se ejecutan secuencialmente), al igual que las dem´as sentencias de alto nivel, puesto que un bloque process constituye una sentencia de alto nivel dentro de la definici´on 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 se˜nales a las cuales el bloque process es “sensible”. Esta lista se escribe, entre par´entesis, a continuaci´on de la palabra reservada process. En este caso, el bloque process es ejecutado s´olo en el instante en que una o varias de estas se˜nales a las que es “sensible” cambia de valor. Ejemplo2.3.4. El siguiente c´odigo muestra un m´etodo est´andar 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.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 jer´arquica. Es decir, es posible definir un circuito mediante instanciaci´on y conexi´on de otros circuitos, y a su vez usar este nuevo circuito para definir, mediante su conexi´on con otros circuitos, otro circuito de un nivel jer´arquico superior, y as´ı sucesivamente. A esto se denomina realizar una descripci´on modular y jer´arquica del hardware.
Para describir un circuito mediante la instanciaci´on y conexi´on de subcircui-tos, es necesario:
1. Escribir la declaraci´on 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 conexi´on entre subcircuitos se indica usando se˜nales con nombres id´enticos.
– Una conexi´on entre el circuito y un subcircuito se indica “mapeando” la se˜nal del circuito con el correspondiente puerto del subcircuito. Esta conexi´on entre se˜nales puede realizarse mediante:
· Asociaci´on posicional, es decir, mediante la posici´on en que la se˜nal se sit´ua en la lista de par´ametros.
· Asociaci´on mediante el nombre, tambi´en llamada asignaci´on ex-pl´ıcita, en la cual la se˜nal y su puerto asociado son incluidos en la lista de par´ametros de la forma
puerto => se~nal
Ejemplo2.3.5. En la Figura 2.3 se muestra el diagrama y la implementaci´on de un multiplexor de 2 se˜nales de 1 bit. Cuando la se˜nal de control s0 vale ’0’, la se˜nal i0 se transmite a la salida d, mientras que cuando s0 vale ’1’ es la se˜nal i1 la que se transmite a la salida.
ST SU V W T XYZ [\] ^_ `_
Figura 2.3: Multiplexor de 2 se˜nales de 1 bit: a) diagrama; b) implementa-ci´on.
Como puede observarse en la Figura 2.3b, este circuito multiplexor est´a 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 se˜nales n1, n2 y n3 tienen por objeto describir la conexi´on entre los componentes.
A continuaci´on, se muestra la descripci´on de la estructura del circuito en lenguaje VHDL. Obs´ervese que al instanciar cada componente, se indica qu´e se˜nal debe asociarse a cada uno de sus puertos. Una misma se˜nal asociada a diferentes puertos indica el establecimiento de una conexi´on 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 );
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 se˜nales de 1 bit puede emplearse para dise˜nar un multiplexor de dos se˜nales de 4 bits. En la Figura 2.4 se muestra la representaci´on esquem´atica del circuito. El c´odigo VHDL que describe este circuito se muestra a continuaci´on.
--- 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;
i0 i1 d s0 abcd e f i0 i1 d s0 abcd e f i0 i1 d s0 abcd e f i0 i1 d s0 abcd e f a3 b3 a2 b2 a1 b1 a0 b0 d3 d2 d1 d0 s0
Figura 2.4:Multiplexor de 2 se˜nales de 4 bit dise˜nado mediante la conexi´on de 4 multiplexores de 2 se˜nales 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;
---2.3.4 Constantes generic
Una propiedad muy relacionada con la modularidad y la jerarqu´ıa es la parame-trizaci´on, que es la capacidad de modificar el valor de ciertas propiedades de un circuito cuando es instanciado, con el fin de adaptarlo a la aplicaci´on en concreto a la que vaya a destinarse al formar parte del circuito de nivel jer´arquico superior. La parametrizaci´on es una propiedad fundamental en la reutilizaci´on del c´odigo, ya que permite adaptar un mismo fragmento de c´odigo 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 jer´arquico. Ejemplos t´ıpicos de constantes gen´ericas son el valor de determinados retardos, el n´umero de bits de un bus de se˜nales, 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 pr´actico descrito en la Secci´on 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 dise˜no (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 definici´on de varias arquitecturas para una misma entidad de dise˜no (con una ´unica interfaz). Por ejemplo, pueden definirse varias arquitecturas de una misma entidad de dise˜no, correspondientes a diferentes versiones del circuito: velocidad baja, media y alta.
En este caso, cuando se emplee esa entidad de dise˜no debe indicarse expl´ı-citamente qu´e arquitectura hay que emplear. Esto puede hacerse mediante la definici´on de una configuraci´on (configuration).
2.5 Señales, variables y constantes
En VHDL se emplean variables, se˜nales y constantes para describir la operaci´on del circuito. Las se˜nales corresponden con las se˜nales l´ogicas reales existentes en el circuito. Las variables pueden o no corresponder con se˜nales f´ısicas reales. Las constantes corresponden a magnitudes cuyo valor no cambia durante la simulaci´on (t´ıpicamente retardos, n´umero de l´ıneas de buses, n´umero de bits de palabras, etc.).
Las variables siempre deben usarse dentro de bloques process. Aparte de esta restricci´on, pueden ser usadas con relativa libertad.
Por el contrario, hay que ser cuidadoso con el empleo de las se˜nales. Las se˜nales definidas en el port de una entity tienen una direcci´on, lo cual condiciona
su uso: no puede leerse el valor de una se˜nal de salida (out), ni asignarse un valor a una se˜nal de entrada (in). Las se˜nales declaradas en la definici´on 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 se˜nales es el siguiente: – Emplear una variable cuando vaya a usarse s´olo dentro de un bloque
pro-cess.
– Emplear una se˜nal 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 s´olo pueden ser se˜nales.
Para asignar valor a una variable o constante se emplea :=, mientras que se emplea <= para asignar valor a una se˜nal. S´olo puede asignarse valor a las variables en los bloques process. Puede asignarse valor a las se˜nales mediante asignaciones concurrentes o en los bloques process.
La diferencia fundamental entre una asignaci´on a una se˜nal y una asignaci´on a una variable, ambas realizadas dentro de un bloque process, es que la asignaci´on a la se˜nal se ejecuta concurrentemente con la siguiente sentencia del bloque process, mientras que la asignaci´on 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 c´alculos para poder asignarle valor a una se˜nal, se definen nuevas variables, se hacen los c´alculos usando esas variables, y finalmente se asigna el resultado de los c´alculos a la se˜nal. 2. Puesto que una se˜nal 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 se˜nal de salida.
Asimismo, existe una diferencia importante en el retraso asociado a una asignaci´on de una variable y de una se˜nal. Este punto es discutido en la Secci´on 2.7.
Pueden definirse constantes en VHDL usando la palabra reservada constant. Las sentencias de definici´on de constantes pueden situarse en los bloques entity y architecture, antes de la palabra reservada begin. Tambi´en pueden definirse constantes dentro de la definici´on de un paquete (package), en cuyo caso deben ser incluidas mediante una cl´ausula use.
2.5.1 Tipos de datos
T´ıpicamente, la informaci´on se comunica dentro de un sistema digital usando se˜nales de valor binario (0 ´o 1). En los sistemas de l´ogica positiva, cuando el voltaje de la se˜nal tiene un valor “alto” (3.3 ´o 5 voltios en la tecnolog´ıa CMOS),
representa un 1 l´ogico, y cuando toma un valor “bajo” (0 voltios en la tecnolog´ıa CMOS) representa un 0 l´ogico.
Aunque todas las se˜nales son interpretadas en los sistemas digitales como 0 y 1 l´ogicos, no es siempre posible modelar y simular los sistemas digitales usando s´olo se˜nales 0 l´ogico y 1 l´ogico. Un motivo es que el valor de algunas se˜nales puede no ser conocido en determinado intervalo de tiempo de la simulaci´on, por ejemplo porque esas se˜nales todav´ıa no hayan sido inicializadas, es decir, no se les haya asignado valor. Por otra parte, una se˜nal puede tener un nivel de voltaje intermedio (que puede ser interpretado como un 0 l´ogico o un 1 l´ogico), por ejemplo debido a que est´a producida por una puerta l´ogica con una salida “d´ebil”. En VHDL se emplean tipos de datos para modelar las se˜nales. Estos tipos de datos pueden ser los est´andar o bien tipos definidos por el usuario. El usuario puede definir sus propios tipos de datos, bien como un subconjunto de tipos de datos est´andar, o bien puede definir sus propios tipos enumerados.
Los tipos m´as comunes en el modelado de se˜nales digitales son bit y std logic. A continuaci´on se describen ambos tipos.
bit y std_logic
Una variable, se˜nal o constante del tipo bit s´olo puede tomar dos valores: 0 y 1 (obs´ervese que los valores se escriben sin comillas). As´ı pues, este tipo es ´util para realizar modelos sencillos de sistemas digitales.
Las variables, se˜nales o constantes del tipo std logic pueden tomar nueve valores. Adem´as de los valores ’0’ y ’1’ (obs´ervese que en este caso los valores se escriben entre comillas simples), pueden tomar otros valores usados para modelar valores intermedios o desconocidos de la se˜nal. De estos valores, los m´as comunes son los tres siguientes:
’U’ El valor de la se˜nal est´a sin inicializar. Es decir, a la se˜nal no se le ha asignado todav´ıa un valor.
’X’ No puede determinarse el valor de la se˜nal, quiz´a debido a un conflicto en las salidas (por ejemplo, una puerta l´ogica intenta poner a ‘0’ la se˜nal mientras otra puerta l´ogica intenta ponerla a ‘1’).
’Z’ Alta impedancia, es decir, la se˜nal ha quedado desco-nectada.
Los restantes posibles valores de una se˜nal del tipo std logic son: ’W’ (des-conocida d´ebil), ’L’ (cero d´ebil), ’H’ (uno d´ebil) y ’-’ (don’t care).
Por lo general, en los modelos mostrados en este texto se emplear´a el tipo std logic para representar las se˜nales binarias.
bit_vector y std_logic_vector
Los conjuntos de se˜nales pueden agruparse formando lo que se denominan buses. An´alogamente, los conjuntos de variables pueden agruparse en vectores. Los buses y vectores pueden modelarse en VHDL mediante los tipos bit vector (un
conjunto de se˜nales o variables de tipo bit) y std logic vector (un conjunto de se˜nales 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 aritm´eticas sobre este tipo de se˜nales. Esto es razonable, ya que en los circuitos digitales no pueden realizarse operaciones aritm´eticas directamente sobre los buses de se˜nales, s´olo pueden realizarse opera-ciones l´ogicas. 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 b´asicos.
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 _ (gui´on bajo) puede usarse como marcador (es ignorado por el compilador de VHDL) con el fin de facilitar la lectura de los n´umeros.
Por ejemplo, las siguientes son tres formas de expresar el n´umero sin signo 29:
B"01_1101" O"35" X"1D" integer Sus literales est´an 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 un punto decimal para separar la parte entera de la parte decimal, y un E (o e) precediendo el valor del exponente. Por ejemplo, a continuaci´on se muestran diferentes for-mas de expresar el n´umero 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 aritm´eticas realizadas sobre buses, pueden usarse los tipos de datos unsigned y signed. Ambos tipos de datos est´an 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