Estructura Y Tecnologia De Computadores 3 - Libro Problemas

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Estructura Y Tecnologia De Computadores 3 - Libro Problemas as PDF for free.

More details

  • Words: 50,758
  • Pages: 176
´ A DISTANCIA (UNED) UNIVERSIDAD NACIONAL DE EDUCACION ´ ´ ESCUELA TECNICA SUPERIOR DE INGENIER´IA INFORMATICA

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

Índice

1 Fundamentos 1.1. 1.2. 1.3. 1.4. 1.5. 1.6.

1

Lenguajes para la descripci´ on de hardware . . . . . . Ciclo de dise˜ no de los circuitos digitales . . . . . . . Propiedades de los circuitos digitales . . . . . . . . . Simulaci´ on de eventos discretos . . . . . . . . . . . . Test de los circuitos . . . . . . . . . . . . . . . . . . Dos simuladores de VHDL’93: VeriBest y ModelSim

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. 1 . 4 . 5 . 8 . 12 . 16

2 Conceptos básicos de VHDL 2.1. Definici´ on de la entidad de dise˜ no . . . . . 2.2. Entity . . . . . . . . . . . . . . . . . . . . 2.3. Architecture . . . . . . . . . . . . . . . . . 2.3.1. Asignaciones concurrentes . . . . . 2.3.2. Bloque process . . . . . . . . . . . 2.3.3. Descripci´ on de la estructura . . . . 2.3.4. Constantes generic . . . . . . . . . 2.4. Configuration . . . . . . . . . . . . . . . . 2.5. Se˜ nales, variables y constantes . . . . . . 2.5.1. Tipos de datos . . . . . . . . . . . 2.5.2. Atributos . . . . . . . . . . . . . . 2.5.3. Operadores . . . . . . . . . . . . . 2.6. Librer´ıas . . . . . . . . . . . . . . . . . . . 2.7. Modelado del retardo . . . . . . . . . . . . 2.7.1. Sentencia wait . . . . . . . . . . . 2.7.2. Retardos en la asignaci´ on a se˜ nales 2.7.3. Retardo inercial y de transporte . 2.7.4. Retardo delta . . . . . . . . . . . . 2.7.5. Caso pr´ actico . . . . . . . . . . . . 2.8. Assert . . . . . . . . . . . . . . . . . . . . 2.9. Procedimientos y funciones . . . . . . . .

19 . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

20 20 21 22 23 24 28 28 28 29 34 35 37 38 38 39 39 40 41 43 44

ii

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

3 Casos prácticos de diseño de circuitos combinacionales 3.1. S´ıntesis de l´ ogica combinacional . . . . . . . . . . . . . 3.1.1. Empleo de sentencias concurrentes . . . . . . . 3.1.2. Empleo de bloques process . . . . . . . . . . . 3.2. Funciones l´ ogicas . . . . . . . . . . . . . . . . . . . . . 3.2.1. Modelado de las funciones l´ ogicas . . . . . . . . 3.2.2. Programaci´ on del banco de pruebas . . . . . . 3.3. Multiplexor de 4 entradas . . . . . . . . . . . . . . . . 3.3.1. Bloque process, sentencia if . . . . . . . . . . . 3.3.2. Bloque process, sentencias if y case . . . . . . . 3.3.3. Sentencias concurrentes . . . . . . . . . . . . . 3.4. Restador completo de 1 bit . . . . . . . . . . . . . . . 3.4.1. Descripci´ on del comportamiento . . . . . . . . 3.4.2. Descripci´ on de la estructura . . . . . . . . . . . 3.4.3. Programaci´ on del banco de pruebas . . . . . . 3.4.4. Banco de pruebas usando un procedimiento . . 3.4.5. Banco de pruebas usando una funci´ on . . . . . 3.5. Sumador binario paralelo con propagaci´ on de arrastre 3.5.1. Dise˜ no de un sumador completo . . . . . . . . 3.5.2. Banco de pruebas de sumador completo . . . . 3.5.3. Dise˜ no del sumador de 4 bits . . . . . . . . . . 3.6. Bus bidireccional y memorias . . . . . . . . . . . . . . 3.6.1. Memoria de s´ olo lectura . . . . . . . . . . . . . 3.6.2. Memoria de lectura y escritura . . . . . . . . . 3.6.3. Bus bidireccional . . . . . . . . . . . . . . . . . 3.7. Unidad aritm´etico l´ ogica (ALU) . . . . . . . . . . . . . 3.7.1. Modelado mediante asignaci´ on concurrente . . 3.7.2. Modelado mediante bloque process . . . . . . . 3.7.3. Programaci´ on del banco de pruebas . . . . . . 3.8. Conversor de BCD a binario . . . . . . . . . . . . . . . 3.8.1. Circuito conversor . . . . . . . . . . . . . . . . 3.8.2. Banco de pruebas . . . . . . . . . . . . . . . . 3.9. Codificador 4:2 con prioridad . . . . . . . . . . . . . . 3.9.1. Dise˜ no del circuito . . . . . . . . . . . . . . . . 3.9.2. Banco de pruebas . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

47 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4 Casos prácticos de diseño de circuitos secuenciales 4.1. Dise˜ no de circuitos secuenciales s´ıncronos . 4.1.1. Circuito detector de secuencias . . . 4.2. S´ıntesis de l´ ogica secuencial . . . . . . . . . 4.2.1. Sentencias condicionales incompletas 4.2.2. Sentencias condicionales completas . 4.2.3. Retardos . . . . . . . . . . . . . . . 4.2.4. Inicializaci´ on . . . . . . . . . . . . . 4.2.5. Bloques process . . . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

47 48 50 50 50 51 54 55 57 59 60 61 62 65 68 70 71 72 75 77 77 78 79 80 82 83 84 85 89 90 91 93 93 94 99

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

99 100 102 102 103 103 103 104

´ Indice

iii

4.3. Flip-flop JK . . . . . . . . . . . . . . . 4.3.1. Dise˜ no del flip-flop . . . . . . . 4.3.2. Banco de pruebas . . . . . . . 4.4. M´ aquinas de estado finito de Moore . 4.4.1. Dise˜ no de la m´ aquina . . . . . 4.4.2. Banco de pruebas . . . . . . . 4.4.3. Modelado estructural . . . . . 4.5. M´ aquinas de estado finito de Mealy . . 4.5.1. Dise˜ no de la m´ aquina . . . . . 4.5.2. Banco de pruebas . . . . . . . 4.6. Descripci´ on VHDL de alto nivel . . . . 4.6.1. Circuito detector de secuencia .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

105 105 106 109 110 113 117 119 119 126 130 130

´ APENDICES

133

A VeriBest VB99.0

133

A.1. Instalaci´ on . . . . . . . . . . . . . . . . . . . . . . A.2. Circuito digital ejemplo: buffer triestado . . . . . . A.2.1. Modelo VHDL del buffer triestado . . . . . A.2.2. Banco de pruebas . . . . . . . . . . . . . . A.3. Edici´ on y compilaci´ on de un modelo . . . . . . . . A.3.1. Arranque del simulador VeriBest VHDL . . A.3.2. Creaci´ on de un espacio de trabajo . . . . . A.3.3. Edici´ on de un fichero . . . . . . . . . . . . . A.3.4. A˜ nadir un fichero al espacio de trabajo . . . A.3.5. Compilaci´ on de un fichero . . . . . . . . . . A.3.6. Banco de pruebas . . . . . . . . . . . . . . A.4. Simulaci´ on y visualizaci´ on de los resultados . . . . A.4.1. Establecer las condiciones de la simulaci´ on A.4.2. Activaci´ on del simulador . . . . . . . . . . . A.4.3. Simulaci´ on y visualizaci´ on de resultados . . A.5. Depurado usando el debugger . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . .

B ModelSim PE Student Edition B.1. Instalaci´ on . . . . . . . . . . . . . . . . . . B.2. Circuito digital ejemplo: buffer triestado . . B.2.1. Modelo VHDL del buffer triestado . B.2.2. Banco de pruebas . . . . . . . . . . B.3. Edici´ on y compilaci´ on de un modelo . . . . B.3.1. Arranque del simulador . . . . . . . B.3.2. Creaci´ on de un proyecto . . . . . . . B.3.3. A˜ nadir ficheros al proyecto . . . . . B.3.4. Compilaci´ on de un fichero . . . . . . B.3.5. Banco de pruebas . . . . . . . . . . B.4. Simulaci´ on y visualizaci´ on de los resultados

133 134 134 135 136 136 136 137 137 138 140 140 140 141 142 144 147

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

147 148 148 149 150 150 151 152 156 157 160

iv

A. Urqu´ıa, C. Mart´ın Villalba

B.4.1. B.4.2. B.4.3. B.4.4.

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Activaci´ on del modo simulaci´ on Visualizaci´ on de los resultados Ejecuci´ on de la simulaci´ on . . . Inserci´ on de puntos de ruptura

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

160 161 162 163

Índice alfabético

167

Bibliografía

169

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 a´rboles 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.

2

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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´ oa 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 especificar 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 obtener 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.

Cap´ıtulo 1

Fundamentos

3

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 hardware. 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 u ´ nicamente describe el dise˜ no de manera estructural, 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 hardware. – 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´ ublico 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

4

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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 simulaci´ 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´ıntesis 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 a´rea 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

Cap´ıtulo 1

5

Fundamentos

             

          

           

                       

                   

                      

           

 !   " !   #$

         

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 afectan 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.

6

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 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 dispositivos 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 simularlo. 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

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 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 a ´rbol de buffers. En la Figura 1.2 se muestra un a´rbol 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 u ´ nicamente a 4 entradas. El uso del a´rbol de buffers tiene un beneficio a˜ nadido: igualar los retardos de las se˜ nales de entrada a todos los m´ odulos, ya que el a´rbol 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 a´rbol 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.

8

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

´ 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 u ´ til 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 3. Se actualiza el reloj de la simulaci´ on al instante de ejecuci´ on del evento.

Cap´ıtulo 1

9

Fundamentos

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 calendario 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 dispositivos 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 suceda 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

y ← s or x2 con retraso 2 ns

(1.1) (1.2)

10

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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 x1 o 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’. on de la asignaci´ on de la puerta OR. – El evento E1 se debe a la ejecuci´ 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

E2 5 ns x2 ← 0

Cap´ıtulo 1

11

Fundamentos

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’

Calendario de eventos

x2

’1’

s

’0’

E3 3 ns y ← 1

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 x2 pasa 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’

Calendario de eventos

x2

’0’

s

’0’

E4 6 ns s ← 1

y

’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

12

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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´ unmente 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.

Cap´ıtulo 1

Fundamentos

13

– 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 u ´ nica 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 entradas 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.

14

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Mediante este procedimiento, un u ´ nico 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 flip-flops, que son flipflops 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, usando programas de test espec´ıficos para cada uno, antes de ser incluidos 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

Cap´ıtulo 1

Fundamentos

15

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 exhaustivamente (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 usando un m´etodo diferente al empleado en el test, y comparar los resultados. 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.

16

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

% &' ( ) &* + , - . ( + / 0 1 ' ) 0 , - 2

34 5 678 64 79: ; <= < 8 >? :8 ? < @: A B < 69: 8 < A ? < 9 < A9

F G HIJK JL JM N N O

UUT

JMQ KJ L KPRM N N O

34 5 678 64 79: ? < 6: C D 8 :5 > 67E = ? < @: A 8 < A4 @9>? : A ? < @ 9 < A9

Figura 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 (denominado 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 combinado 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 instalaci´ on 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 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 u ´ nica 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 u ´ til. 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 funciones. 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

20

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con 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 codificaci´ 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 continuaci´ 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). Ejemplo 2.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 direcci´ 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.

Cap´ıtulo 2

21

Conceptos b´ asicos de VHDL

x0

y0

x0

y0

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;

x0

y0

x1

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 u ´ ltimo 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 comportamiento 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. Ejemplo 2.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 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 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

22

A. Urqu´ıa, C. Mart´ın Villalba

x0

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

y0

x0

x0

y0

x1

architecture not of not is begin y0 <= not x0; end architecture not;

y0

x1

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.

begin end architecture <nombre architecture>;

En el a´rea 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 architecture, 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. Ejemplo 2.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 a <= b; -- Asignaciones concurrentes

Cap´ıtulo 2

23

Conceptos b´ asicos de VHDL

c <= u and v; ... end archEjemplo;

-- a las se~ nales: a, c

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 respecto 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. Ejemplo 2.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.std_logic_1164.all;

24

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 begin if reset_n = ’0’ then q <= ’0’;

-- Proceso activo cuando cambia -- el valor de reset_n o de clk -- Comprueba reset as´ ıncrono

q_n <= ’1’; elsif rising_edge(clk) then q <= d; q_n <= not d; end if;

-- En el flanco de subida del reloj

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 subcircuitos, 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.

Cap´ıtulo 2

25

Conceptos b´ asicos de VHDL

· Asociaci´ on mediante el nombre, tambi´en llamada asignaci´ on expl´ı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

Ejemplo 2.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.

X Y Z [ \] ST SU

WT

V

^_

`_

Figura 2.3: Multiplexor de 2 se˜ nales de 1 bit: a) diagrama; b) implementaci´on.

Como puede observarse en la Figura 2.3b, este circuito multiplexor est´ a compuesto 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 i0, i1 : in s0 : in end entity Mux2_1bit;

std_logic; std_logic; std_logic );

26

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 And2_1 And2_2 Or2_1

: : : :

not1 and2 and2 or2

port port port port

map map map map

( ( ( (

x0 x0 x0 x0

=> => => =>

s0, i0, i1, n2,

y0 x1 x1 x1

=> => => =>

n1); n1, y0 => n2); s0, y0 => n3); 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 a0, a1, a2, a3 b0, b1, b2, b3 s0 end entity Mux2_4bit;

: out

std_logic;

: in : in : in

std_logic; std_logic; std_logic );

architecture Mux2_4bit of Mux2_4bit is

Cap´ıtulo 2

27

Conceptos b´ asicos de VHDL

abcdef

a3 b3

i0 i1

d3

d s0 abcdef

a2 b2

i0 i1

d2

d s0 abcdef

a1 b1

i0 i1

d1

d s0 abcdef

a0 b0

i0 i1

d

d0

s0 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; std_logic ); s0 : in end component Mux2_1bit; begin Mux2_0 Mux2_1

: Mux2_1bit port map ( d => d0, i0 => a0, i1 => b0 , s0 => s0 ); : 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

2.3.4

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Constantes generic

Una propiedad muy relacionada con la modularidad y la jerarqu´ıa es la parametrizaci´ 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 entidades 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 u ´ nica 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

Cap´ıtulo 2

Conceptos b´ asicos de VHDL

29

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 process. – 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 u ´ ltimo 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),

30

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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 u ´ til 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’ ’X’

’Z’

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. 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’). Alta impedancia, es decir, la se˜ nal ha quedado desconectada.

Los restantes posibles valores de una se˜ nal del tipo std logic son: ’W’ (desconocida 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

Cap´ıtulo 2

31

Conceptos b´ asicos de VHDL

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 operaciones 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 formas 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 u ´ til 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

32

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

est´ an definidas las operaciones l´ ogicas, pero no las aritm´eticas, mientras que para los tipos de datos unsigned y signed est´ an definidas las operaciones l´ ogicas y aritm´eticas. Puede cambiarse el tama˜ no (es decir, el n´ umero de bits) de los datos unsigned y signed mediante la funci´ on resize. El par´ ametro size representa el nuevo n´ umero de bits del dato. Tabla 2.2: Funciones para cambio de tama˜ no de unsigned y signed.

Tipo de dato Funci´ on unsigned resize(arg,size) signed resize(arg,size)

real e integer Tambi´en existen tipos de datos est´ andar que no se corresponden necesariamente con se˜ nales en los circuitos f´ısicos. Resultan u ´ tiles 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 programaci´ on. Lo mismo sucede con las operaciones aritm´eticas 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 u ´ tiles, en el proceso de depuraci´ on (debugging) del modelo, para mostrar mensajes que son generados durante la simulaci´ on. 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). Adem´ as, existe una funci´ on est´ andar (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 programaci´ on, un string se define simplemente como un array de caracteres.

Tipos enumerados Adem´ as de los tipos est´ andar de datos descritos anteriormente, es posible definir tipos enumerados de datos. Por ejemplo, supongamos una se˜ nal llamada opcode, que representa el c´ odigo de operaci´ on de un circuito. Suponiendo que s´ olo puede tomar cuatro valores

Cap´ıtulo 2

Conceptos b´ asicos 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 construcci´ on hace el c´ odigo VHDL m´ as sencillo de entender. Sin embargo, esta forma de realizar el modelo no permite especificar expl´ıcitamente el c´ odigo binario correspondiente a cada uno de los c´ odigos de operaci´ on. 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 se˜ nal 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 operaci´ on se emplean tipos para los cuales esa operaci´ on no est´ a expl´ıcitamente permitida. La finalidad de ello es reducir los errores de programaci´ on, si bien tambi´en 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 conversi´ on de tipos est´ an definidas en las librer´ıas est´ andar 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 est´ an: to unsigned Convierte de integer a unsigned Convierte de unsigned a integer to integer Asimismo, la conversi´ on entre tipos cercanos puede realizarse usando funciones cuyo nombre coincide con el nombre de los tipos. Por ejemplo, unsigned(t) convierte una se˜ nal t del tipo std logic vector al tipo unsigned. Tabla 2.3: Funciones para la conversi´on de tipos.

Conversi´ on de: a: Funci´ on std logic vector unsigned unsigned(arg) std logic vector signed signed(arg) std_logic_vector(arg) unsigned std logic vector 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 Obs´ervese en la Tabla 2.3 que en la conversi´ on del tipo integer a los tipos unsigned o signed, es preciso especificar el n´ umero de bits (size) de la se˜ nal del tipo unsigned o signed resultante.

34

A. Urqu´ıa, C. Mart´ın Villalba

2.5.2

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Atributos

Puede considerarse que los atributos son propiedades de los tipos de datos. Existen conjuntos est´ andar de atributos que son soportados para diferentes prop´ ositos. No todos los atributos son soportados para s´ıntesis. En la Tabla 2.4 se muestra un conjunto de atributos est´ andar 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 de s´ıntesis.

Atributo

Significado ’ Indica que el argumento es del tipo ’base Tipo base de ’left Primer (m´ as a la izquierda) valor en ´ ’right Ultimo (m´ as a la derecha) valor en ’low Valor m´ as peque˜ no en ’high Valor m´ as grande en ’range Rango de ´ındices de un vector ’reverse_range Rango de ´ındices del vector, en orden inverso ’length N´ umero de valores en el rango del vector <array>’range(n) Rango de ´ındices en la dimensi´ on n del array <array>’reverse\_range(n) Rango de ´ındices, en la dimensi´ on n del array, en orden inverso <array>’length(n) N´ umero de valores en el rango de la dimensi´on n del array <se~ nal>’stable true mientras no hay cambios en <se~nal> <se~ nal>’event true s´ olo cuando hay un cambio en <se~nal>

El primer atributo, ’, se usa para especificar el tipo de una se˜ nal 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 dimensi´ on (vectores), para arrays de n dimensiones, y para se˜ nales. En la Tabla 2.4 se ha empleado la terminolog´ıa siguiente: un tipo de datos escalar, est´ andar o definido por el usuario. un tipo array unidimensional. <array> un tipo array. <se~ nal> una se˜ nal. n un valor entero.

Cap´ıtulo 2

35

Conceptos b´ asicos de VHDL

Asimismo, existen atributos que resultan u ´ tiles para programar bancos de prueba y que, por tanto, no necesitan ser sintetizados. Un atributo particularmente u ´ til es ’image(se~ nal)

que devuelve un string con el valor del tipo de la se˜ nal <se˜ nal>. Este atributo se usa para convertir el valor de una se˜ nal 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, s´ olo 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 se˜ nal de reloj. Sin embargo, puesto que este predicado es tambi´en cierto cuando la se˜ nal 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 se˜ nal clk. Otro atributo usado frecuentemente es ’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 est´ an resumidos en la Tabla 2.5. En la Tabla 2.6 se muestra el tipo de dato obtenido al realizar operaciones aritm´eticas entre operandos del tipo unsigned, signed, e integer.

Tabla 2.5: Operadores de VHDL’93

Categor´ıa Miscel´ aneos

Operador ** abs not Multiplicaci´ on / Divisi´ on * / mod rem Unitarios (signo) + – Suma / Resta + – & Desplazamiento sll srl sla sra rol ror Relacional = /= < <= > >= L´ ogico and or nand nor xor xnor

Significado Exponenciaci´ on Valor absoluto NOT l´ ogico Multiplicaci´ on Divisi´ on M´ odulo Resto Identidad Negaci´ on (complemento a 2) Suma Resta Concatenaci´ on Desplazamiento l´ ogico izquierda Desplazamiento l´ ogico derecha Desplazamiento aritm´etico izquierda Desplazamiento aritm´etico derecha Rotaci´ on l´ ogica izquierda Rotaci´ on l´ ogica derecha Comprueba igualdad Comprueba desigualdad Menor que Menor o igual que Mayor que Mayor o igual que AND l´ ogica OR l´ ogica NAND l´ ogica NOR l´ ogica OR exclusiva l´ ogica NOR exclusiva l´ ogica

Tabla 2.6: Tipo obtenido como resultado de las operaciones aritm´eticas.

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

2.6

37

Conceptos b´ asicos de VHDL

Librerías En VHDL, una librer´ıa de dise˜ no contiene la definici´ on de un conjunto de tipos de datos, as´ı como la definici´ on de los operadores y funciones que pueden aplicarse sobre estos tipos de datos. Existe un buen n´ umero de librer´ıas de dise˜ no est´ andar y de librer´ıas espec´ıficas, que son proporcionadas junto con las herramientas de simulaci´ on. A excepci´ on de los tipos bit y bit vector, todos los dem´ as tipos precisan de la inclusi´ on de alguna librer´ıa de dise˜ no. 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 sublibrer´ıas denominadas packages. Un beneficio a˜ nadido de ello es que incluir u ´ nicamente los tipos de datos necesarios para el dise˜ no reduce el tama˜ no del c´ odigo y simplifica la simulaci´ on del programa en VHDL. Por este motivo, adem´ as de especificar qu´e librer´ıas deben ser incluidas, conviene que el dise˜ nador indique qu´e paquetes en concreto de la librer´ıa son usados en la definici´ on del circuito. Si no se especifica el paquete, o si un mismo objeto est´ a definido en varios paquetes, es preciso referirse a ´el usando la notaci´ on punto: librer´ıa.paquete.objeto Entre los paquetes m´ as com´ unmente usados, cabe mencionar los siguientes, pertenecientes a la librer´ıa IEEE: IEEE.std logic 1164

IEEE.numeric std

IEEE.math real

Incluye la definici´ on de los tipos de datos std logic y std logic vector, y de las operaciones en las que intervienen estos tipos de datos. Incluye la definici´ on de los tipos de datos unsigned y signed, y de las operaciones m´ as comunes realizadas sobre estos tipos de datos. Incluye la definici´ on de las operaciones en las que intervienen n´ umeros reales (tipo real). Estos son n´ umeros reales en coma flotante de 64 bits seg´ un el est´ andar de IEEE.

As´ı pues, es frecuente incluir, antes de la definici´ on de la entidad de dise˜ no, 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 c´ odigo VHDL que sigue a continuaci´ on. Por supuesto, si

38

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

en el c´ odigo no se usan los tipos de datos unsigned y signed, entonces puede omitirse la tercera sentencia. Las herramientas de simulaci´ on 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 m´ as notables son las dos siguientes: work

std

2.7

Librer´ıa por defecto donde se compilan todos los tipos, las funciones, entity, architecture, package, etc. definidos por el usuario. Contiene la mayor´ıa de las definiciones y construcciones est´ andar soportadas por VHDL.

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 consideraci´ on los retardos que se producen en ellos. Una recomendaci´ on cuando se modelan circuitos digitales es asignar alg´ un retardo (incluso un retardo arbitrario, como 1 ns) a todas las operaciones al nivel de transferencia entre registros usadas en el c´ odigo VHDL que describe el circuito. Obs´ervese, 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 dise˜ nador a poner esos retardos a cero o a eliminarlos del c´ odigo. Los retardos pueden ser modelados mediante varios m´etodos. A continuaci´ on se describen algunos de ellos.

2.7.1

Sentencia wait

El m´etodo m´ as sencillo de modelar un retardo es emplear la sentencia wait, indicando el n´ umero 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 ejecuci´ on 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 ejecuci´ on del bloque.

Cap´ıtulo 2

39

Conceptos b´ asicos de VHDL

Asimismo, las construcciones: wait until ; wait until <lista de se~ nales>;

dentro de un bloque process, detienen la ejecuci´ on del bloque hasta que la condici´ on booleana se haga verdadera, o hasta que alguna de las se˜ nales 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 u ´ nica forma de uso de la sentencia wait permitida para s´ıntesis), entonces es equivalente a nales a las que el bloque process es usar <lista de se~nales> como la lista de se˜ sensible.

2.7.2

Retardos en la asignación a señales

Pueden especificarse retardos en las asignaciones a se˜ nales usando la palabra reservada after. Por ejemplo, puede modelarse el comportamiento de una puerta NAND con un retardo de propagaci´ on de 2 ns mediante la sentencia: y <= x0 nand x1 after 2 ns;

Cuando se encuentra esta sentencia en la simulaci´ on, se emplean los valores actuales de x0 y x1 para calcular el resultado de la operaci´ on 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 se˜ nal y no habr´ a ocurrido en el instante en el cual se ejecute la siguiente sentencia. Para especificar que la simulaci´ on 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 descripci´ on jer´ arquica del circuito, cobran importancia los conceptos de retardo inercial y retardo de transporte. Un dispositivo l´ ogico real tiene la propiedad de que un glitch en un puerto de entrada, con una duraci´ on inferior al retardo de propagaci´ on 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 propagaci´ on de 1 ns, entonces un glitch de 0.5 ns (un 0 o´ 1 temporal, de duraci´ on 0.5 ns) en una de sus entradas no produce ning´ un cambio en su salida.

40

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 asignaci´ on (<=). El modo recomendado de modelar el retardo en el c´ odigo VHDL sintetizable es el retardo inercial.

2.7.4

Retardo delta

Es importante tener en cuenta que todas las operaciones que involucran se˜ nales poseen un retardo, dado que todas las se˜ nales en los circuitos f´ısicos experimentan retardos cuando pasan a trav´es de los dispositivos y las conexiones. En vista de ello, aunque no se especifique de manera expl´ıcita en el c´ odigo VHDL el retardo, todas las se˜ nales son simuladas someti´endolas a un retardo en cada operaci´ on de asignaci´ on o instanciaci´ on de un subcircuito. As´ı pues, cuando se ejecuta una sentencia en la que se asigna un nuevo valor a una se˜ nal, se aplica por defecto un retardo de valor delta. Es decir, un retardo infinitesimal, inferior al incremento de tiempo m´ as peque˜ no que puede ser especificado en VHDL, que es un femtosegundo (1 fs = 10−15 s). Como consecuencia de este m´etodo de retardo delta empleado en la simulaci´ on, cuando se asigna un valor a una se˜ nal en VHDL, hay dos eventos de inter´es: 1. Se calcula el nuevo valor y se planifica el cambio en la se˜ nal. 2. Transcurrido un tiempo delta, se asigna a la se˜ nal su nuevo valor. Este comportamiento no tiene un efecto apreciable para las sentencias de asignaci´ on que est´ an fuera de bloques process, que en cualquier caso se ejecutan concurrentemente. Sin embargo, tiene un efecto importante en las asignaciones a se˜ nales que est´ an dentro de bloques process: 1. Se planifica el cambio en la se˜ nal antes de que se ejecute la siguiente sentencia. 2. El cambio en el valor de la se˜ nal debido a la primera sentencia ocurre despu´es de que se haya planificado el cambio debido a la siguiente sentencia, para lo cual se usan los valores de las se˜ nales en el instante actual. As´ı pues, una cadena de asignaciones a se˜ nales contenida en un bloque process se comporta de manera diferente a un conjunto de sentencias en un lenguaje de programaci´ on. Por ejemplo, suponga el siguiente fragmento de c´ odigo VHDL: process (clk) is begin if rising_edge(clk) then b <= a;

Cap´ıtulo 2

Conceptos b´ asicos de VHDL

41

c <= b; ...

Puesto que b y c son se˜ nales, existe un retardo delta antes de que se produzca la asignaci´ on del nuevo valor a b. Antes de que transcurra este retardo, se calcula el nuevo valor de la variable c, us´ andose para ello el valor “antiguo” de b. En este ejemplo, la se˜ nal c adquiere el valor que ten´ıa la se˜ nal b en el anterior ciclo de reloj, dado que el proceso es activado u ´ nicamente en los flancos de subida de la se˜ nal de reloj. La discusi´ on anterior acerca del retardo delta no aplica a las asignaciones a variables. De hecho, ni siquiera es posible asociar un retardo a una asignaci´ on 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 est´ an ideadas para ser usadas como las variables de los programas de los lenguajes de programaci´ on. As´ı pues, dada una cadena de asignaciones a variables contenida dentro de un bloque process, estas asignaciones a variables se realizan de manera estrictamente 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 continuaci´ on pretende ilustrar los conceptos relacionados con el retardo expuestos en esta secci´ on, as´ı como la diferencia entre las se˜ nales y las variables en lo que respecta al retardo. En primer lugar, se muestra el c´ odigo de una puerta NAND con un retardo inercial del 2 ns, y a continuaci´ on el c´ odigo 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 Pr´ acticos de Dise˜ no 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 var2 s3 s4

:= in1 nand in2; := var1; -- var2 debe ser igual a var1 <= in1 nand in2; <= 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’, ’1’ after 10 ns, ’0’ after 11 ns, ’1’ after 20 ns, ’0’ after 22 ns, ’1’ after 26 ns, ’0’ after 29 ns; end architecture retardo_bp; -------------------------------------------

-- in2 comienza a 0 -- Pulso de 1 ns -- en el instante 10 ns -- Pulso de 2 ns -- en el instante 20 ns -- Pulso en el instante 26 ns

Cap´ıtulo 2

43

Conceptos b´ asicos de VHDL

Las formas de onda obtenidas de la simulaci´ on se muestran en la Figura 2.5. La se˜ nal 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 m´ as corto que el retardo de propagaci´ on de la puerta NAND y de la asignaci´ on a la se˜ nal s2. Por ello, las se˜ nales 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 se˜ nales s1 y s2 no est´ a definido hasta el instante 2 ns. Por ello, estas se˜ nales inicialmente tienen el valor U. Inicialmente, la se˜ nal s3 est´ a 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 se˜ nal 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 l´ ogicas que, dado el valor esperado en ese punto del estado del programa, deber´ıan valer true. Se emplea frecuentemente para depurar el c´ odigo. Su sintaxis es: assert

report <string> severity ;

Mientras la condici´ on booleana es true, la sentencia no realiza ninguna acci´ on. Cuando la condici´ on se hace false, la sentencia muestra el texto <string> en la consola. La clausula severity se usa para indicar qu´e gravedad tiene la violaci´ on de la condici´ on booleana. Posibles valores de son: note warning error failure

No es un error. Aviso. Error. Error severo que hace que termine la simulaci´ on.

44

2.9

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Procedimientos y funciones Dos construcciones que pueden ser u ´ tiles en la descripci´ on de las arquitecturas son los procedimientos (bloques procedure) y las funciones (function), ya que contribuyen a hacer el c´ odigo VHDL m´ as legible, portable y compacto. Las funciones son usadas como operadores en las sentencias de asignaci´ on, mientras que los procedimientos son usandos de forma m´ as 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 secci´ on de declaraci´ on 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 dise˜ nadores manejar peque˜ nos fragmentos de c´ odigo reutilizable. Algunas de sus caracter´ısticas m´ as destacables son las siguientes: – Desde dentro de un procedimiento se puede acceder a todas las se˜ nales, variables y constantes del bloque desde el que es llamado el procedimiento. – Pueden pasarse argumentos (variables o se˜ nales) al procedimiento, que pueden ser in, out e inout. · Puede modificarse en el procedimiento el valor de los argumentos declarados 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 direcci´ on 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 se˜ nal. · Se considera que un argumento in es una constante dentro del bloque del procedimiento. No obstante, si el argumento in es una se˜ nal, entonces los cambios que se produzcan en la se˜ nal fuera del procedimiento se producir´ an igualmente en el valor de la se˜ nal dentro del procedimiento. – Dentro de un procedimiento pueden definirse variables locales, a las que no se puede acceder desde fuera del procedimiento. – A excepci´ on del uso de las variables locales, el efecto de usar un procedimiento es equivalente a reemplazar la llamada al procedimiento por el c´ odigo del procedimiento. Las dos diferencias fundamentales entre los procedimientos y las funciones en VHDL son las siguientes:

Cap´ıtulo 2

Conceptos b´ asicos de VHDL

45

– La funci´ on debe devolver un valor al c´ odigo que la llama. – Los argumentos de la funci´ on deben ser de tipo in, con lo cual no es necesario especificar su direcci´ on. El caso pr´ actico descrito en la Secci´ on 3.4 ilustra el empleo de procedimientos y funciones.

3

Casos prácticos de diseño de circuitos combinacionales

Objetivos. Una vez estudiado el contenido del tema deber´ıa saber: – Dise˜ nar circuitos l´ ogicos combinacionales empleando VHDL, tales como funciones l´ ogicas, multiplexores, sumadores y restadores binarios, buses, ALUs, conversores de c´odigo y decodificadores, describiendo el comportamiento y/o la estructura del circuito. – Dise˜ nar y simular bancos de pruebas para circuitos combinacionales.

3.1

Síntesis de lógica combinacional Cuando el objetivo de la descripci´ on del circuito mediante VHDL es la s´ıntesis, es u ´ til saber c´ omo escribir c´ odigo VHDL para crear determinadas estructuras circuitales. El comportamiento y las salidas de un bloque l´ ogico combinacional dependen u ´ nicamente del valor actual de las entradas. No dependen del valor pasado de las entradas, ni tampoco del estado. As´ı pues, el c´ odigo VHDL que describe un circuito combinacional no debe tener “historia”, ni tampoco debe describir dependencia respecto al estado. Tambi´en, debe evitarse incluir retardos temporales en la descripci´ on VHDL del circuito, ya que los retardos del circuito real ser´ an dependientes del hardware en particular que se emplee para implementar el circuito. Existen varios m´etodos 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 (conexi´ on de las correspondientes puertas l´ ogicas) o describiendo su

48

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

comportamiento, mediante una sentencia concurrente de asignaci´ on a una se˜ nal, tal como: out <= in1 when (sel=’1’) else in0;

A continuaci´ on, se describe un m´etodo para la descripci´ on de circuitos combinacionales que es sencillo de entender, aplicable de manera general y ampliamente usado.

3.1.1

Empleo de sentencias concurrentes

Los circuitos l´ ogicos combinacionales pueden ser descritos empleando sentencias concurrentes de asignaci´ on a se˜ nales. Este tipo de sentencias modelan de manera correcta el comportamiento de los dispositivos combinacionales, que est´ an activos durante todo el tiempo de manera concurrente. – En la parte izquierda de una sentencia de asignaci´ on concurrente debe aparecer, o bien una se˜ nal local de la architecture, o bien una se˜ nal de la interfaz (definida en la entity) del tipo out o inout. – En la parte derecha de la asignaci´ on concurrente pueden aparecer se˜ nales locales de la architecture y tambi´en se˜ nales de la interfaz, del tipo in o inout. Las herramientas de s´ıntesis pueden sintetizar las puertas l´ ogicas simples a partir de las operaciones l´ ogicas primitivas de VHDL. A continuaci´ on, se muestran dos ejemplos: Puerta NAND Puerta OR-exclusiva

nand_out <= i0 nand i1; xor_out

<= i0 xor

i1;

Tambi´en, pueden sintetizarse arrays de puertas l´ ogicas a partir de este mismo 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 u ´ nica puerta l´ ogica o un array de puertas l´ ogicas, depende del tipo de se˜ nales usadas en la sentencia de asignaci´ on concurrente. Por ejemplo, las siguientes sentencias dan lugar a un buffer triestado y a un array de buffers triestado, respectivamente. Buffer triestado Array de buffers triestado

tri_out

<= i0 when (sel=’1’) else ’Z’;

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 est´ an descritos mediante sentencias condicionales del tipo siguiente:

Cap´ıtulo 3

49

Casos pr´ acticos de dise˜ no de circuitos combinacionales

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 tambi´en 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 cl´ ausulas with para describir multiplexores y decodificadores, ya que el empleo de cl´ ausulas condicionales puede dar lugar a la s´ıntesis de circuitos innecesariamente complejos. Esto es debido a que las condiciones de las cl´ ausulas condicionales en general no tienen que ser excluyentes entre s´ı, cosa que s´ı sucede siempre con las condiciones de las cl´ ausulas with. Es posible tambi´en realizar una descripci´ on del circuito basada u ´ nicamente en la operaci´ on 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 conversi´ on de tipo TO INTEGER y unsigned, que est´ an definidas en el package IEEE.numeric std. Finalmente, los circuitos que realizan operaciones aritm´eticas pueden ser descritos aplicando las correspondientes operaciones aritm´eticas 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 multiplicaci´ on. 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 descripci´ on da lugar a la s´ıntesis de los tipos est´ andar de circuitos aritm´eticos. Dependiendo de la opci´ on seleccionada en la s´ıntesis, las unidades aritm´eticas sintetizadas pueden ser circuitos lentos que usan un n´ umero peque˜ no de puertas l´ ogicas (si se escoge la opci´ on “optimizar el a´rea”) o bien circuitos r´ apidos que utilizan gran n´ umero de puertas l´ ogicas (se se escoge la opci´ on “optimizar la velocidad”). Para crear tipos espec´ıficos de unidades aritm´eticas, tales como tipos especiales de sumadores o multiplicadores r´ apidos, puede ser necesario describirlos o bien indicando su estructura, o bien mediante una descripci´ on de su comportamiento a m´ as bajo nivel, tal como se explica a continuaci´ on.

50

A. Urqu´ıa, C. Mart´ın Villalba

3.1.2

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Empleo de bloques process

Aunque las sentencias concurrentes de asignaci´ on a se˜ nal son u ´ tiles para crear estructuras combinacionales simples, es necesario disponer de otro m´etodo para crear circuitos m´ as complejos. En concreto, cierto n´ umero de cl´ ausulas de VHDL (tales como if, case, for, etc.) s´ olo pueden ser usadas dentro de bloques process. Los bloques process pueden ser usados para describir l´ ogica 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 se˜ nales a las que es sensible el bloque process. 2. Ninguna otra se˜ nal 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 se˜ nal. A continuaci´ on, se muestran varios ejemplos sencillos de dise˜ no de circuitos combinacionales, empleando tanto sentencias concurrentes como bloques process.

3.2

Funciones lógicas En esta secci´ on se describe el modelado de dos funciones l´ ogicas y de su banco de pruebas. Las dos funciones l´ ogicas (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 continuaci´ on se muestra el c´ odigo VHDL que describe las funciones l´ ogicas. Obs´ervese que el orden en el cual deben realizarse las operaciones booleanas debe indicarse expl´ıcitamente mediante par´entesis en el c´ odigo VHDL (en caso contrario se obtiene error). Es decir, las funciones l´ ogicas deben escribirse de la forma siguiente: F = ( a and b ) or not c G = ( a and b ) or ( not b and c )

--------------------------------------- Funciones l´ ogicas: -F = ab + c’ -G = ab + b’c

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no 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 l´ ogicas es descrita 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 se˜ nales transmitidas por el cableado de los circuitos. La definici´ on 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 continuaci´ on de la palabra reservada begin) se describe c´ omo 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 programaci´ on cualquier instrucci´ on VHDL disponible (incluso aquellas que dar´ıan lugar a circuitos no sintetizables). Instrucciones u ´ tiles de este tipo son wait, assert y report, que permiten controlar el progreso de la simulaci´ on, comprobar y mostrar sus resultados. En este caso, la finalidad del banco de pruebas es u ´ nicamente 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 dise˜ nador. Es decir, observando las se˜ nales de salida del circuito y comparando con la tabla de la verdad de las funciones l´ ogicas, el dise˜ nador 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 ning´ un puerto.

52

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Internamente, el banco de pruebas tiene conexiones al UUT. Se han definido se˜ nales 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 conexi´ on del UUT en el banco de pruebas se realiza instanciando el UUT como un subcircuito dentro del banco de pruebas. En este caso, la conexi´ on se realiza nombrando expl´ıcitamente los puertos: uut : component funcLog_F_G port map ( F => y0, G => y1, a => x0, b => x1, c => x2 );

Obs´ervese que la se˜ nal y su puerto asociado son incluidos en la lista de par´ ametros 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 continuaci´ on, se muestra el c´ odigo 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 pr´ acticos de dise˜ no de circuitos combinacionales

variable test_in begin test_in := B"000";

53

: unsigned (2 downto 0); -- Vector de test

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 ser´ an ejecutadas secuencialmente. En el c´ odigo 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 sentencias a ejecutar secuencialmente se escriben a continuaci´ on de la palabra begin. Una variable (variable) es conceptualmente diferente a una se˜ nal (signal), puesto que la variable puede no corresponder con una se˜ nal f´ısica. La variable simplemente se usa como ayuda en la descripci´ on de la operaci´ on del circuito. La asignaci´ on a una variable se representa mediante :=, mientras que la asignaci´ on a una se˜ nal se representa mediante <=. En el c´ odigo 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 aritm´eticas. La longitud del vector se especifica por el rango (2 downto 0). El primer n´ umero del rango (2) indica el ´ındice del bit m´ as significativo del vector, y el segundo n´ umero del rango (0) indica el ´ındice del bit menos significativo del vector. La sentencia for en VHDL tiene el formato siguiente: for in loop ... end loop;

donde es una nueva variable temporal, con un rango entero (), que no necesita ser definida previamente.

54

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

La sentencia wait se emplea para esperar durante un n´ umero determinado de unidades de tiempo. En el c´ odigo 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 especific´ o ning´ un retardo. La segunda sentencia wait, que est´ a situada al final de c´ odigo, no tiene ninguna indicaci´ on 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 simulaci´ on 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 selecci´ on (s1, s0) y una salida (d). En esta secci´ on se describen diferentes maneras de modelar el multiplexor, as´ı como bancos de pruebas que permite simular tests sobre los modelos del circuito. ghi jkl

i0 i1 d i2 i3 s0 s1

Figura 3.2: Multiplexor de 4 entradas.

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no de circuitos combinacionales

3.3.1

55

Bloque process, sentencia if

A continuaci´ on, se muestra el c´ odigo VHDL del MUX 4:1 que describe el comportamiento 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 s1, s0 : in end entity mux_4x1;

std_logic; std_logic );

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 d elsif d else

(s1=’0’and s0=’1’) then <= i1; (s1=’1’and s0=’0’) then <= i2;

d <= i3; end if; end process; end architecture mux_4x1; --------------------------------------

Obs´ervese que el bloque process es sensible a las se˜ nales i3, i2, i1, i0, s1, s0. Esto significa que se ejecutar´ a el contenido del bloque cada vez que alguna de estas se˜ nales cambie de valor. A continuaci´ on, se muestra el c´ odigo de un banco de prueba que aplica algunos vectores de test al multiplexor (es s´ olo un peque˜ no 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 Pr´ acticos de Dise˜ no 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 end component mux_4x1;

std_logic );

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 ejecutar´ a cuando cambie el valor de

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no de circuitos combinacionales

57

la variable no incluida en la lista, con lo cual el modelo simulado no reproducir´ a 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 multiplexor, como puede observarse en la Figura 3.3b. Obs´ervese 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 ejecuci´ on 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 continuaci´ on, se muestra el c´ odigo VHDL del MUX 4:1 que describe el comportamiento 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

mn

on

Figura 3.3: Formas de onda obtenidas de simular el banco de pruebas: a) modelo del multiplexor correcto; b) modelo del multiplexor err´oneo.

entity mux_4x1 is port ( d : out std_logic; i3, i2, i1, i0 : in s1, s0 : in end entity mux_4x1;

std_logic; std_logic );

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 pr´ acticos de dise˜ no de circuitos combinacionales

59

d <= i2; when others => d <= i3; end case; end process; end architecture mux_4x1; --------------------------------------

3.3.3

Sentencias concurrentes

A continuaci´ on, se muestra la descripci´ on del circuito multiplexor usando una sentencia concurrente, en la cual se asigna valor a la se˜ nal d en funci´ on 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 s1, s0 : in end entity mux_4x1;

std_logic; std_logic );

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 se˜ nales del tipo integer, a continuaci´ on se muestra una variaci´ on del modelo anterior en el cual se describe el comportamiento del circuito mediante dos sentencias concurrentes. En la primera, se asigna valor a la se˜ nal integer sel en funci´ on del valor de las entradas de selecci´ on. En la segunda, se asigna valor a la salida del circuito en funci´ on de las entradas de datos y del valor de la se˜ nal entera. A continuaci´ on se muestra el c´ odigo.

--------------------------------------- MUX 4x1 library IEEE; use IEEE.std_logic_1164.all;

60

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura 3.4: Formas de onda obtenidas de simular el banco de pruebas, empleando la descripci´ on 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 simulaci´ on.

3.4

Restador completo de 1 bit En esta secci´ on 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 comportamiento y tambi´en mediante su estructura, es decir, indicando c´ omo est´ an conectados los subcircuitos que lo componen. En primer lugar se realizar´ a una descripci´ on del circuito basada en el comportamiento y, a continuaci´ on, se har´ a una descripci´ on basada en su estructura.

Cap´ıtulo 3

61

Casos pr´ acticos de dise˜ no de circuitos combinacionales

3.4.1

Descripción del comportamiento

A continuaci´ on 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 1 1

0 1 0 1

0 1 1 0

0 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 n´ umeros de varios bits. A continuaci´ on, se muestra el c´ odigo VHDL de un restador completo de 1 bit. Obs´ervese que la architecture describe el funcionamiento del circuito, sin entrar en detalles acerca de su implementaci´ on.

------------------------------------------ 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 se˜ nales del tipo std logic y std logic vector para modelar las se˜ nales transmitidas por el cableado de los circuitos f´ısicos.

62

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

La definici´ on de la architecture incluye el nombre de la entity. Se define una se˜ nal del tipo unsigned de 2 bits (llamada result), con el fin de almacenar el resultado de la operaci´ on de sustracci´ on. Al declararla, se indica que la se˜ nal tiene 2 bits, especificando para ello su rango: ( 1 downto 0 ). Si no se especifica el rango, las se˜ nales del tipo unsigned tienen por defecto 32 bits. El tipo de la se˜ nal debe ser unsigned, a fin de permitir el uso del operador sustracci´ on (–). Las se˜ nales 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 se˜ nal de 2 bits del tipo unsigned. Finalmente, el resultado de la resta se asigna a res y acarreo_out. Obs´ervese que es posible realizar las asignaciones: acarreo_out <= result(1); res <= result(0);

porque cada elemento de una se˜ nal del tipo unsigned es del tipo std logic, que es exactamente el tipo de las se˜ nales 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 definici´ on, se emplean puertas OR-exclusiva de 2 entradas (xor2), AND de dos entradas (and2), OR de tres entradas (or3) e inversor (not1). | ~‚ p r pss t u v u z {

t ~ƒ

~… }

~„ x u{v p p q p r pss t u v wx



r

st y

~ ~€

Figura 3.5: Diagrama de un circuito restador completo de 1 bit.

Obs´ervese que, a fin de facilitar la descripci´ on del modelo, se han etiquetado las se˜ nales internas (not a, c, d, e, f) y las puertas l´ ogicas (g0, ..., g6). La definici´ on de la entity y architecture de cada una de estas puertas l´ ogicas se muestra a continuaci´ on.

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no de circuitos combinacionales

--------------------------------------- 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; --------------------------------------

63

64

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 l´ ogicas 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 conexi´ on entre ellos. A continuaci´ on, se muestra el c´ odigo 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; -- Declaraci´ on 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 pr´ acticos de dise˜ no 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 -g0 g1 -g2

Instanciaci´ on y conexi´ on de los componentes : component xor2 port map (c, a, b); : component xor2 port map (res, c, acarreo_in); g2 : component not1 port map (not_a, a); : component not1 port map (y0 => not_a, x0 => a);

g3 : component g4 : component g5 : component g6 : component end architecture

and2 port map (d, not_a, acarreo_in); and2 port map (e, not_a, b); and2 port map (f, b, acarreo_in); or3 port map (acarreo_out, d, e, f); rest_completo_estruc;

-----------------------------------

En el modelo anterior, se realiza la conexi´ on entre los componentes mediante asociaci´ on posicional. Es posible tambi´en usar asignaci´ on 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 c´ odigo del banco de pruebas se comprueban las salidas obtenidas 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 generar´ a el correspondiente mensaje. Se usar´ a la descripci´ on estructural del restador para modelar el UUT, y su descripci´ on del comportamiento para obtener las salidas “correctas”, que se comparar´ an 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 continuaci´ on, se muestra el c´ odigo 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 Pr´ acticos de Dise˜ no 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 : unsigned (2 downto 0); -- Vector de test variable test_in 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 report "ERROR : Esperado (" & 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;

-- Comprueba resultado -- Report del error

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no 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 ning´ un puerto (port): entity bp_rest_completo is end entity bp_rest_completo;

La conexi´ on del UUT en el banco de pruebas se realiza instanciando el restador binario como un subcircuito dentro del banco de pruebas. Aunque la conexi´ on se realiza mediante asociaci´ on posicional, podr´ıa haberse realizado la asociaci´ on 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 se˜ nales internas al banco de pruebas para todas las conexiones al UUT. Aunque en este ejemplo si lo sean, los nombres de las se˜ nales no tienen que ser id´enticos 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 m´etodo empleado para calcular las salidas “esperadas” del UUT debe ser diferente del m´etodo empleado en el propio UUT para obtener las salidas. En este ejemplo, el UUT contiene una descripci´ on estructural de la arquitectura del restador, mientras que las salidas “esperadas” (variable esperado) se calculan a partir de una descripci´ on 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 funci´ on predefinida que devuelve el tiempo simulado como un dato del tipo time. Puede usarse time’image(now) para obtener una representaci´ on del tipo string del tiempo actual de la simulaci´ on. Como resultado de la simulaci´ on 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura 3.6: Formas de onda y mensaje en la consola obtenidos de simular el 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 se˜ nal con el valor obtenido de la simulaci´ on del circuito. Si ambos valores no coinciden, entonces se muestra un mensaje de error y se incrementa el contador del n´ umero de errores. A continuaci´ on, se muestra el c´ odigo del banco de pruebas para el circuito restador completo de 1 bit, programado empleando un procedimiento que realiza la comparaci´ on 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 end entity bp_rest_completo;

-- El banco de pruebas no tiene -- 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

69

Casos pr´ acticos de dise˜ no de circuitos combinacionales

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

3.4.5

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Banco de pruebas usando una función

El c´ odigo anterior del banco de pruebas puede modificarse con el fin de emplear una funci´ on en lugar de un procedimiento. A continuaci´ on, se muestra una posible forma de modificar el c´ odigo. Obs´ervese que se ha sustituido la cl´ ausula if, que compara el valor esperado con el valor actual, por una sentencia assert. El motivo es u ´ nicamente 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 end entity bp_rest_completo;

-- El banco de pruebas no tiene -- 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; if ( esperado /= actual ) then return 1; else return 0; end if; end function error_check; component rest_completo is port ( res, acarreo_out : out std_logic; a, b, acarreo_in : in std_logic);

& & & & & &

-- Opcion severity -- Indica error -- Indica que no hay error

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no 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 de arrastre En esta secci´ on se describe el modelo de un sumador de 4 bits, compuesto a partir de la conexi´ on de cuatro sumadores completos de 1 bit. En primer lugar se realizar´ a el modelo del sumador completo de 1 bit mediante la conexi´ on de puertas l´ ogicas AND, OR y XOR. A continuaci´ on, se usar´ a este modelo de sumador completo para componer el sumador de 4 bits.

72

A. Urqu´ıa, C. Mart´ın Villalba

3.5.1

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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 est´ a descrito por la tabla de la verdad siguiente: ci xi yi ci+1 si 0 0 0 0 1 1 1 1

0 0 1 1 0 0 1 1

0 1 0 1 0 1 0 1

0 0 0 1 0 1 1 1

0 1 1 0 1 0 0 1

Simplificando las funciones l´ ogicas mediante mapas de Karnaugh, se llega a las expresiones siguientes:

ci+1 = xi yi + xi ci + yi ci si = xi ⊕ yi ⊕ ci En la Figura 3.7 se muestra el circuito del sumador completo. ‡† ‰ˆ

 

‹Š

Œ

’‘

”“

‹ Ž Š +

’•

Figura 3.7: Sumador completo.

Las puertas l´ ogicas AND, OR y XOR se modelan con un retardo de 10 ns. A continuaci´ on, se muestran los modelos de las puertas l´ ogicas.

--------------------------------------- AND de 2 entradas con retardo

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no de circuitos combinacionales

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;

73

74

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 definici´ on de la architecture. La definici´ on del package se muestra a continuaci´ on.

------------------------------------ package de componentes -- Puertas l´ ogicas 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 end component xor2;

std_logic );

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 definici´ on 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

75

Casos pr´ acticos de dise˜ no de circuitos combinacionales

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 -- Instanciaci´ on y conexi´ on 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, AND2_2 : component and2 port map (x0 => x, x1 => C_in, AND2_3 : component and2 port map

); );

y0 => n2

);

y0 => n3

);

(x0 => y, x1 => C_in, y0 => n4 ); : component or3 port map (x0 => n2, x1 => n3, x2 => n4, y0 => C_out ); end architecture sum_completo_estruc; ----------------------------------OR3_1

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 dise˜ no´ para el restador de 1 bit. En el banco de pruebas se compara el resultado obtenido de la descripci´ on de la estructura del sumador, con el resultado obtenido de la descripci´ on de su comportamiento. Se muestra un mensaje si ambos resultados no coinciden y se lleva la cuenta del n´ umero de errores, mostrando al final de la simulaci´ on un mensaje con el n´ umero total de errores. A continuaci´ on, se muestra el c´ odigo 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 end entity bp_sum_completo;

-- El banco de pruebas no tiene -- ni entradas ni salidas

76

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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

77

Casos pr´ acticos de dise˜ no de circuitos combinacionales

--------------------------------------------------

En la Figura 3.8 se muestra el resultado de la simulaci´ on del banco de pruebas. Obs´ervese que, debido al retardo de las puertas l´ ogicas, desde el instante inicial hasta el instante 20ns las salidas del sumador toman el valor ’U’ (indefinido). Asimismo, los cambios en las se˜ nales de entrada tardan 20ns en propagarse a las se˜ nales de salida.

Figura 3.8: Simulaci´on 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 propagaci´ on del arrastre. «

Â

­ ¬

ª

š™ ¿ÀÁ

¢¡  

±

œ›

–— ˜

+

Ÿ

¯

®

ž

î

³ ²

°

š™ ¢¡  

·

œ›

–— ˜

+

ž

ÅÄ

¤£

µ

´

¹ ¸



¦¥ ¢¡  

±

¨§

–— ˜

+

¤£

»

º

©£

ƺ

­

¼

¦¥ ¢¡  

¼

œ›

–— ˜

+

ž

É ÇÈ

Ÿ

¾

½

Figura 3.9: Sumador binario paralelo de 4 bits con propagaci´on 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 u ´ nica palabra de N bits. Una de las memorias tiene capacidad de lectura y escritura. La otra s´ olo lectura. Adem´ as 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 continuaci´ on, se describe el modelado mediante VHDL de este sistema.

78

A. Urqu´ıa, C. Mart´ın Villalba

3.6.1

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Memoria de sólo lectura

Los puertos de la memoria son los siguientes: – Se˜ nal de entrada de 1 bit (OE_n). Cuando esta se˜ nal se pone a ’0’, habilita la operaci´ on de lectura de la memoria. Cuando est´ a a ’1’, la operaci´ on de lectura est´ a deshabilitada. – Vector de salida de N bits (data). Contiene el dato almacenado en memoria (palabra de N bits) una vez ejecutada la operaci´ on de lectura. Est´ a a alta impedancia cuando la operaci´ on de lectura est´ a deshabilitada (OE_n = ’1’). A continuaci´ on, se muestra el c´ odigo VHDL que describe la interfaz y el funcionamiento de esta memoria. Se definen dos constantes generic: WORD_SIZE, que contiene el n´ umero de bits de la palabra (N ) y READ_DELAY, que contiene el tiempo de retardo entre que se habilita la se˜ nal de lectura hasta que el dato est´ a disponible.

-------------------------------------------- Fuente de datos unidireccional (lectura) library IEEE; use IEEE.std_logic_1164.all; entity fuenteUnidireccional is generic ( WORD_SIZE : integer READ_DELAY :

time

:= 8; := 10 ns);

-----

Bits por palabra, por defecto 8 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

79

Casos pr´ acticos de dise˜ no de circuitos combinacionales

data <= ( 0 => ’1’, others => ’0’ ) after READ_DELAY;

indica que debe asignarse al vector de se˜ nales data, una vez transcurrido el retardo de tiempo READ_DELAY, una palabra del tama˜ no 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 operaci´ on de lectura. An´ alogamente, la sentencia data <= (others => ’Z’);

asigna al vector de se˜ nales data una palabra, con el mismo n´ umero 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: – Se˜ nal de entrada de 1 bit (OE_n). Cuando esta se˜ nal se pone a ’0’, habilita la operaci´ on de lectura de la memoria. Cuando est´ a a ’1’, la operaci´ on de lectura est´ a deshabilitada. – Se˜ nal de entrada de 1 bit (WE_n). Cuando esta se˜ nal se pone a ’0’, habilita la operaci´ on de escritura en la memoria. Cuando est´ a a ’1’, la operaci´ on de escritura est´ a 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 READ_DELAY :

time

:= 8; := 10 ns;

-- Bits por palabra, -- por defecto 8 bits -- 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; WE_n : in std_logic ); end entity fuenteBidireccional;

-- Habilita lectura -- Habilita escritura

architecture fuenteBidireccional of fuenteBidireccional is

80

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 continuaci´ on, se muestra el c´ odigo 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 tama˜ no de la palabra, que pasa a ser 16 bits, y a los retardos: – Memoria de s´ olo 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 se˜ nales OE1_n, OE2_n y WE_n, es decir, inicialmente se encuentras deshabilitadas las operaciones de lectura y escritura en las memorias. Tambi´en, en el instante inicial, se asigna el valor 0x0fc3 a la se˜ nal 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 operaci´ on de escritura, para ello se pone a ’0’ la se˜ nal 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 operaci´ on de escritura, poniendo la se˜ nal WE_n al valor ’1’. Se habilita la operaci´ on de lectura de la memoria de s´ olo lectura, para lo cual se pone la se˜ nal OE2_n a ’0’. A consecuencia de ello, el valor 0x0001 est´ a disponible en el bus en el instante tiempo = 220 ns. 4. tiempo = 300 ns. Se deshabilita la lectura de la memoria de s´ olo lectura, para lo cual se pone la se˜ nal OE2_n a ’1’. Finalmente, se habilita la lectura

Cap´ıtulo 3

81

Casos pr´ acticos de dise˜ no de circuitos combinacionales

de la memoria de lectura y escritura, para lo cual se pone la se˜ nal OE1_n a ’0’. A consecuencia de ello, en el instante tiempo = 330 ns el valor 0x0fc3 est´ a disponible en el bus. A continuaci´ on, se muestra el c´ odigo VHDL que describe las operaciones realizadas sobre las memorias mediante el empleo del bus.

------------------------------------------------ Conexi´ on 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 constant PERIOD end entity tb_bus;

: :

integer time

:= 16; := 100 ns;

-- Bits por palabra -- Periodo ciclo reloj

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 s´ olo 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; WE_n : in std_logic ); end component fuenteBidireccional;

-- Habilita lectura -- Habilita escritura

component fuenteUnidireccional is generic ( WORD_SIZE : READ_DELAY :

integer time

:= 8; := 10 ns);

-- Bits por palabra -- 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); end component fuenteUnidireccional; begin

-- Habilita lectura

82

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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’; wait for PERIOD; WE_n <= ’1’; OE2_n <= ’0’; wait for PERIOD; OE2_n <= ’1’; OE1_n <= ’0’;

-- Habilita escritura (se escribe 0x0fc3) -- Deshabilita escritura -- Habilita lectura desde la fuente unidireccional -- El dato en el bus debe ser 0x0001 -- Deshabilita lectura de la fuente unidireccional -- 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 simulaci´ on.

Figura 3.10: Formas de onda obtenidas de simular el circuito.

3.7

Unidad aritmético lógica (ALU) Una unidad aritm´etico l´ ogica (ALU) es un circuito que, dependiendo del valor de sus entradas de selecci´ on de funci´ on, realiza una operaci´ on l´ ogica o aritm´etica, de entre un conjunto de operaciones posibles, sobre uno o dos operandos.

Cap´ıtulo 3

Casos pr´ acticos de dise˜ no de circuitos combinacionales

83

Este tipo de circuito puede ser descrito mediante una asignaci´ on concurrente a una se˜ nal, 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 se˜ nales de entrada al circuito combinacional sean incluidas en la lista de variables a las que es sensible el bloque process. A continuaci´ on, se muestran dos posibles formas de modelar una ALU: la primera usando una asignaci´ on concurrente y la segunda usando un bloque process. 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 funci´ on del valor de la entrada de selecci´ on de funci´ on de 3 bits mode. mode Operaci´ on 000 A∗2 001 A+B 010 A−B 011 −A 1 0 0 A and B 101 A or B 1 1 0 A xor B 111 not A

Descripci´ on Multiplicar por 2 (equivale a desplazamiento a la izqda) Suma Resta Complemento a dos AND l´ ogico OR l´ ogico XOR l´ ogico 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 continuaci´ on se muestra un package con las las constantes que definen el tama˜ no de palabra de los operandos y el tama˜ no de la palabra de selecci´on de la operaci´ on.

----------------------------------------------- Definici´ on de constantes globales de la ALU package ALU_CONSTANTS is constant WIDTH : integer := 16; -- N´ um. bits de los operandos constant SEL_BITS

:

integer := 3; -- N´ um. bits selecci´ on de operaci´ on end package ALU_CONSTANTS; ----------------------------------------------

A continuaci´ on, se muestra el c´ odigo que define el comportamiento de la ALU mediante una u ´ nica sentencia de asignaci´ on concurrente a una se˜ nal.

84

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 A, B : in mode : in end entity ALU;

std_logic_vector (WIDTH-1 downto 0); std_logic_vector (WIDTH-1 downto 0); std_logic_vector (SEL_BITS-1 downto 0) );

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 else else else else

std_logic_vector (signed(A)-signed(B)) when (mode="010") std_logic_vector (-signed(A) ) when (mode="011") A and B when (mode="100") A or B when (mode="101") 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 tambi´en puede ser descrito empleando un bloque process sensible a tres se˜ nales: los dos operandos y la se˜ nal de selecci´ on de la operaci´ on.

----------------------------------------------- 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 pr´ acticos de dise˜ no de circuitos combinacionales

begin case mode is when "000" when when when when when

"001" "010" "011" "100" "101"

85

=> C <= std_logic_vector(signed(A)+signed(A)); => => => => =>

C C C C C

<= <= <= <= <=

std_logic_vector(signed(A)+signed(B)); std_logic_vector(signed(A)-signed(B)); std_logic_vector(-signed(A)); A and B; 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 est´ a t´ıpicamente formado por las tres partes siguientes: el dispositivo que va a ser probado (UUT), el c´ odigo para la generaci´ on de los vectores de test y el c´ odigo para comprobar los resultados del test. A´ un 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 pr´ actica esta t´ecnica 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+4 para 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 m´ aximo 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”, m´ as 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

----------------------------------------------- Definici´ on 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 continuaci´ on se muestra el c´ odigo 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 signal mode

downto 0);

: std_logic_vector (SEL_BITS-1 downto 0);

component ALU is port ( C : out A, B : in mode : in end component ALU;

std_logic_vector (WIDTH-1 std_logic_vector (WIDTH-1

downto 0); downto 0);

std_logic_vector (SEL_BITS-1 downto 0) );

-- 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 pr´ acticos de dise˜ no de circuitos combinacionales

87

variable expected_C : integer; begin case k is when when when when when

0 1 2 3 4

when 5

=> => => => =>

expected_C expected_C expected_C expected_C expected_C

:= := := := :=

i*2; i+j; i-j; -i; TO_INTEGER(signed(

std_logic_vector(TO_SIGNED(i,WIDTH)) and std_logic_vector(TO_SIGNED(j,WIDTH)) )); => 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 definici´ on 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

report "Comienza la simulaci´ on"; -- Vectores de test: operandos con valor pr´ oximo 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 pr´ oximo 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 pr´ oximo al m´ aximo 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 pr´ acticos de dise˜ no 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 simulaci´ on: 0 errores"; else report "Finaliza la simulaci´ on: " & integer’image(error_count) & "errores"; end if; wait; -- Termina la simulaci´ on end process main; end architecture TB_ALU; ----------------------------------------------

3.8

Conversor de BCD a binario En los circuitos l´ ogicos digitales se emplean diferentes c´ odigos binarios. En ocasiones, dos circuitos que usan diferente c´ odigo necesitan comunicarse entre s´ı, siendo preciso emplear otro circuito para realizar la conversi´ on de un c´ odigo a otro. Como ejemplo de este tipo de circuitos conversores de c´ odigo, en esta secci´ on de describir´ a el dise˜ no de un conversor para n´ umeros en c´ odigo BCD de longitud fija a c´ odigo binario. En el c´ odigo BCD (binary-coded decimal), cada grupo de cuatro bits consecutivos es convertido a un d´ıgito decimal. El n´ umero completo es interpretado como un n´ umero 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 u ´ ltimos cuatro bits (1001) corresponden a un 9 decimal. El equivalente binario al n´ umero 5910 es 0011 10112 . El circuito descrito en esta secci´ on deber´ıa realizar la conversi´ on de 0101 1001BCD a 0011 10112 . Existen varios algoritmos de conversi´ on de c´ odigo BCD a binario, los cuales t´ıpicamente requieren la realizaci´ on de una secuencia de operaciones sobre el n´ umero BCD de entrada, que aparentemente deber´ıan ser implementadas usando un circuito secuencial. Sin embargo, el algoritmo descrito a continuaci´ on puede

90

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

ser transformado en una secuencia de puertas l´ ogicas, y por tanto puede ser implementado usando un circuito combinacional. Paso 1. Paso 2. Paso 2a. Paso 2b.

Paso 3.

3.8.1

bcd <- bcd_data_input; bin <- 0 (mismo n´ umero de bits que bcd) For count <- 1 to bcd_bit_size do begin {bcd,bin} <- {bcd,bin} >> 1; 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 bin contiene el n´ umero convertido

Circuito conversor

La constante global que almacena el n´ umero de bits del n´ umero en BCD, se declara en un package, que ser´ a usado desde la descripci´ on del circuito y desde la descripci´ on del banco de pruebas. ------------------------------------------- Definici´ on de constantes globales package BCD_CONST is constant LENGTH : integer := 16; -- Longitud (# bits) del n´ umero BCD end package BCD_CONST; ------------------------------------------

A continuaci´ on se muestra la descripci´ on de un circuito que ejecuta el algoritmo de conversi´ on 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 pr´ acticos de dise˜ no 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; --------------------------------------

Obs´ervese que un bloque process puede dar lugar a un circuito combinacional si en la lista de se˜ nales 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 se˜ nales de entrada cambia, este c´ odigo representa un circuito combinacional. Igualmente, un bucle for no implica necesariamente que el circuito sintetizado deba ser secuencial. En este caso, el bucle for u ´ nicamente representa la interconexi´ on de puertas l´ ogicas combinacionales.

3.8.2

Banco de pruebas

A continuaci´ on se muestra el c´ odigo del banco de pruebas del circuito conversor. Para probar el circuito, se generan todos los posibles n´ umeros en BCD con LENGTH bits. En este caso, todos los posibles n´ umeros de 16 bits. Puesto que un n´ umero BCD de 16 bits puede representar cualquier n´ umero entero comprendido entre 0 y 999910 , ese ser´ a el rango de n´ umeros 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 m´ aximo 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 Pr´ acticos de Dise˜ no 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 -- Declaraci´ on 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 : unsigned (LENGTH-1 downto 0); variable temp 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; -- N´ umero de errores begin report "Comienza la simulaci´ on."; -- 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 pr´ acticos de dise˜ no de circuitos combinacionales

93

wait for DELAY; -- Informe final if (error_count = 0) then on finalizada sin errores"; report "Simulaci´ else report "ERROR: Hay " & integer’image(error_count) & " errores."; end if; wait; -- Final de la simulaci´ on 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 funci´ on inversa a un decodificador). Este circuito, que tiene 2N entradas y N salidas, presenta en la salida el c´ odigo binario correspondiente a la entrada activada. El codificador no funciona correctamente si en un determinado instante se produce m´ as de una entrada al circuito. En aquellos casos en que deba contemplarse esta situaci´ on, se emplean circuitos codificadores con prioridad, en los cuales queda definido qu´e 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. Obs´ervese que cuando no hay ninguna entrada, la salida del codificador no es v´ alida.

3.9.1

Diseño del circuito

A continuaci´ on, se muestra el c´ odigo 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 Pr´ acticos de Dise˜ no 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 v´ alida else valida <= ’0’; end if;

-- Salida no v´ alida, puesto que no hay entrada

if

(i3=’1’) then

codificada <= "11";

elsif (i2=’1’) then elsif (i1=’1’) then else end if;

codificada <= "10"; codificada <= "01"; codificada <= "00";

end process; end architecture codificador_4_2_prioridad; -------------------------------------------

Obs´ervese que el bloque process es activado cuando cambia cualquiera de las entradas, ya que el bloque es sensible a estas cuatro se˜ nales. Se emplean sentencias if-elsif para inspeccionar de manera priorizada las entradas.

3.9.2

Banco de pruebas

A continuaci´ on, se muestra el c´ odigo 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 pr´ acticos de dise˜ no de circuitos combinacionales

signal valida signal codificada -- Entradas UUT

: std_logic; : std_logic_vector(1 downto 0);

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 alculos variable temp : unsigned (3 downto 0); -- Usado en los c´ variable esperado_valida : std_logic; variable esperado_codificada : std_logic_vector(1 downto 0); variable error_count : integer := 0; begin report "Comienza la simulaci´ on"; -- 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 end if; end if;

esperado_codificada := "11";

wait for DELAY; -- Espera y compara con las salidas de UUT if ( esperado_valida /= valida ) then

95

96

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 n´ umero total de errores if (error_count = 0) then report "Simulaci´ on finalizada sin errores"; else report "ERROR: Hay " & integer’image(error_count) & " errores."; end if; wait;

-- Final de la simulaci´ on

end process main; end architecture bp_codificador_4_2; -----------------------------------------------------

La ejecuci´ on del banco de pruebas indica que no hay ning´ un error en el circuito. En la Figura 3.11 se muestra el resultado de la simulaci´ on.

Figura 3.11: Formas de onda obtenidas de simular el banco de pruebas.

4

Casos prácticos de diseño de circuitos secuenciales

Objetivos. Una vez estudiado el contenido del tema deber´ıa saber: – Dise˜ nar en VHDL m´aquinas de estado finito de Moore y de Mealy sintetizables, realizando el dise˜ no en base a la descripci´ on de su estructura y/o comportamiento. – Dise˜ nar y programar en VHDL bancos de pruebas de circuitos secuenciales.

Muchos problemas de dise˜ no pueden ser resueltos usando m´ aquinas de estado finito. Una m´ aquina de estado finito consiste esencialmente en un conjunto de estados (codificados usando flip-flops) y transiciones entre estos estados, gobernadas por un conjunto de bits de condici´ on. Es esta secci´ on trataremos algunos aspectos del dise˜ no de m´ aquinas de estado finito de Moore y de Mealy usando VHDL. – M´ aquina de Moore. Una m´ aquina de estado finito de Moore (o simplemente, “m´ aquina de Moore”) es una m´ aquina de estado en la cual las salidas del circuito dependen del estado actual y no del valor actual de las entradas. – M´ aquina de Mealy. Las salidas de una m´ aquina de Mealy dependen del estado actual y tambi´en del valor actual de las entradas. Ambos tipos de m´ aquina pueden ser dise˜ nados de manera sistem´ atica usando un m´etodo de dise˜ no de m´ aquinas de estado finito descrito en la siguiente secci´on.

4.1

Diseño de circuitos secuenciales síncronos Las m´ aquinas de Moore y Mealy pueden ser dise˜ nadas de manera sistem´ atica siguiendo los pasos descritos a continuaci´ on:

100

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 transici´ on del estado usando el diagrama dibujado en el Paso 1 y la codificaci´on de los estados del Paso 2. 4. Formular, a partir de la tabla de transici´ on del estado del Paso 3, las funciones l´ ogicas simplificadas para el nuevo estado y las salidas. 5. Dise˜ nar el circuito empleando un flip-flop por cada variable de estado, y l´ ogica combinacional para las funciones de transici´ on del estado y de salida obtenidas en el Paso 4.

4.1.1

Circuito detector de secuencias

El m´etodo anterior puede aplicarse al dise˜ no de un circuito que detecte la secuencia 101. El circuito tiene una u ´ nica entrada, por la que recibe bits en serie, y una u ´ nica 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 tambi´en deben detectarse las secuencias cuando se encuentran solapadas, por ejemplo: 10101 El primer paso del dise˜ no 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 transici´ on para el circuito detector de la secuencia 101. ÊË Ê

s0 ÊË Ê

s2

ÌÍ Î ÌÍ Î

s1

ÊË Ê ÏË Ï

Figura 4.1: Diagrama de estados del circuito detector de la secuencia 101.

Cada estado del diagrama “recuerda” una porci´ on de la secuencia 101. Las transiciones entre los estados est´ an etiquetadas x/y, donde x corresponde con el valor de la entrada que produce la transici´ on, e y corresponde con el valor de la variable de salida dado el estado en el que empieza la transici´ on 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 m´ aquina de Mealy. En este tipo de diagrama debe tenerse en cuenta que debe escribirse una transici´ on desde cada estado por cada posible valor que puede tomar la entrada en ese estado.

Cap´ıtulo 4

101

Casos pr´ acticos de dise˜ no de circuitos secuenciales

El segundo paso del m´etodo de dise˜ no consiste en codificar los estados. Puesto que hay tres estados, son necesarias dos variables de estado: A y B. Por simplicidad en la exposici´ on, realizaremos una codificaci´ on binaria de los estados: Estado A B S0 S1 S2

0 0 1

0 1 0

En general, unas codificaciones de los estados conducen a circuitos m´ as sencillos que otras, aunque las diferencias t´ıpicamente no son muy grandes. El tercer paso del m´etodo de dise˜ no consiste en escribir la tabla de transici´ on de estados y salidas. Esto puede hacerse de manera sencilla a partir del diagrama de transici´ on de estados mostrado en la Figura 4.1 y de la tabla anterior de codificaci´ on de los estados. La tabla de transici´ on de estados y salidas es la siguiente: oximo estado Salida Estado actual Entrada Pr´ A B x NA NB y S0 : S0 : S1 : S1 : S2 : S2 :

0 0 0 0 1 1

0 0 1 1 0 0

0 1 0 1 0 1

S0 : S1 : S2 : S1 : S0 : S1 :

0 0 1 0 0 0

0 1 0 1 0 1

0 0 0 0 0 1

El cuarto paso consiste en obtener las funciones l´ ogicas simplificadas que relacionan el pr´ oximo estado y la salida con el estado actual y la entrada. Estas funciones son:

NA = x B

(4.1)

NB = x

(4.2)

y=xA

(4.3)

Finalmente, el quinto paso consiste en sintetizar el circuito secuencial s´ıncrono que implemente las funciones l´ ogicas anteriores. Si se usan flip-flops D, las entradas al flip-flop corresponden con el nuevo estado (DA = N A, DB = N B), 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 Pr´ acticos de Dise˜ no 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 l´ ogica 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 u ´ nicamente cuando su entrada enable est´ a a un determinado nivel (’0’ o´ ’1’). A continuaci´ on, 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

Obs´ervese que el latch se define empleando una cl´ ausula 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 cl´ ausula se satisface.

Cap´ıtulo 4

Casos pr´ acticos de dise˜ no 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 se˜ nales en este caso (ya que en la pr´ actica nunca se producir´ a). Si no deseamos que el circuito se sintetice mediante un latch, debemos incluir el caso else en la sentencia condicional y asignar a las se˜ nales 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 l´ ogica 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 r´ apidas y ocupan relativamente poco a´rea.

4.2.3

Retardos

En la Secci´ on 3.1 se explic´ o que en la descripci´ on para s´ıntesis de los circuitos combinacionales debe evitarse el uso de retardos. Lo mismo aplica a la descripci´ on de circuitos secuenciales. Los retardos en el hardware son dependientes de la tecnolog´ıa empleada en su fabricaci´ on y est´ an sujetos a la variabilidad del proceso de fabricaci´ on, 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. Igualmente, no es posible sintetizar sentencias que empleen la cl´ ausula 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 c´ odigo constant DEL : time := 1 ns;

y usar este retardo en el c´ odigo del circuito. Por ejemplo: A <= B after DEL; Puede asignarse un valor positivo a esta constante de retardo para realizar la simulaci´ on del circuito y posteriormente asignarle el valor cero cuando vaya a realizarse la s´ıntesis. Obs´ervese que esta discusi´ on 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 se˜ nales al declararlas, ya que este tipo de inicializaci´ on no puede ser sintetizada.

104

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

La inicializaci´ on de una variable o se˜ nal implica una acci´ on que se realiza u ´ nicamente una vez al comienzo de la simulaci´ on. Si es preciso realizar una acci´ on al comienzo de la simulaci´ on, entonces debe situarse en la secuencia de acciones que se ejecutan cuando se activa la se˜ nal de reset. Estas acciones se definen t´ıpicamente dentro de un bloque process sensible a la se˜ nal de reset.

4.2.5

Bloques process

La descripci´ on de la architecture de los circuitos secuenciales se basa fundamentalmente en el empleo de bloques process. Las asignaciones a se˜ nales dentro de los bloques process deben cumplir que: – La se˜ nal en la parte izquierda de la asignaci´ on concurrente debe ser una se˜ nal definida dentro del bloque process, o una se˜ nal out o inout de la interfaz del circuito. – Las se˜ nales en la parte derecha de la asignaci´ on concurrente deben ser se˜ nales definidas dentro del bloque process, o se˜ nales in o inout de la interfaz del circuito. – No se debe asignar valor a una determinada se˜ nal dentro de m´ as de un bloque process. Es decir, cada se˜ nal debe ser evaluada en un u ´ nico bloque process. Aunque VHDL no impide que se asigne valor a una misma se˜ nal en varios bloques process, esta pr´ actica 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 asignaci´ on a se˜ nal (usan el operador <=) y sentencias de asignaci´ on a variable (usan el operador :=). Las asignaciones a variable tienen efecto inmediatamente, mientras que las asignaciones a se˜ nal 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 asignaci´ on empleando la cl´ ausula 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 controlar cu´ ando 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 se˜ nales que componen la lista. Obs´ervese que es posible controlar la ejecuci´ on del bloque process mediante la lista de sensibilidad y tambi´en mediante el empleo de cl´ ausulas wait dentro del cuerpo el bloque process. Sin embargo, no es recomendable emplear este segundo m´etodo (uso de cl´ ausulas 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 simulaci´ on es muy ineficiente. Por este motivo, es recomendable que todo bloque process tenga su lista de sensibilidad.

Cap´ıtulo 4

4.3

105

Casos pr´ acticos de dise˜ no de circuitos secuenciales

Flip-flop JK En esta secci´ on se describe el dise˜ no 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 u ´ nicamente las entradas J (entrada set), K (entrada reset), el estado actual (Qt ) y el siguiente estado Qt+1 es la mostrada a continuaci´ on. Las transiciones de estado se producen en el flanco de subida del reloj.

J (set) K (reset) 0 0 0 1 1 0 1 1

Nuevo estado Qt+1 = Qt Qt+1 = 0 Qt+1 = 1 Qt+1 = not Qt ÑÐ

ÐÑ

0

ÓÒ ÒÓ

1

Figura 4.3: Transici´on de estados de un flip-flop JK. En los arcos del diagrama se muestra el valor de las se˜ nales JK. El bit ’X’ es“don’t care”(por ejemplo, “0X” representa “00” o´ “01”). La transici´on de reset se representa mediante 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 transici´ on al estado ’0’ se produce en el instante en que cambia la se˜ nal de reset, con independencia del valor de la se˜ nal de reloj. La transici´ on 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 continuaci´ on, se muestra el c´ odigo VHDL del flip-flop JK con reset as´ıncrono activado al nivel LOW. La architecture contiene un bloque process que es sensible a la se˜ nal de reset y a la se˜ nal de reloj. En el cuerpo del bloque process se examina primero la se˜ nal de reset, ya que en caso de estar activa esa se˜ nal (con valor ’0’) la m´ aquina 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

entity flipflop_JK is port ( q, q_n

: out std_logic;

clk, J, K, reset_n end entity flipflop_JK;

: in std_logic );

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" when "10" when "11" when others

=> => => =>

q_interna <= ’0’; q_interna <= ’1’; q_interna <= not q_interna; 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 transici´ on. 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 recorrer´ a los arcos (n´ umero inscrito en una circunferencia), y qu´e valores de las entradas se aplicar´ a en cada caso para producir la transici´ on. 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

107

Casos pr´ acticos de dise˜ no de circuitos secuenciales

Ø ÔÔ Ù ÕÖ

Û ÕÖ ß ××

0

à

Ý ÔÔ Þ ÖÕ

Ú ÖÕ Ü ××

1

Figura 4.4: Orden en que el programa de test recorre los arcos del diagrama de transiciones.

Obs´ervese que la sentencia wait que hay al final del bloque process finaliza la ejecuci´ on de dicho bloque, pero no la simulaci´ on, ya que la simulaci´ on de las sentencias de asignaci´ on concurrente a las se˜ nales de reset y reloj se realiza indefinidamente. Por tanto, la simulaci´ on del banco de pruebas no finaliza por s´ı misma, siendo preciso fijar su duraci´ on: 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 signal signal signal

PERIODO q, q_n clk J, K, reset_n

: : : :

time := 100 ns; -- Reloj std_logic; -- Salidas UUT std_logic := ’0’; -- Entradas UUT std_logic;

component flipflop_JK is port ( q, q_n clk, J, K, reset_n end component flipflop_JK;

: out std_logic; : in std_logic );

-- 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 Pr´ acticos de Dise˜ no 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; -- N´ um. errores begin report "Comienza la simulaci´ on"; -- Vectores de test y comprobaci´ on 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); wait for PERIODO; -- 4 J <= ’0’; K <= ’1’; 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 pr´ acticos de dise˜ no 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); wait for PERIODO; -- 8 J <= ’1’; K <= ’1’; 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 "Simulaci´ on 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 -- asignaci´ on concurrente, esta sentencia -- wait no finaliza la simulaci´ on end process gen_vec_test; end architecture bp_flipflopJK; --------------------------------------

La simulaci´ on del banco de pruebas se realiza con cero errores. En la Figura 4.5 se muestra el resultado obtenido de la simulaci´ on.

Figura 4.5: Resultado de la ejecuci´on del banco de pruebas del flip-flop JK.

4.4

Máquinas de estado finito de Moore Hay varias maneras de escribir c´ odigo VHDL para una m´ aquina 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

del circuito, ya que este tipo de descripci´ on suele ser menos propensa a errores y las herramientas de s´ıntesis convertir´ an estos dise˜ nos en implementaciones optimizadas. En la Figura 4.6 se muestra una m´ aquina de Moore sencilla. La transici´ on 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 dem´ as estados. Este c´ odigo puede ser adaptado f´ acilmente para la descripci´ on de otras m´ aquinas de Moore.

1 Sá/ 0

1 Sã / 0

0

1 Sâ /1

0 0

Figura 4.6: Maquina de estado finito de Moore.

4.4.1

Diseño de la máquina

A continuaci´ on se muestra el c´ odigo VHDL que describe la m´ aquina de Moore mostrada en la Figura 4.6. En primer lugar, se define un package con las constantes que ser´ an 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 c´ odigo. -------------------------------------------------------- Paquete con la definici´ on 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 c´ odigo VHDL que describe el comportamiento de la m´ aquina de estado finito mostrada en la Figura 4.6 es el siguiente. ------------------------------------------------------- M´ aquina de Moore library IEEE;

Cap´ıtulo 4

Casos pr´ acticos de dise˜ no de circuitos secuenciales

use IEEE.std_logic_1164.all; use work.STATE_CONSTANTS.all; -- Definici´ on 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 m´ aquina 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; -- Definici´ on 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 when S1 when S2 when others end case;

=> => => =>

z z z z

<= <= <= <=

’0’; ’0’; ’1’; ’X’;

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 => if (x = ’0’) then

-- Estado actual: S1

111

112

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 c´ odigo anterior, puede observarse que: – La interfaz del circuito est´ a compuesta por dos puertos de salida (la salida y el estado actual) y tres puertos de entrada (se˜ nal de reset as´ıncrono, reloj y entrada). Cuando la se˜ nal de reset (reset_n) pasa de valer 1 a valer 0, entonces la m´ aquina pasa al estado S0 . – Se ha definido una se˜ nal interna a la architecture, llamada internal_state, que almacena el estado actual en que se encuentra la m´ aquina. Cabe preguntarse por qu´e no se usa directamente la se˜ nal state, ya que ambas se˜ nales 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 se˜ nal de salida de la interfaz, no puede ser le´ıda en el cuerpo de la architecture. Puesto que internal_state es una se˜ nal 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 se˜ nal de salida, z. 2. El segundo, que es activado cuando cambia la se˜ nal de reset as´ıncrono (reset_n) o el reloj (clk), describe los cambios en el estado de la m´ aquina, actualizando el valor de la se˜ nal internal_state. Puesto que se comprueba antes el valor de reset_n, esta se˜ nal tiene prioridad sobre la se˜ nal de reloj. Se emplea la funci´ on est´ andar de VHDL rising edge para representar que las transiciones en el estado s´ olo se producen en el flanco de subida de la se˜ nal de reloj. – Se ha a˜ nadido una cl´ ausula when other al final de los dos bloques case, con el fin de contemplar todos los casos posibles. Obs´ervese que se asigna

Cap´ıtulo 4

113

Casos pr´ acticos de dise˜ no de circuitos secuenciales

el valor ’X’ (don’t care) a la se˜ nal de salida. Esta es una buena pr´ actica, ya que con ello se ayuda a la herramienta de s´ıntesis a optimizar el circuito combinacional para la se˜ nal de salida (z).

4.4.2

Banco de pruebas

A continuaci´ on, se muestra el c´ odigo VHDL de un banco de pruebas que puede usarse para comprobar el funcionamiento de la m´ aquina de estado finito. El programa de test ejercita completamente la m´ aquina: 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 transici´ on entre los estados. La constante T es el periodo de la se˜ nal de reloj, que en el c´ odigo VHDL del banco de pruebas de denomina PERIODO y toma el valor 100 ns. La se˜ nal de reloj, que inicialmente vale 0, tiene un periodo (PERIODO) de T = 100 ns. Esto implica que los flancos de subida de la se˜ nal 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, seg´ un se muestra en la Figura 4.7. Para generar la se˜ nal de reloj se emplea la siguiente sentencia concurrente: clk <= not clk after ( PERIODO/2 );

donde se asume que la se˜ nal de reloj ha sido inicializada al valor ’0’. Obs´ervese que de esta forma se crea una se˜ nal de reloj infinitamente larga, con lo cual la simulaci´ on no finalizar´ a autom´ aticamente, sino que hay que definir el instante de finalizaci´ on. íìí î



ü

Sä / 0 ðìí î



ýþÿ





Sæ / 0

=

òóôõö÷ö

=

øùù úû

ëìí î ñìí î



ïìí î





S å /1

é ê è ⋅ ç

Figura 4.7: Transiciones en el estado realizadas durante el test.

En el c´ odigo del banco de pruebas, se define un procedimiento para comparar el valor esperado del estado y la salida de la m´ aquina con los actuales. De esta forma el c´ odigo se hace m´ as f´ acilmente comprensible. ------------------------------------------------------- Banco de pruebas para la m´ aquina de Moore library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all;

114

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

use work.STATE_CONSTANTS.all; -- Definici´ on de la entity entity bp_maquinaMooreSimple is constant PERIODO : time := 100 ns; -- Periodo reloj end entity bp_maquinaMooreSimple; -- Definici´ on 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;

-- Declaraci´ on del componente: UUT component maquinaMooreSimple is : out std_logic; -- Se~ nal de salida port( z state

: out std_logic_vector(STATE_BITS-1 downto 0); -- Estado actual de la m´ aquina 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 actual_state actual_z error_count begin

: : : : inout

std_logic; std_logic_vector(STATE_BITS-1 downto 0); std_logic; integer ) is

-- 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

115

Casos pr´ acticos de dise˜ no de circuitos secuenciales

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 u ´nico pulso LOW para reset_n -- En el instante PERIODO/4 se resetea la m´ aquina reset_n <= ’1’, ’0’ after ( PERIODO/4 ), ’1’ after ( PERIODO + PERIODO/4 ); -- Genera se~ nal clk, asumiendo que se inicializ´ o 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 simulaci´ on"; 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 Pr´ acticos de Dise˜ no 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 on finalizada con 0 errores"; report "Simulaci´ else report "ERROR: hay " & integer’image(error_count) & " errores."; end if; wait; -- Final de la ejecuci´ on del bloque process. -- La simulaci´ on continua debido a la sentencia de -- asignaci´ on 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 ejecuci´on del test.

Cap´ıtulo 4

117

Casos pr´ acticos de dise˜ no de circuitos secuenciales

4.4.3

Modelado estructural

Ahora veremos c´ omo describir la m´ aquina de estado finito de la Figura 4.6 empleando c´ odigo VHDL estructural. Usando c´ odigo estructural se tiene mayor control acerca de la l´ ogica que se emplea en el dise˜ no, con lo cual pueden conseguirse circuitos m´ as optimizados que los dados por las herramientas de s´ıntesis a partir de la descripci´ on del comportamiento. Sin embargo, implica realizar parte del dise˜ no manualmente, con el consiguiente riesgo de cometer errores. Para emplear c´ odigo VHDL estructural, en primer lugar hay que decidir qu´e componentes van a usarse en el dise˜ no. Emplearemos puertas l´ ogicas b´ asicas (AND, OR, inversor, NAND, NOR y XOR), as´ı como flip-flops tipo D tales como el descrito en el Ejemplo 2.3.4. A continuaci´ on, debemos obtener las funciones l´ ogicas para el c´ alculo de la salida y del siguiente estado. La tabla de transici´ on de estados y salidas para la m´ aquina descrita en la Figura 4.6 es la siguiente: Estado actual Entrada Pr´ oximo estado Salida A B x NA NB z S0 : S0 : S1 : S1 : S2 : S2 :

0 0 0 0 1 1

0 0 1 1 0 0

0 1 0 1 0 1

S2 : S1 : S2 : S1 : S0 : S2 :

1 0 1 0 0 1

0 1 0 1 0 0

0 0 0 0 1 1

Las funciones l´ ogicas simplificadas que relacionan el pr´ oximo estado (N A, N B) 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 c´ odigo VHDL estructural a partir de la funciones l´ ogicas anteriores. Se define una nueva architecture para la entity del circuito anteriormente definida. ------------------------------------------------------- M´ aquina de Moore, dise~ no estructural library IEEE; use IEEE.std_logic_1164.all; -- Definici´ on de la arquitectura architecture maquinaMooreSimple_estruc of maquinaMooreSimple is signal A, B : std_logic; -- Variables de estado actuales signal NA, NB : std_logic; -- Pr´ oximas variables de estado

118

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 c´ alculo 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 Secci´ on 4.4.2 para testear esta descripci´ on del circuito. Se obtienen los mismos resultados que se obtuvieron cuando se hizo el test de la descripci´ on del comportamiento (v´ease la Figura 4.8). Los resultados del test se muestran en la Figura Figura 4.9.

Figura 4.9: Resultado de la ejecuci´on del test.

Cap´ıtulo 4

4.5

119

Casos pr´ acticos de dise˜ no de circuitos secuenciales

Máquinas de estado finito de Mealy En las m´ aquinas de Mealy, las salidas del circuito dependen del estado actual y del valor actual de las entradas. As´ı pues, aunque la m´ aquina permanezca en un determinado estado, sus salidas pueden cambiar si cambian las entradas. Como ejemplo de implementaci´ on de una m´ aquina de Mealy, consideremos la m´ aquina para el reconocimiento de la secuencia de bits 0110 mostrada en la Figura 4.10. Obs´ervese que se permite el solapamiento de secuencias (por ejemplo, 0110110). La salida de la m´ aquina es un ’1’ l´ ogico cada vez que se detecta el patr´ on 0110 en la secuencia de bits de entrada, que se supone que est´a sincronizada con el reloj de la m´ aquina. El tiempo que transcurre entre la entrada del u ´ ltimo ’0’ del patr´ on y la salida del ’1’ es igual al retardo de una puerta l´ ogica. Para los dem´ as bits de la secuencia de entrada, la salida de la m´ aquina es ’0’.    

S

 

S

   

S

     

S

Figura 4.10: Diagrama de estado de una m´aquina de Mealy para el reconocimiento de la secuencia 0110.

4.5.1

Diseño de la máquina

Adem´ as de la entrada serie de la secuencia de bits (x) y la entrada del reloj (clk), la m´ aquina 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 se˜ nal del reloj, la entrada reset_n vale ’0’, entonces se resetea la m´ aquina, es decir, pasa al estado S0. La m´ aquina tiene dos salidas: el estado actual de la m´ aquina (state) y la salida de detecci´ on del patr´ on 0110 (z). Las constantes globales, que son usadas tanto en el dise˜ no del circuito como en el banco de pruebas, son definidas en el package mostrado a continuaci´ on. ----------------------------------------- Definici´ on de las constantes globales library IEEE; use IEEE.std_logic_1164.all;

120

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 continuaci´ on se muestra el c´ odigo VHDL que describe el comportamiento de la m´ aquina. Obs´ervese 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 pr´ oximo estado y resetear al m´ aquina, que es sensible u ´ nicamente a la se˜ nal de reloj. Puesto que la m´ aquina tiene reset s´ıncrono, este segundo bloque process no es sensible a la se˜ nal de reset. --------------------------------------------------- M´ aquina de Mealy detectora de la secuencia 0110 library IEEE; use IEEE.std_logic_1164.all; use work.seq0110_CONST.all; -- Definici´ on 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; x : in std_logic ); end entity seq0110;

-- Se~ nal de reloj -- Bit de entrada

-- Definici´ on de la architecture architecture seq0110 of seq0110 is signal internal_state : std_logic_vector(STATE_BITS-1 downto 0); begin state <= internal_state; -- C´ alculo 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

121

Casos pr´ acticos de dise˜ no de circuitos secuenciales

end if; end process calculo_salida; -- C´ alculo del pr´ oximo 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 case internal_state is when S0 => if (x = ’0’) then internal_state <= S1;

-- Flanco de subida del reloj

else internal_state <= S0; end if; when S1 => if (x = ’1’) then

-- Primer bit del patr´ on

-- Segundo bit del patr´ on

internal_state <= S2; else internal_state <= S1; end if; when S2 => if (x = ’1’) then internal_state <= S3; else internal_state <= S1; end if; when others => if (x = ’0’) then internal_state <= S1; else internal_state <= S0;

-- Tercer bit del patr´ on

-- Cuarto bit del patr´ on

end if; end case; end if; end process proximo_estado; end architecture seq0110; --------------------------------------------------

El bloque process usado para generar el pr´ oximo estado corresponde directamente con el diagrama mostrado en la Figura 4.10. La se˜ nal de reset no se ha incluido en la lista de se˜ nales a las que es sensible el bloque. As´ı pues, este bloque s´ olo es activado cuando se produce un cambio en la se˜ nal de reloj: la condici´ on if ( (reset_n = ’0’) and rising_edge(clk) ) s´ olo se comprueba

122

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

cuando se produce un cambio en la se˜ nal de reloj. De esta forma, se implementa un reset s´ıncrono. El bloque process usado para generar la se˜ nal 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 se˜ nales de la parte derecha de la asignaci´ on. Puesto que ´este es un bloque combinacional, la duraci´ on de la se˜ nal ’1’ de salida puede ser m´ as peque˜ na que un ciclo de reloj, ya que su duraci´ on depende del tiempo durante el cual la entrada x siga valiendo ’0’ mientras la m´ aquina permanezca en el estado S3. Para garantizar que la salida ’1’ tiene una duraci´ on de al menos un ciclo de reloj, es necesario hacer pasar la se˜ nal de salida por un flip-flop D. Esto puede hacerse a˜ nadiendo a la descripci´ on 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 definici´ on del circuito, modificada de la forma descrita anteriormente, es mostrada a continuaci´ on. --------------------------------------------------- M´ aquina de Mealy detectora de la secuencia 0110 library IEEE; use IEEE.std_logic_1164.all; use work.seq0110_CONST.all; -- Definici´ on 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; -- Definici´ on 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

123

Casos pr´ acticos de dise˜ no de circuitos secuenciales

-- a partir del estado actual -- y la entrada actual, mediante -- un circuito combinacional begin state <= internal_state; -- C´ alculo 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; -- C´ alculo del pr´ oximo 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 internal_state <= S1; else internal_state <= S0; end if; when S1 => if (x = ’1’) then internal_state <= S2; else internal_state <= S1; end if;

-- Primer bit del patr´ on

-- Segundo bit del patr´ on

124

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

when S2 => if (x = ’1’) then internal_state <= S3; else internal_state <= S1; end if; when others => if (x = ’0’) then

-- Tercer bit del patr´ on

-- Cuarto bit del patr´ on

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 dise˜ narse un peque˜ no banco de pruebas que introduzca algunos vectores de test. A continuaci´ on, se muestra un ejemplo de este tipo de banco de pruebas. ------------------------------------------------------- Banco de pruebas que introduce algunos vectores de -- test en la m´ aquina 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 m´ aquina signal state : std_logic_vector(STATE_BITS-1 downto 0); -- Estado actual signal reset_n : std_logic; signal clk : std_logic := ’0’; signal x : std_logic; -- Declaraci´ on del componente component seq0110 is port ( z_long : out std_logic;

-- Reset s´ ıncrono activado LOW -- Se~ nal de reloj -- Entrada a la m´ aquina

Cap´ıtulo 4

Casos pr´ acticos de dise˜ no 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 end component seq0110;

std_logic );

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 simulaci´ on"; x <= ’0’; wait for 2*PERIODO; x <= ’1’; wait for PERIODO; x <= ’1’; wait for PERIODO; x <= ’0’; wait for PERIODO; x <= ’1’; x <= ’1’; x <= ’0’; x <= ’1’; wait;

wait for PERIODO; wait for PERIODO; wait for PERIODO; wait for PERIODO; -- Detiene este bloque process, pero no -- finaliza la simulaci´ on debido a que -- hay asignaciones concurrentes

end process main; end architecture bp1_seq0110;

Ejecutando este banco de pruebas durante 1200 ns, se obtienen las se˜ nales mostradas en la Figura 4.11. Obs´ervese que la se˜ nal z vale ’1’ mientras el circuito se encuentra en el estado S3 y la entrada vale ’0’. La se˜ nal z est´ a conectada a la entrada de un flip-flop D, cuya salida es la se˜ nal z_long, que mantiene su valor a ’1’ durante un ciclo completo de reloj.

126

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura 4.11: Resultado de la simulaci´on del circuito detector del patr´ on 0110.

4.5.2

Banco de pruebas

El banco de pruebas anterior da cierta informaci´ on acerca del comportamiento del circuito, pero no lo prueba de manera sistem´ atica. A continuaci´ on, se muestra el c´ odigo de un banco de pruebas que testea sistem´ aticamente el circuito, pasando al menos una vez por cada uno de los arcos de transici´ on entre estados de la m´ aquina. El orden en el cual el banco de pruebas recorre los arcos de transici´ on de la m´ aquina es mostrado en la Figura 4.12. El c´ odigo del banco de pruebas es mostrado a continuaci´ on. 4

2 1

S

10

3

S

5

S

11

S

6 13

9

7

8 12

Figura 4.12: Orden en que el programa de test recorre los arcos del diagrama de estado de la m´aquina.

------------------------------------------------------- Banco de pruebas - M´ aquina 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 m´ aquina signal state : std_logic_vector(STATE_BITS-1 downto 0);

Cap´ıtulo 4

127

Casos pr´ acticos de dise˜ no de circuitos secuenciales

signal reset_n : std_logic; signal clk : std_logic := ’0’;

-- Estado actual -- Reset s´ ıncrono activado LOW -- Se~ nal de reloj

signal x

-- Entrada a la m´ aquina

: std_logic;

-- Declaraci´ on del componente component seq0110 is port ( z_long : out std_logic; state : out reset_n : in clk : in x : in end component seq0110;

std_logic_vector(STATE_BITS-1 downto 0); std_logic; std_logic; std_logic );

-- Procedimiento para comprobar si se produce error procedure comprueba_estado_salida std_logic_vector(STATE_BITS-1 downto 0); ( esperado_state : std_logic; esperado_z : actual_state actual_z error_count begin -- Comprueba el

: std_logic_vector(STATE_BITS-1 downto 0); : std_logic; : inout integer) is 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 Pr´ acticos de Dise˜ no 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 um. errores variable error_count : integer := 0; -- N´ begin report "Comienza la simulaci´ on"; 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); wait for PERIODO; -- Va a S1 x <= ’0’; 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 pr´ acticos de dise˜ no 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 "Simulaci´ on finalizada sin errores"; else report "ERROR: Hay " & integer’image(error_count) & " errores."; end if; wait;

-- Detiene este bloque process, pero no -- finaliza la simulaci´ on debido a que -- hay asignaciones concurrentes

end process main; end architecture bp_seq0110;

El test se ejecuta durante 1500 ns, sin que se produzca ning´ un error. En la Figura 4.13 se muestra la evoluci´ on de las se˜ nales durante los primeros 1400 ns.

Figura 4.13: Resultado de la simulaci´on del programa de test.

130

4.6

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Descripción VHDL de alto nivel Las herramientas de s´ıntesis actuales son capaces de generar circuitos eficientes a partir de una descripci´ on RTL (register-transfer level) del circuito. De hecho, a menos que el dise˜ nador est´e muy familiarizado con la arquitectura hardware en la que va a implementarse el circuito, generalmente se obtienen mejores circuitos si se realiza una descripci´ on VHDL de alto nivel del circuito y se emplea una buena herramienta de s´ıntesis, en lugar de dise˜ nar manualmente (al nivel de puertas l´ ogicas o transistores) el circuito. Debido a esto, el m´etodo de dise˜ no de hardware recomendado actualmente es realizar una descripci´ on VHDL de alto nivel del circuito y emplear una buena herramienta de s´ıntesis para obtener la netlist para la arquitectura hardware de la implementaci´ on. Cuando se describe el comportamiento del circuito a alto nivel, la herramienta de s´ıntesis tiene mayor libertad para optimizar su estructura, produciendo circuitos m´ as eficientes. Por ejemplo, si el dise˜ nador realiza una descripci´ on estructural basada en puertas NAND, o emplean una secuencia de ecuaciones l´ ogicas para describir el circuito, entonces la herramienta de s´ıntesis s´ olo puede eliminar las puertas redundantes y simplificar las funciones l´ ogicas. En cambio, si el dise˜ nador describe el comportamiento esperado de ese mismo circuito, la herramienta de s´ıntesis puede producir un dise˜ no l´ ogico completamente diferente que sea m´ as eficiente que el considerado originalmente por el dise˜ nador. Para ilustrar c´ omo puede realizarse una descripci´ on VHDL de alto nivel a partir de una descripci´ on algor´ıtmica, consideraremos nuevamente el dise˜ no de un circuito detector de patrones en una secuencia de bits.

4.6.1

Circuito detector de secuencia

Supongamos que deseamos dise˜ nar un circuito para la detecci´ on 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. Paso 2.

prev_data <- 1111 1111; /* Almacena 8 bits anteriores */ 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 c´ odigo VHDL del circuito detector de secuencia puede escribirse directamente bas´ andose en el algoritmo anterior. A continuaci´ on, se muestran dos versiones de la descripci´ on del circuito: una en la cual prev_data es una variable

Cap´ıtulo 4

Casos pr´ acticos de dise˜ no de circuitos secuenciales

131

y otra en la cual es una se˜ nal. Ambas descripciones de la arquitectura son igualmente v´ alidas. -------------------------------------------- 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 reset_n : in clk : in data_in : in end entity detector_sec;

std_logic; std_logic; std_logic; std_logic );

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 u ´ nica diferencia entre la descripci´ on en VHDL y la descripci´ on algor´ıtmica, aparte del uso de la sintaxis de VHDL, es que en el c´ odigo VHDL no se ha incluido la sentencia data_in <- siguiente dato de entrada;

En el c´ odigo VHDL no es necesario realizar la asignaci´ on 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 se˜ nal de reloj. A continuaci´ on, se muestra otra forma de describir la architecture del circuito. En este caso, prev_data es una se˜ nal.

132

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no 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 l´ ogico de un bit hacia la izquierda e inserta data_in en el bit menos significativo. Puesto que la asignaci´ on a se˜ nales no tiene efecto inmediatamente, sino un delta de tiempo posterior al tiempo simulado actual, esta operaci´ on de desplazamiento 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 comparaci´ on, es necesario realizar la comparaci´ on usando el valor de prev_data anterior al desplazamiento.

A

VeriBest VB99.0

Objetivos. Instalar en su propio ordenador y realizar las operaciones b´ asicas de manejo del entorno de simulaci´ on de VHDL’93 VeriBest. Estas operaciones b´ asicas incluyen al menos: – Edici´ on y compilaci´on de modelos. – Simulaci´ on y visualizaci´ on de los resultados. – Depurado usando el debugger.

A.1 Instalación La versi´ on de evaluaci´ on VB99.0 presenta la limitaci´ on 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 Simulator. 2. Acepte los t´erminos de la licencia. 3. Escoja el directorio en el cual desea que se instale el simulador. 4. Seleccione para su instalaci´ on “VeriBest VHDL Simulator”, que es la opci´ on se˜ nalada por defecto. 5. El programa de instalaci´ on 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 Simulator”, en la que se encuentra el simulador VHDL (VeriBest VHDL), un tutorial y la documentaci´ on en l´ınea.

134

A.2

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

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 com´ unmente 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 d

y

a)

E

Y

0

Z

1

d

b)

Figura A.1: Buffer triestado: a) s´ımbolo l´ogico; 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; -------------------------------------------

Ap´endice A

135

VeriBest VB99.0

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.3

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Edición y compilación de un modelo En esta secci´ on se describe c´ omo 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 men´ u “Workspace” y seleccione la opci´ on “New... ” 2. Seleccione el comando “New...” del men´ u “File”. Se mostrar´ a una ventana en la que tiene que seleccionar la opci´ on “VHDL Workspace”. Tras seguir una de estas dos opciones, se mostrar´ a una ventana (v´ease 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.

Aparecer´ a en el lateral izquierdo de la ventana principal del simulador una nueva ventana con el t´ıtulo bufferTriestado.vpd. Inicialmente, la ventana s´ olo muestra una carpeta vac´ıa, denominada bufferTriestado source (v´ease la Figura A.3). En dicha ventana ubicaremos todos los ficheros necesarios para simular el buffer triestado, que en este caso son dos: la descripci´ on del circuito (bufferTriestado.vhd) y de su banco de pruebas (bp bufferTriestado.vhd). Al igual que el buffer

Ap´endice A

VeriBest VB99.0

137

Figura A.3: Entorno de simulaci´on tras crear el espacio de trabajo.

se ha definido en un u ´ nico fichero, podr´ıa haberse definido en dos: un fichero con el c´ odigo de la interfaz y otro con el c´ odigo de la arquitectura.

A.3.3

Edición de un fichero

Puede crearse un nuevo fichero utilizando el comando “New...” del men´ u “File”. Obtendr´ a una ventana en blanco en la que puede teclear el c´ odigo VHDL. Escriba el c´ odigo que se muestra en la secci´ on A.2.1. Una vez haya concluido, gu´ ardelo con el nombre bufferTriestado.vhd mediante el comando “Save”, situado en el men´ u “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 rat´ on sobre el bot´ on “+”, 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 men´ u “Workspace”. Tras realizar este paso obtendr´ a una ventana para la selecci´ on 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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura A.4: Entorno de simulaci´on tras incluir el fichero bufferTriestado.vhd el espacio de trabajo.

A.3.5

Compilación de un fichero

Para establecer las opciones de compilaci´ on, seleccionamos la opci´ on “Settings...” del men´ u “Workspace”, o bien recurrimos al icono “Workspace Settings” que est´ a situado en la barra de herramientas. Con ello se mostrar´ a una ventana, en la cual seleccionamos la pesta˜ na “Compile”. De este modo, accedemos al cuadro de di´ alogo donde se muestran, entre otras, las siguientes opciones de compilaci´on: “Debug”

Activando esta opci´ on el archivo seleccionado ser´a compilado con la opci´ on de depuraci´ on. Con esta opci´ on activa antes de una compilaci´on, es posible utilizar todos los comandos del men´ u Debug durante la fase de simulaci´ on. Si se desea que todos los archivos del espacio de trabajo sean compilados con esta opci´ on, basta con seleccionar la carpeta del espacio de trabajo en la ventana y activar la opci´ on.

“Index Checks”

Si esta opci´ on se encuentra activa, el compilador comprueba la existencia de errores en los ´ındices de los arrays.

“Range Checks”

Si esta opci´ on se encuentra activa, el compilador comprueba la existencia de errores en los rangos de los subtipos que se hayan definido.

Ap´endice A

139

VeriBest VB99.0

Compile el fichero. Para ello seleccione el comando “Compile”, que est´ a situado en el men´ u “Workspace”. El resultado de la compilaci´ on se muestra en la ventana de informaci´ on, situada en la parte inferior de la ventana principal. Observe que la ventana de informaci´ on contiene las tres pesta˜ nas siguientes: “General”

Proporciona informaci´on sobre cualquier acci´on que se realice en la herramienta.

“Build”

Muestra la informaci´on referente al proceso de compilaci´ on de ficheros. En el caso de que haya habido errores en la compilaci´on muestra la l´ınea de c´odigo donde aparece cada error y el tipo de error que es.

“Simulate”

Proporciona informaci´on sobre la fase de simulaci´ on.

Cuando el proceso no da errores, lo guardamos (“Save”). La unidad compilada se almacena en la librer´ıa WORK. Para ver su ubicaci´ on, se selecciona el comando “Library Browser” ubicado en el men´ u “Library”, o se pincha en el icono correspondiente. 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 informaci´ on de fecha y opciones de compilaci´ on 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 est´ a trabajando mediante el comando “Reinitialize Lib environment” situado en el men´ u “Workspace”. Al reinicializar la librer´ıa, desaparecen las unidades compiladas.

Figura A.5: Library Browser.

140

A. Urqu´ıa, C. Mart´ın Villalba

A.3.6

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Banco de pruebas

1. Cree un nuevo fichero con el c´ odigo que se muestra en la secci´ on A.2.2. Una vez haya concluido, gu´ ardelo con el nombre bp bufferTriestado.vhd. 2. Incluya el fichero bp bufferTriestado.vhd en el espacio de trabajo bufferTriestado.vpd. La ventana principal del simulador tiene que quedar tal y como se muestra en la Figura A.6. El orden de compilaci´ on 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 simulaci´on tras incluir el banco de pruebas en el espacio de trabajo.

3. Compile el fichero bp bufferTriestado.vhd.

A.4

Simulación y visualización de los resultados En esta secci´ on se describen los pasos a seguir para realizar la simulaci´ on y la visualizaci´ on de resultados, usando el buffer triestado como ejemplo.

A.4.1

Establecer las condiciones de la simulación

Para fijar las condiciones de la simulaci´ on, siga los pasos siguientes: 1. Seleccione la opci´ on “Settings...” del men´ u “Workspace” o haga clic sobre el icono correspondiente, denominado “Workspace Settings”, de la barra de

Ap´endice A

141

VeriBest VB99.0

Figura A.7: Opciones de simulaci´on.

herramientas. A continuaci´ on, se abrir´ a la ventana mostrada en la Figura A.7. 2. Para acceder al cuadro de di´ alogo con las opciones de simulaci´ on, seleccione la pesta˜ na “Simulate” de la ventana. 3. Despliegue la carpeta “WORK” para visualizar los elementos sobre los que se puede realizar una simulaci´ on. Obtendr´ a las interfaces (entity) y arquitecturas (architecture) que ha programado en los pasos anteriores. Para realizar la prueba de la puerta l´ ogica 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 rat´ on (haga clic sobre ella) y pulse el bot´ on “Set”. Tras esta acci´ on, los campos “Entity” y “Arch” se rellenar´ an autom´aticamente con los nombres de la interfaz y de la arquitectura. Por u ´ ltimo, activamos la opci´ on “Trace On” (que nos permite visualizar las formas de onda resultantes). Esto tambi´en se logra desplegando Simulate→Trace. 4. Fijadas las condiciones de simulaci´ on, pulse el bot´ on “Aceptar”.

A.4.2

Activación del simulador

Para realizar la simulaci´ on hay que arrancar el simulador. Esto se puede realizar de dos formas: mediante la opci´ on “Execute Simulator” del men´ u “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 activaci´ on del simulador aparecer´ a una ventana de aviso (v´ease

142

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

la Figura A.8) en la que se indica que, al no encontrar una licencia, se est´ a utilizando el simulador en modo limitado. Pulse el bot´ on “Aceptar” para continuar trabajando.

Figura A.8: Mensaje de aviso sobre la ausencia de licencia.

Tras la activaci´ on del simulador, en la ventana denominada “Simulate”, situada en la parte inferior del espacio de trabajo, aparece un texto. En la u ´ ltima 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 simulaci´ on, ya puede empezar a realizar simulaciones. Para realizar simulaciones puede elegir una de las siguientes opciones: 1. Presionar el bot´ on de color verde, denominado “Run”, que est´ a situado en la barra de herramientas (v´ease la Figura A.9). 2. Seleccionar la opci´ on “Run” o “Run Forever” del men´ u “Simulate”. Los siguientes controles de la barra de herramientas del entorno (ver Figura A.9) nos permiten controlar la simulaci´ on:

Run Tiempo de Unidades del simulación tiempo de simulación

Stop Quit

Figura A.9: Botones para controlar la simulaci´on.

– Lista desplegable. Permite seleccionar las unidades del tiempo de simulaci´ on. Por defecto, la unidad de tiempo es nanosegundos (ns).

Ap´endice A

143

VeriBest VB99.0

– Casilla num´erica (junto al bot´ on “Run”). Permite indicar el tiempo de simulaci´ on. – Bot´ on “Run”. Permite ejecutar una simulaci´ on. – Bot´ on “Stop”. Permite detener la simulaci´ on. – Bot´ on “Quit”. Permite salir del simulador. Para visualizar los resultados de la simulaci´ on, podemos o bien pinchar con el rat´ on sobre el icono “WaveForm Window”, que est´ a situado en la barra de herramientas, o bien ejecutar el comando “New WaveForm Window”, que se encuentra en el men´ u “Tools...” Obtendr´ a una ventana con una escala de tiempos, en la que no se visualiza ninguna se˜ nal. Para seleccionar las se˜ nales, pulse el bot´ on “Add signals” en la ventana de visualizaci´ on de se˜ nales. Dicho bot´ on se encuentra indicado en la Figura A.10.

Add signals

Figura A.10: Selecci´on de las se˜ nales a visualizar.

Obtendr´ a una nueva ventana, mostrada tambi´en en la Figura A.10, en la que puede seleccionar las se˜ nales que desea representar. Pueden seleccionarse se˜ nales 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 se˜ nales que corresponden a la arquitectura del banco de pruebas, pulse sobre el bot´ on “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 rat´ on sobre el icono “Quit”, que se encuentra indicado en la Figura A.9.

144

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura A.11: Resultados de la simulaci´on.

A.5

Depurado usando el debugger Para poder hacer uso del depurador se tienen que haber compilado los ficheros con la opci´ on “Debug” habilitada y se ha de activar el simulador. Una vez activado el simulador, aparece el men´ u “Debug”. Hasta que no se inicie la simulaci´ on no aparecer´ an habilitados todos los comandos del depurador. Entre los comandos del depurador habilitados antes de iniciar la simulaci´ on, cabe destacar los siguientes (v´ease la Figura A.12):

Insert/remove Examine breakpoint Clear all breakpoint

Show breakpoints New watch window

Call stack

Figura A.12: Opciones de depuraci´ on antes del inicio de la simulaci´on.

– “Insert/Remove a breakpoint”: nos permite introducir un punto de ruptura (breakpoint) o eliminar un punto de ruptura que hab´ıamos introducido previamente.

Ap´endice 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 evoluci´ on de las se˜ nales de forma num´erica. Esta ventana, mostrada en la Figura A.13, dispone de hasta 4 paneles de observaci´ on independientes (“Watch1” a “Watch4”). Para a˜ nadir a uno de los cuatro paneles los elementos a observar, pulse el bot´ on “Add Watch...” y obtendr´ a una ventana cuyo t´ıtulo es “Add watch” (v´ease la Figura A.13), en la que puede seleccionar tanto las se˜ nales de forma independiente (se selecciona la se˜ nal y se pulsa el bot´ on “Watch”), como todas las se˜ nales de un elemento (se selecciona el componente o bloque en la parte izquierda de la ventana y se pulsa el bot´ on “Watch block”).

Figura A.13: Ventanas para observar la evoluci´on de las se˜ nales.

– “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 bot´ on denominado “Condition...” Pulsando este bot´ on se abre una ventana, denominada “Source Breakpoint Condition”, en la que puede establecer condiciones de activaci´ on para un punto de ruptura determinado. Desde la ventana “Source Breakpoint Condition” podr´ a indicar que el punto de ruptura permanezca activo u ´ nicamente para una instancia o proceso espec´ıfico. De esta forma, cuando se establecen condiciones, el simulador se detiene u ´ nicamente en el punto de ruptura que hay dentro del proceso especificado, no en todos los procesos en los que est´ a el punto de ruptura. – “Call stack”: nos permite conocer la pr´ oxima l´ınea de c´ odigo VHDL que se ejecutar´ a cuando se contin´ ue con la simulaci´ on. Si se realiza doble clic sobre

146

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

una de las entradas que aparecen en la “Call Stack”, se obtendr´ a una nueva ventana en la que se muestra el c´ odigo fuente VHDL que se indica en la entrada que ha seleccionado. En el caso de que el dise˜ no que est´ a ejecutando contenga subprogramas anidados, en el momento en que se entre a ejecutar un subprograma, la ventana “Call Stack” se incrementar´ a con una nueva entrada correspondiente a la llamada al subprograma. Cuando concluya la ejecuci´ on del subprograma, la correspondiente entrada en la ventana ser´ a eliminada. Para empezar el proceso de depuraci´ on hay que comenzar la simulaci´ on. Una vez comenzada la simulaci´on, se habilitar´ an, entre otros, los siguientes comandos de depuraci´ on (v´ease la Figura A.14): – “Continue”: contin´ ua la ejecuci´ on de la simulaci´ on hasta el siguiente punto de ruptura o hasta que concluya el tiempo de simulaci´ on. – “Step”: avanza la simulaci´ on una l´ınea del c´ odigo fuente VHDL.

Step Continue

Figura A.14: Opciones de depuraci´ on una vez iniciada la simulaci´on.

B

ModelSim PE Student Edition

Objetivos. Instalar en su propio ordenador y realizar las operaciones b´ asicas de manejo del entorno de simulaci´ on ModelSim PE Student Edition. Estas operaciones b´ asicas incluyen al menos: – Edici´ on y compilaci´on de modelos. – Simulaci´ on y visualizaci´ on de los resultados. – Depurado de modelos.

B.1

Instalación El grupo Mentor Graphics, desarrollador de ModelSim, ofrece de manera gratuita una versi´ on de evaluaci´ on temporal (180 d´ıas) del simulador. El simulador ModelSim 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 instalaci´ on se describen a continuaci´ on. Durante todo el proceso debe disponerse de conexi´ on a Internet. 1. Descargar el fichero ejecutable de instalaci´ on (aproximadamente 60MB) de la direcci´ on: http://www.model.com/resources/student edition/download.asp para lo cual en primer lugar tendr´ a que rellenar un formulario electr´ onico con sus datos y se˜ nalar una casilla que indica que s´ olo va a usar la herramienta para fines educativos. 2. Ejecutar dicho fichero, el cual realiza la instalaci´ on del simulador. En la fase final de la instalaci´ on, el programa de instalaci´ on se conecta a una p´ agina web en la cual hay un formulario para la solicitud de la licencia.

148

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

3. En la hoja de solicitud de licencia, debemos indicar a qu´e direcci´ on de correo electr´ onico deseamos que nos env´ıen el fichero de licencia. En esa direcci´ on de correo recibiremos un correo con el fichero de licencia y las indicaciones de d´ onde debe guardarse. La licencia tiene una validez de 180 d´ıas, transcurridos los cuales debe repetirse la instalaci´ on y la solicitud de la licencia. La licencia s´ olo es v´ alida 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 com´ unmente 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 d

y

a)

E

Y

0

Z

1

d

b)

Figura B.1: Buffer triestado: a) s´ımbolo l´ogico; 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)

Ap´endice 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 Pr´ acticos de Dise˜ no 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 secci´ on se describe c´ omo 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 aparecer´ a 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 aplicaci´ on pulse el bot´ on “Close”.

Menús

Iconos

Workspace

Transcript

Figura B.2: Ventana principal de ModelSim.

Se abrir´ a entonces la ventana principal del entorno (v´ease la Figura B.2), que cuenta con los elementos siguientes:

Ap´endice B

151

ModelSim PE Student Edition

“Workspace”

Panel situado a la izquierda de la ventana principal. Al arrancar la aplicaci´ on este panel tiene una u ´ nica pesta˜ na denominada “Library”. En esta pesta˜ na aparecen los nombres l´ ogicos 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 ejecuci´ on de comandos. 2. Permitir teclear comandos en l´ınea. Se mantiene un hist´ orico de todos los comandos ejecutados. Usando las teclas ↑ y ↓ se puede acceder a comandos anteriores y posteriores para ejecutarlos de nuevo.

Barra de men´ us Barra de iconos

B.3.2

Creación de un proyecto

Para crear un proyecto, debe seguir los pasos siguientes: 1. Seleccione la opci´ on File → New → Project. Aparecer´ a la ventana de di´ alogo para la creaci´ on de proyectos (v´ease 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 di´alogo para la creaci´on de un proyecto.

2. En la casilla “Project Name” teclee bufferTriestado como nombre del proyecto. 3. En la casilla “Project Location”, seleccione el directorio d´ onde va a ubicar los ficheros del proyecto. Puede ayudarse del bot´ on “Browse...” para moverse por el disco. Si el directorio introducido no existe, la herramienta le pedir´ a confirmaci´ on para su creaci´ on. En este directorio se crear´ a el fichero bufferTriestado.mpf.

152

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura B.4: Entorno de simulaci´on 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 ser´ a el que, una vez creado el proyecto, la herramienta asigne autom´ aticamente a un directorio ubicado debajo del indicado en el cuadro “Project Location”. En este directorio se almacenar´ an las unidades de dise˜ no VHDL compiladas. En la Figura B.3 se muestra el cuadro de di´ alogo una vez realizados estos pasos. 5. Pulse el bot´ on “OK”.

B.3.3

Añadir ficheros al proyecto

Al crear un proyecto, se producen los siguientes cambios en el entorno de simulaci´ on (v´ease la Figura B.4): – Aparece una nueva pesta˜ na en el panel “Workspace” denominada “Project”. En dicha pesta˜ na se muestran los ficheros que forman parte del proyecto. Observe que si la pesta˜ na “Project” est´ a seleccionada se muestra un men´ u llamado “Project”. Por el contrario, si la pesta˜ na “Library” est´ a seleccionada no se muestra el men´ u “Project” sino un men´ u 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 di´ alogo denominada “Add items to the Project”. Esta ventana, que permite a˜ nadir elementos al proyecto, incluye las siguientes opciones (v´ease la Figura B.4):

Ap´endice B

153

ModelSim PE Student Edition

“Create New File” “Add Existing File”

Permite crear un nuevo fichero de dise˜ no. Permite incluir un fichero ya existente en el proyecto actual copi´ andolo al directorio del proyecto o referenci´ andolo desde su ubicaci´ on actual.

“Create Simulation” “Create New Folder”

Permite crear configuraciones para simulaci´ on. Permite crear directorios virtuales. Estos directorios tienen, sobre la pesta˜ na “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 di´ alogo “Add items to the Project”. Se pueden acceder a estas mismas opciones a trav´es del men´ u 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 di´ alogo “Add items to the Project” mostrado en la Figura B.4. – O bien, seleccionar del men´ u el comando Project → Add to Project → New File... Para poder usar el men´ u, si est´ a abierta la ventana de di´ alogo “Add items to the Project”, hay que cerrarla presionando el bot´ on “Close”. Aparece una ventana de di´ alogo denominada “Create Project File”. Esta ventana tiene los siguientes elementos (ver Figura B.5): “File Name”

Permite especificar la ubicaci´ on y nombre del fichero fuente. El bot´ on “Browse...” nos permite especificar la ubicaci´ on del fichero navegando a trav´es de las carpetas del sistema. Si especificamos un nombre del fichero, sin indicar ning´ un directorio, ´este se guardar´ a en el directorio del proyecto.

“Add File As Type” “Folder”

Nos permite seleccionar el tipo de fichero. Lista desplegable donde aparecen todos los directorios existentes en el proyecto. En el caso de que no se haya creado ning´ un directorio esta lista s´olo tendr´ a un elemento: “Top Level”.

2. Complete los cuadros de la ventana de di´ alogo “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 Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

– En la lista desplegable “Add file as type” seleccione VHDL. – Pulse “OK”. Si ha a˜ nadido el fichero a trav´es del cuadro de di´ alogo “Add items to the Project” y no quiere a˜ nadir por el momento m´ as elementos al proyecto cierre dicha ventana. Ello lo puede hace pulsando el bot´ on “Close”.

Figura B.5: Ventana de di´alogo “Create Project File”.

Una vez finalizado este proceso se crea un fichero denominado bufferTriestado.vhd en el directorio del proyecto. En la Figura B.6 se muestra la ventana principal tras seguir estos pasos. Observe que en la pesta˜ na “Project” del panel “Workspace” aparece la informaci´ on sobre el fichero creado. La informaci´ on mostrada es la siguiente: “Name” “Status”

Nombre del fichero. S´ımbolo que refleja el estado del fichero. Existen los siguientes tres s´ımbolos: – ?: El fichero a´ un no ha sido compilado. – X: El fichero se ha compilado y contiene errores. √ – : El fichero ha sido compilado con ´exito.

“Type” “Order”

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

“Modified”

Muestra la fecha y hora en que el fichero fue modificado por u ´ ltima vez.

Indica la posici´ on del fichero en la secuencia de compilaci´ on cuando hay varios ficheros fuente. El primer fichero de la secuencia de compilaci´on es aqu´el con un n´ umero menor.

3. Al crear el fichero, se abre autom´ aticamente 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 c´ odigo VHDL mostrado en la Secci´ on B.2.1. 5. Salve el fichero seleccionando la opci´ on File → Save del men´ u de la ventana del editor o bien pulsando el icono correspondiente. De al fichero el nombre bufferTriestado.vhd.

Ap´endice B

ModelSim PE Student Edition

155

Figura B.6: Entorno de simulaci´on tras crear un nuevo fichero.

Figura B.7: Ventana de di´alogo “Add File to Project”.

Inserción de un fichero existente en el proyecto A continuaci´ on, se describen los pasos que habr´ıa que seguir para incorporar al proyecto un fichero ya existente: – Seleccionar del men´ u el comando Project → Add to Project → Existing File... Tambi´en se puede realizar la misma acci´ on desde la ventana de di´ alogo “Add items to the Project” seleccionando la opci´ on “Add Existing File”. Aparece una ventana de di´ alogo denominada “Add File to Project” (v´ease la Figura B.7). Esta ventana tiene los siguientes elementos:

156

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

“File Name”

Permite seleccionar el fichero fuente. El bot´ on “Browse...” nos facilita la selecci´on de dicho fichero navegando a trav´es de las carpetas del sistema.

“Add File As Type” “Folder”

Nos permite seleccionar el tipo de fichero.

“Copy to project directory” “Reference from current location”

Realiza una copia f´ısica del fichero desde su localizaci´ on al directorio del proyecto.

Lista desplegable donde aparecen todos los directorios existentes en el proyecto. En el caso de que no se haya creado ning´ un directorio esta lista s´olo tendr´ a un elemento: “Top Level”.

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 bot´ on “Browse...”). Seleccione VHDL de la lista deplegable “Add file as type” y “Top Level” de “Folder”. Por u ´ ltimo, seleccione la opci´ on “Copy to project directory” y pulse “OK”.

B.3.4

Compilación de un fichero

Para verificar que el c´ odigo VHDL es correcto, es necesario compilar el fichero. Al compilar el fichero se genera el fichero binario que posteriormente se emplear´ a en la simulaci´ on. Para compilar el fichero podemos seguir una de las opciones siguientes: – Seleccionar la opci´ on Compile → Compile All. Mediante esta opci´ on se compilan todos los ficheros del proyecto. El orden de compilaci´ on que se sigue es el indicado en la columna “Order” del panel “Workspace”. – Seleccionar la opci´ on Compile → Compile Selected. Mediante esta opci´ on se compila u ´ nicamente el fichero seleccionado. – Situar el rat´ on en el panel “Workspace” de la ventana principal y pulsar el bot´ on derecho. Aparece un men´ u contextual con varias opciones para lanzar directamente la compilaci´ on. Mediante la opci´ on Compile → Compile Outof-Date de este men´ u se compila u ´ nicamente 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 ubicaci´ on, se selecciona la pesta˜ na “Library” del panel ”Workspace”. Pulsando sobre el signo “+” que aparece a la izquierda de la librer´ıa work podemos ver su contenido (v´ease la Figura B.8). En la librer´ıa existe una interfaz (entity) denominada bufferTriestado y una arquitectura (architecture) llamada behavioral.

Ap´endice B

ModelSim PE Student Edition

157

Figura B.8: Contenido de la librer´ıa work tras compilar el fichero bufferTriestado.vhd.

Errores de compilación A continuaci´ on, se describe qu´e ocurre cuando existen errores de compilaci´ on en un fichero. Para ello vamos a modificar el fichero bufferTriestado.vhd. Introducimos 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 (v´ease la Figura B.9). Tambi´en 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 compilaci´ on en el fichero bufferTriestado.vhd. Si hacemos doble clic con el rat´ on sobre el mensaje de error se muestra una ventana de di´ alogo (v´ease la Figura B.9). Dicha ventana contiene en color rojo un mensaje con informaci´ on sobre el tipo de error que se ha producido y el n´ umero de l´ınea en que aparece. Si hacemos doble clic con el rat´ on sobre dicho mensaje se abre la ventana de edici´ on con la l´ınea del c´ odigo que ha producido el error marcada en color naranja (v´ease 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 c´ odigo del banco de pruebas, que se va a guardar con el nombre bp bufferTriestado.vhd. El c´ odigo del banco de pruebas se muestra en la Secci´ on B.2.2. Para crear el fichero, siga los siguientes pasos: – Seleccione del men´ u el comando Project → Add to Project → New File · · · – Complete la ventana de di´ alogo denominada “Create Project File” del siguiente modo:

158

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Figura B.9: Entorno de simulaci´on cuando hay errores de compilaci´on en el fichero 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 a´ un no ha sido compilado. El fichero tiene el n´ umero 1 en la columna “Order”. Esto indica que si usamos la opci´ on de compilaci´ on Compile → Compile All, el fichero bp bufferTriestado.vhd se compilar´ a despu´es que el fichero bufferTriestado.vhd. Compile el fichero bp bufferTriestado.vhd siguiendo algunas de las opciones descritas en la secci´ on B.3.4. Existen ocasiones en que el orden de compilaci´ on de los ficheros puede no ser el correcto en funci´ on de la estructura del c´ odigo 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 compilaci´ on. Se puede modificar el orden de compilaci´ on del siguiente modo: – Situar el rat´ on en el a´rea del panel “Workspace”. – Apretar el bot´ on derecho del rat´ on. Aparece as´ı un men´ u textual. – Seleccionar la opci´ on Compile → Compile Order... del men´ u. Aparece una ventana denominada “Compile Order” (ver Figura B.11). – Puede cambiar el orden de posici´ on del fichero en la secuencia de compilaci´ on seleccionando dicho fichero en la ventana “Compile Order” y pulsando sobre los botones (ver Figura B.11).

Figura B.10: Panel bp bufferTriestado.vhd.

“Workspace”

tras

insertar

Botones para cambiar el orden en la secuencia de compilación

Figura B.11: Ventana “Compile Order”.

el

fichero

160

B.4

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Simulación y visualización de los resultados En esta secci´ on se describen los pasos a seguir para realizar la simulaci´ on y la visualizaci´ on 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 pesta˜ na “Library” la interfaz (entity) que queremos simular. En este caso, seleccionamos bp bufferTriestado. Con el bot´ on derecho de rat´ on sobre esta interfaz seleccionamos la opci´ on “Simulate” (v´ease la Figura B.12). Observe que la ventana principal del simulador se modifica. Cabe destacar los cambios siguientes: – Aparecen las tres pesta˜ nas siguientes en el panel “Workspace”: “sim” “Files” “Memories”

Muestra la jerarqu´ıa de dise˜ no. Muestra los ficheros fuente. Herramienta de an´ alisis 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 simulaci´ on, 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 ventana haciendo clic con el rat´ on sobre el bot´ on “undocked” (v´ease la Figura B.13a). Puede volver a insertar el panel en la ventana principal presionando el bot´ on “docked” (v´ease la Figura B.13b). Podemos seleccionar los paneles a mostrar usando el men´ u “View”. A continuaci´ on, se comenta brevemente la funcionalidad de algunos paneles: “Dataflow”

Permite visualizar, de modo gr´ afico, la conectividad entre los elementos (procesos, sentencias de asignaci´ on concurrente, etc.) del modelo y rastrear eventos.

“List”

Muestra, en modo texto, los valores de las se˜ nales y variables en un formato tabular.

“Process”

Muestra la lista de procesos junto con informaci´on sobre su estado.

“Objects”

Muestra la lista de se˜ nales de la interfaz (entity) seleccionada en la pesta˜ na “Sim”.

“Wave”

Permite visualizar la forma de onda de las se˜ nales y variables.

Ap´endice B

161

ModelSim PE Student Edition

Figura B.12: Activaci´on del modo simulaci´on.

a)

b)

Figura B.13: Botones: a) “undocked”; y b) “docked”.

B.4.2

Visualización de los resultados

Las se˜ nales se pueden visualizar en el panel “Wave”. Este panel se puede separar de la ventana principal pulsando el bot´ on “undocked” (v´ease la Figura B.13a). Podemos a˜ nadir se˜ nales de inter´es al panel “Wave” siguiendo uno de los dos siguientes procedimientos: – Seleccionar todas las se˜ nales que queremos visualizar del panel “Objects”. Arrastrar la selecci´ on con el rat´ on y llevarla hasta el panel “Wave”. – Pulsar sobre el panel “Objects” con el bot´ on derecho del rat´ on. En el men´ u que aparece podemos realizar las dos siguiente acciones: 1. Incluir en el panel “Wave” todas las se˜ nales que aparecen en el panel “Objects”. Para ello hacemos clic en la opci´ on Add to Wave → Signals in Region. 2. Mostrar una selecci´ on de las se˜ nales del panel. Para ello hacemos clic en la opci´ on Add to Wave → Selected Signals. Para seleccionar un

162

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

conjunto de se˜ nales pulsamos el bot´ on “Shift” del teclado al mismo tiempo que hacemos clic con el rat´ on sobre las se˜ nales que queremos seleccionar. Para quitar se˜ nales del conjunto seleccionado mantenemos pulsado el bot´ on “Control” mientras hacemos clic con el rat´ on sobre las se˜ nales que queremos quitar. Caben destacar las siguientes caracter´ısticas del panel “Wave” (v´ease la Figura B.14): – Se puede adaptar la informaci´ on visualizada en el panel “Wave” usando los diferentes iconos de zoom. A continuaci´ on se describe la funcionalidad de los iconos de zoom: “Zoom In” “Zoom Out” “Zoom Full”

Amplia la escala de tiempos. Reduce la escala de tiempos. Cambia el rango de la escala de tiempo de modo que vaya desde el instante inicial hasta el instante actual de simulaci´ on.

– Podemos a˜ nadir cursores presionando el bot´ on “Insert Cursor”. Al pie del cursor se indica el instante de tiempo en que se encuentra situado. Adem´ as, aparece el valor de cada se˜ nal en dicho instante de tiempo en el a´rea que hay junto a los nombres de las se˜ nales. Se puede eliminar un cursor presionando el bot´ on “Delete Cursor” una vez hayamos seleccionando dicho cursor.

B.4.3

Ejecución de la simulación

Los siguientes botones nos permiten controlar la simulaci´ on y realizar el depurado del modelo (ver Figura B.15): “Run”

Ejecuta la simulaci´ on durante el tiempo indicado por defecto en el cuadro de la ventana principal (la simulaci´ on puede detenerse antes, si se han introducido puntos de ruptura, o manualmente o por la ejecuci´on de alguna sentencia del banco de pruebas).

“Continue Run”

Contin´ ua la simulaci´ on en curso hasta agotar el tiempo de simulaci´ on por defecto (la simulaci´ on puede detenerse antes por los motivos indicados en el p´ arrafo anterior).

“Run - All”:

Ejecuta la simulaci´ on durante tiempo indefinido. Esta podr´ a detenerse si se han incluido puntos de ruptura en el c´odigo o si se interrumpe con el bot´ on siguiente. En la zona de estado de la ventana principal (parte inferior) se muestra el tiempo de simulaci´ on.

Ap´endice B

163

ModelSim PE Student Edition

Zoom In Zoom Out Zoom Full Zoom In On Active Cursor

Insert cursor

Delete Find Find Next cursor Previous Transition Transition

Figura B.14: Panel “Wave”.

“Break” “Restart”

Detiene la simulaci´ on en curso. Reinicia la simulaci´ on. Carga de nuevo el modelo binario, sit´ ua el tiempo de simulaci´ on en cero y, opcionalmente, puede mantener el formato dado a algunas ventanas, los puntos de ruptura, etc.

“Step”

Ejecuta la simulaci´ on hasta la siguiente sentencia de c´ odigo. 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 continuaci´ on, se describen los pasos a seguir para insertar punto de ruptura (breakpoint) en el c´ odigo: – Seleccionamos la unidad de dise˜ no en cuyo c´ odigo queremos introducir el punto de ruptura. Las unidades de dise˜ no se muestran en la pesta˜ na “Sim” del panel “Workspace”.

164

A. Urqu´ıa, C. Mart´ın Villalba

Restart

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Run Length

Run Continue Run All Step Step Over Run

Figura B.15: Botones para la simulaci´on y depurado del modelo.

– Hacemos doble clic sobre la unidad de dise˜ no seleccionada. Aparece as´ı un panel con el c´ odigo de dicha unidad de dise˜ no. – En el c´ odigo mostrado en el panel podemos insertar puntos de ruptura usando el rat´ on. Las l´ıneas en las que podemos introducir puntos de ruptura son aquellas cuyo n´ umero de l´ınea est´ a en color rojo. Para introducir el punto de ruptura hacemos clic con el rat´ on 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 di´ alogo denominada “Modify Breakpoints”. Para ello, seguimos los pasos siguientes: – Hacemos clic con el bot´ on derecho del rat´ on en el a´rea del panel donde se muestra el c´ odigo de la unidad de dise˜ no seleccionada. – En el men´ u textual que aparece seleccionamos la opci´ on “Breakpoints...”. A continuaci´ on, se describen los pasos a dar para introducir un punto de ruptura en la l´ınea n´ umero 15 del fichero bufferTriestado.vhd (v´ease la Figura B.16): – Hacemos doble clic sobre la unidad de dise˜ no uut. Aparece as´ı un panel que muestra el c´ odigo del fichero bufferTriestado.vhd. – Hacemos clic con el rat´ on a la izquierda del n´ umero de l´ınea 15. Aparecer´ a un c´ırculo rojo indicando la existencia del punto de ruptura. Para poder modificar el punto de ruptura podemos situarnos con el rat´ on sobre el c´ırculo y hacer clic con el bot´ on derecho. Se despliega un men´ u de texto que nos permite deshabilitar el punto de ruptura (“Disable Breakpoint”) y quitar el punto de ruptura (“Remove Breakpoint”).

Figura B.16: Inserci´on 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 Asignaci´ on concurrente, 22, 48, 59, 83 Atributos, 34

Descripci´ on del hardware mediante esquem´ atico, 3 mediante lenguaje, 3 modular y jer´ arquica, 24 Detector de secuencias, 100, 130 Diagrama de estados, 100 downto, 53

Ejecuci´ on concurrente, 6 Entidad de dise˜ no, 20 Banco de pruebas, 16, 51, 55, 65, 75, 85, Entity, 20 91, 94, 106, 113, 124, 126 Est´ andar IEEE Buffer triestado, 48, 134, 148 1067-1987 (VHDL’87), 4 Bus bidireccional, 80 1076-1993 (VHDL’93), 4 1076-2001 (VHDL-AMS), 4 CAD, 3 1076.6 (VHDL sintetizable), 20 Calendario de eventos, 8 1364-1995 (Verilog), 3 case, 57, 103 1666-2005 (SystemC), 4 Ciclo de dise˜ no, 4 Circuito integrado Fallo ASIC, 5 Abierto, 12 FPGA, 5 Acoplo, 13 PLD, 5 Corto, 13 Codificador Modelo, 13 4:2 con prioridad, 93 Patr´ on, 13 Configuraci´ on, 28 Flip-flop, 102 Constantes generic, 28, 78 JK, 105 Conversor for, 53 BCD a binario, 89 Funci´ on, 44, 70 l´ ogica, 50 Decodificador, 48

168

A. Urqu´ıa, C. Mart´ın Villalba

Casos Pr´ acticos de Dise˜ no de Circuitos Digitales con VHDL

Glitch, 39 HDL, 2 ventajas, 3 if, 55, 102 Inicializaci´ on, 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 s´ olo lectura, 78 Modelo de fallos, 13 Multiplexor, 48 4:1, 54 M´ aquina de estado finito, 99 de Mealy, 99, 119 de Moore, 99, 109 m´etodo de dise˜ no, 99 Netlist, 4 now, 32, 67 Operadores, 35 package, 37, 74, 85, 90, 110 Palabras reservadas, 21 Parametrizaci´ on, 28 Procedimiento, 44, 68 procedure, 106 process, 23, 50, 55, 84, 104 Puerto, 20 in, 20 inout, 20 out, 20 Reloj de la simulaci´ on, 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 l´ ogica secuencial, 102 Tabla de transici´ on 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 Aritm´etico L´ ogica, 82 UUT (Unit Under Test), 16 Verificaci´ on 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 L´ ogica Digital con Dise˜ no 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), Documentaci´ on en l´ınea de VeriBest VB99.0. Suministrada con VeriBest VB99.0.

Related Documents