Vous êtes sur la page 1sur 172

Diseño Digital Utilizando Lógicas

Programables

Versión 0.6
Junio 29, 2005

Guillermo Güichal

Universidad Tecnológica Nacional


Facultad Regional Bahía Blanca
Diseño digital utilizando Lógicas Programables UTN, Facultad Regional Bahía Blanca

Índice
1 Agradecimientos ......................................................................................................... 7
2 Versiones..................................................................................................................... 8
3 Introducción ................................................................................................................ 9
4 Temas Básicos de Diseño Digital ............................................................................. 11
4.1 Diseño Combinacional y Secuencial ................................................................ 11
4.1.1 Flip-Flops y Latches ................................................................................. 11
4.2 Diseño Secuencial Asincrónico y Sincrónico ................................................... 11
4.3 Algunas Notas sobre Diseño Secuencial Sincrónico ........................................ 11
4.3.1 Temporizado y Utilización de Registros................................................... 11
4.3.2 Distribución de Reloj ................................................................................ 11
4.3.3 Máxima Frecuencia de Trabajo ................................................................ 11
4.3.4 Pipelines.................................................................................................... 11
4.3.5 Dominios de Reloj .................................................................................... 11
4.3.6 Metaestabilidad en los Flip-Flops............................................................. 11
4.4 Autómatas de Estados Finitos (Máquinas de estados finitos)........................... 11
4.4.1 Máquinas de Mealy................................................................................... 11
4.4.2 Máquinas de Moore .................................................................................. 11
4.4.3 Codificación de estados. Mínima, One-hot, One-cold, Grey, etc. ............ 11
4.5 Integridad de Señal ........................................................................................... 11
4.5.1 Que afecta la integridad de señal y que es. Como afecta fuera y dentro del
chip (FPGA?) ............................................................................................................ 11
4.5.2 Terminaciones de Señales......................................................................... 12
4.6 Interfaces Eléctricas .......................................................................................... 12
4.7 Potencia y Consumo de los Circuitos ............................................................... 12
5 Diseño Digital con FPGAs y HDLs.......................................................................... 13
5.1 Metodología General de Diseño Digital ........................................................... 15
5.1.1 Especificación y Diseño............................................................................ 17
5.1.2 Verificación............................................................................................... 18
5.1.3 Pasos Finales............................................................................................. 18
5.2 Diseño Digital Utilizando Lenguajes de Descripción de Hardware ................. 18
5.3 Flujo de Diseño para Lógicas Programables .................................................... 19
5.3.1 Flujo de Diseño (Design Flow)................................................................. 19
5.4 Lenguajes de descripción de hardware ............................................................. 22
5.4.1 VHDL ....................................................................................................... 23
5.4.2 Verilog ...................................................................................................... 23
5.4.3 Otros.......................................................................................................... 23
5.5 Herramientas de Desarrollo .............................................................................. 24
5.5.1 Descripción del Diseño ............................................................................. 24
5.5.2 Generación o Traducción.......................................................................... 24
5.5.3 Simulación ................................................................................................ 24
5.5.4 Notas Manejo del tiempo en VHDL ......................................................... 24
6 Dispositivos Lógicos Programables.......................................................................... 27
6.1 Evolución de los Primeros Dispositivos Lógicos Programables ...................... 28

©2005 Guillermo Güichal


Diseño digital utilizando Lógicas Programables UTN, Facultad Regional Bahía Blanca

6.2 CPLDs............................................................................................................... 31
6.3 FPGAs............................................................................................................... 32
6.3.1 Bloque Lógico Programable ..................................................................... 35
6.3.2 Bloque de Entrada / Salida....................................................................... 38
6.3.3 Bloque de Control de Reloj....................................................................... 41
6.3.4 Memoria.................................................................................................... 43
6.3.5 Bloque de Procesamiento de Señal ........................................................... 44
6.3.6 CPUs Embebidas ...................................................................................... 46
6.3.7 Matriz de Interconexión............................................................................ 47
6.4 Granularidad de los Dispositivos Lógicos Programables (PLDs) .................... 48
6.5 Tecnología de Configuración de los PLDs ....................................................... 53
6.6 Tendencias Actuales y Futuras ......................................................................... 54
6.7 Notas a Junio 2005............................................................................................ 54
7 Primeros Pasos con VHDL ....................................................................................... 56
7.1 Notas Preliminares Sobre Formato de VHDL y los Ejemplos ......................... 56
7.1.1 Formato del Código de Ejemplo ............................................................... 56
7.1.2 Capitalización en VHDL........................................................................... 56
7.1.3 Comentarios en VHDL ............................................................................. 56
7.1.4 Delimitadores de Código en VHDL ......................................................... 56
7.2 Estructura Básicas de un Modelo en VHDL..................................................... 57
7.2.1 Entidades y Arquitecturas ......................................................................... 57
7.2.2 Modelos de comportamiento..................................................................... 59
7.2.3 Modelos Estructurales............................................................................... 61
7.3 Elementos del Lenguaje VHDL........................................................................ 64
7.3.1 Palabras Reservadas.................................................................................. 64
7.3.2 Símbolos Especiales.................................................................................. 64
7.3.3 Identificadores........................................................................................... 66
7.3.4 Números.................................................................................................... 66
7.3.5 Cadenas de bits ......................................................................................... 66
7.4 Tipos en VHDL................................................................................................. 67
7.4.1 Tipos Comunes ......................................................................................... 67
7.4.2 Declaración de Tipos ................................................................................ 67
7.4.3 Tipos enumerados ..................................................................................... 68
7.4.4 Subtipos..................................................................................................... 68
7.4.4.1 Tipo Natural y Positivo......................................................................... 68
7.4.5 Tipos Físicos ............................................................................................. 69
7.4.5.1 Tipo Tiempo.......................................................................................... 69
7.4.6 Tipos compuestos...................................................................................... 69
7.4.6.1 Arreglos................................................................................................. 70
7.4.6.2 Arreglos sin Rangos Predeterminados .................................................. 71
7.4.6.3 Records ................................................................................................. 72
7.4.7 Calificación y Conversión de Tipos.......................................................... 72
7.5 Objetos en VHDL ............................................................................................. 73
7.5.1 Constantes ................................................................................................. 73
7.5.2 Señales ...................................................................................................... 73
7.5.3 Variables ................................................................................................... 74

©2005 Guillermo Güichal


Diseño digital utilizando Lógicas Programables UTN, Facultad Regional Bahía Blanca

7.6 Librerías y Paquetes.......................................................................................... 75


7.6.1 Librerías .................................................................................................... 75
7.6.2 Paquetes (Packages).................................................................................. 75
7.6.3 Paquetes de Lógica Estándar del IEEE..................................................... 77
7.6.3.1 Lógica estándar std_logic y std_ulogic definidos en std_logic_1164 .. 78
7.6.3.2 Detección de flancos de señales definidos en std_logic_1164 ............. 79
7.6.4 Aritmética sobre lógica estándar............................................................... 79
7.7 Construcciones Básicas de VHDL.................................................................... 81
7.7.1 Declaración de señales.............................................................................. 82
7.7.2 Operaciones Concurrentes ........................................................................ 83
7.7.2.1 Flujo de datos........................................................................................ 83
7.7.2.2 Palabra reservada AFTER..................................................................... 85
7.7.2.3 Expresión with … select ....................................................................... 86
7.7.2.4 Expresión when, else ............................................................................ 87
7.7.3 Operaciones secuenciales.......................................................................... 88
7.7.3.1 Instrucción WAIT ................................................................................. 88
7.7.3.2 Expresión if… elsif… else.................................................................... 90
7.7.3.3 Expresión null ....................................................................................... 92
7.7.3.4 Expresión case ...................................................................................... 92
7.7.3.5 Procesos (process)................................................................................. 94
7.7.4 Operaciones secuenciales, retardos delta y síntesis .................................. 98
7.7.5 Visibilidad de las declaraciones de objetos en VHDL.............................. 99
8 Más VHDL.............................................................................................................. 101
8.1 Introducción .................................................................................................... 101
8.2 Parámetros Genéricos ..................................................................................... 101
8.2.1 Declaración de parámetros genéricos ..................................................... 101
8.2.2 Uso de componentes con parámetros genéricos ..................................... 104
8.3 Subprogramas: FUNCTION y PROCEDURE ............................................... 108
8.3.1 Procedimientos........................................................................................ 108
8.3.2 Funciones ................................................................................................ 111
8.3.3 Asociación de parámetros por posición y por nombre............................ 113
8.4 Instrucción GENERATE ................................................................................ 113
8.5 Componentes Básicos de Diseño (Primitivas - Primitives) ............................ 114
8.5.1 Utilización de Primitivas desde VHDL .................................................. 114
8.5.2 Librerías de Primitivas (componentes) Específicos para Simulación..... 116
8.5.3 Memoria.................................................................................................. 116
Inferencia de Memorias ...................................................................................... 118
Instancia de Memorias ........................................................................................ 124
8.5.4 Definición de Nuevos Componentes de Diseño ..................................... 125
8.6 Máquinas de Estado ........................................................................................ 129
8.6.1 Codificación de Estados.......................................................................... 133
8.6.2 División de la Señal de Reloj (Clock Enable) ........................................ 134
9 VHDL para Simulación y Verificación .................................................................. 135
9.1 Introducción .................................................................................................... 135
9.2 Bancos de Prueba............................................................................................ 135
9.2.1 Vectores de prueba.................................................................................. 136

©2005 Guillermo Güichal


Diseño digital utilizando Lógicas Programables UTN, Facultad Regional Bahía Blanca

9.2.2 Diseño de un Banco de Pruebas.............................................................. 136


9.2.3 Manejo de tiempo en simulaciones usando VHDL ................................ 137
9.2.3.1 Uso del WAIT y AFTER .................................................................... 137
9.2.3.2 Función NOW..................................................................................... 138
9.3 VHDL (Generalmente) No Sintetizable.......................................................... 139
9.3.1 Instrucciones de lazo FOR, WHILE y LOOP, NEXT y EXIT............... 139
9.3.2 Instrucciones ASSERT y REPORT ........................................................ 142
9.3.3 Manejo de Archivos y Paquete TEXTIO................................................ 143
9.3.4 Palabra reservada ALIAS ....................................................................... 145
9.3.5 Ejemplos de Componentes para Bancos de Prueba ................................ 146
9.3.5.1 Generación de Señal de Reloj ............................................................. 146
9.3.5.2 Generación de una Señal de Reset ...................................................... 147
9.3.5.3 Temporizado de la Interfase de un Bus de Microcontrolador............. 148
9.4 Que Falta sobre VHDL… ............................................................................... 152
10 Buenas Prácticas de Diseño ................................................................................ 153
10.1 Introducción .................................................................................................... 153
10.2 Documentación ............................................................................................... 153
10.3 Guía de estilo para el código HDL ................................................................. 153
10.4 Programación para Diseños Sintetizables....................................................... 156
10.4.1 Diferencias entre Síntesis y Simulación ................................................. 156
10.4.2 División de la Frecuencia Mediante Habilitación del Reloj ................... 156
10.5 Guía de Estilo Para un Buen Diseño de Hardware ......................................... 159
11 SoCs, Cores y Propiedad Intelectual................................................................... 162
11.1 Introducción .................................................................................................... 162
11.2 Presentación de un Core.................................................................................. 162
11.3 Diseño para Verificación (Design For Test)................................................... 162
11.4 Reutilización de Propiedad Intelectual ........................................................... 162
12 Notas Sobre Síntesis con FPGAs........................................................................ 163
12.1 Introducción .................................................................................................... 163
12.2 Diseño y Optimización Para Síntesis.............................................................. 163
12.3 Formato Edif ................................................................................................... 163
12.4 Estructuras Recomendadas para Diseños Sintetizables .................................. 163
12.4.1 Estructuras de Decisión Jerárquicas y Concurrentes (IF vs. CASE) ...... 163
12.4.2 Procesos sincrónicos ............................................................................... 163
12.4.3 etc............................................................................................................ 163
12.4.4 etc............................................................................................................ 163
12.4.5 etc............................................................................................................ 163
12.5 Ejemplos de estructuras sintetizadas............................................................... 163
13 Notas sobre Verificación..................................................................................... 165
13.1 Introducción .................................................................................................... 165
14 Uso de las Herramientas ..................................................................................... 166
14.1 Manejo Básico de Xilinx Project Manager..................................................... 166
14.2 Manejo Básico de Altera Quartus II ............................................................... 166
14.3 Manejo Básico de Actel Libero (o la que sea gratuita)................................... 166
14.4 Manejo Básico de ModelSim.......................................................................... 167
15 Referencias.......................................................................................................... 169

©2005 Guillermo Güichal


Diseño digital utilizando Lógicas Programables UTN, Facultad Regional Bahía Blanca

15.1 Dispositivos Lógicos Programables................................................................ 169


Bibliografía ............................................................................................................. 169
Links de Interés....................................................................................................... 169
15.2 Diseño Digital con PLDs ................................................................................ 170
Bibliografía ............................................................................................................. 170
Links de Interés....................................................................................................... 170
15.3 VHDL ............................................................................................................. 170
Bibliografía ............................................................................................................. 170
Links de Interés....................................................................................................... 170
15.4 Buenas Prácticas de Diseño ............................................................................ 171
Bibliografía ............................................................................................................. 171
15.5 Síntesis ............................................................................................................ 171
Bibliografía ............................................................................................................. 171
Links de Interés (síntesis) ...................................................................................... 171
16 Ejemplos ............................................................................................................. 172
16.1 Ejemplos de Lógica Combinacional ............................................................... 172
16.2.............................................................................................................................. 172
16.3 Ejemplos de Lógica Secuencial ...................................................................... 172
16.4 Divisor Reloj................................................................................................... 172
16.5 Control display 7 segmentos........................................................................... 172
16.6 ... otros ejemplos de laboratorios hechos en clase... ....................................... 172
16.6.1 Interfase Mouse....................................................................................... 172
16.6.2 Controlador VGA.................................................................................... 172
16.7 Ejemplo Completo: UART ............................................................................. 172
16.8 etc, etc ............................................................................................................. 172

©2005 Guillermo Güichal


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

1 Agradecimientos
Con la versión 0.6 llega el aporte de algunos colaboradores. Me gustaría aprovechar
entonces para agregar esta sección y agradecerles su ayuda.

Julio Amoedo de Invap S.E. (www.invap.com.ar) leyó la primer versión y me dio mucha
realimentación para mejorar estas notas. Se que hay secciones que pueden no estar muy
claras, pero traté de seguir sus sugerencias para que todo sea mas entendible.

Salvador Eduardo Tropea, del Instituto Nacional de Tecnología Industrial de Argentina


(INTI - www.inti.gov.ar) me dio algunas sugerencias y me hizo notar algunos puntos que
podían mejorarse. Gracias a esas sugerencias y sus ejemplos reescribí la sección sobre
memorias, agregué algunos comentarios a la sección de VHDL no sintetizable (que en
muchos casos sí es sintetizable) y cambié algunos ejemplos que eran muy específicos de
Xilinx.

©2003 Guillermo Güichal 7


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

2 Versiones
Ver 0.5 (27/06/2005)
Publicación inicial en www.fpga.com.ar

Ver 0.6 (29/06/2005)


Sección de Agradecimientos y Versiones.
Fuentes en las figuras y tablas de terceros
Cambios en la implementación de máquinas de estado (no se si aclaran algo o no:)
Cambios en la descripción de memorias y su uso en VHDL
Algunas notas sobre VHDL sintetizable y no sintetizable
Cambios en la sección sobre primitivas
Traté de usar términos aceptados en castellano en vez de mis "castellanizaciones"
Varias correcciones y cambios menores

©2003 Guillermo Güichal 8


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

3 Introducción
Estas notas son una introducción al diseño digital utilizando lógicas programables y
lenguajes de descripción de hardware. La intención no es hacer un tratamiento exhaustivo
y completo de este tema, sino presentar el material que permitirá comenzar a trabajar lo
más rápido posible. Esto se intenta hacer limitando el contenido y focalizándolo sobre
aplicaciones y ejemplos para diseños sintetizables sobre FPGAs.

Los ejemplos de aplicaciones fueron desarrollados para la placa de desarrollo D2E, DIO1
y DIO2 de Digilent, Inc (www.digilentinc.com). La placa D2E contiene una FPGA
Spartan IIe 200 y varios conectores. Las otras placas se conectan a la D2E y contienen
periféricos, tales como botones, leds, display, conectores PS2 y VGA, etc. Por ese
motivo, en las secciones o ejemplos que utilicen o presenten herramientas de desarrollo, y
en los ejemplos en donde se presenten dispositivos específicos, se utilizarán herramientas
y dispositivos de Xilinx. En las secciones generales, sin embrago, se intentan presentar
dispositivos y herramientas de varios fabricantes para que el lector tenga una visión más
amplia de las alternativas existentes.

Se espera que el lector de estas notas tenga una base de diseño digital. Además se supone
que el lector conoce algún lenguaje de programación y esta familiarizado con la
utilización de herramientas de desarrollo de software. Para el que necesita estudiar los
conceptos básicos de diseño digital se recomienda el libro de John F. Wakerly detallado
al final de esta sección. Este libro, además, contiene una excelente introducción a los
dispositivos lógicos programables. Para el lector que no está familiarizado con ningún
ambiente de desarrollo de software también se da una lista de los documentos y manuales
de Xilinx que permitirán que se entienda rápidamente el uso de las herramientas de
desarrollo. En el futuro se completará una sección introductoria con un repaso de temas
de diseño, tecnologías y técnicas digitales.

Algunas características y limitaciones que deben tenerse en cuenta al leer estas notas son
las siguientes:

• Las notas están principalmente orientadas a síntesis de diseños digitales sobre


FPGAs. Esto debe tenerse en cuenta especialmente en las secciones sobre VHDL,
ya que los temas tratados y los ejemplos presentados se limitan a ese uso del
lenguaje.
• Se tratan de presentar los temas con ejemplos que permitan la rápida utilización y
aprendizaje. Un estudiante debería poder comenzar a hacer diseños bastante
complejos sobre FPGAs solo copiando y modificando el código presentado en los
apéndices y ejemplos, sin realmente tener una base demasiado formal sobre PLDs
y VHDL.
• Se trata de enseñar a través de ejemplos funcionales, que puedan usarse como
plantillas bases para un diseño o que puedan copiarse directamente. En las
secciones sobre VHDL, en muchos casos no se presentará formalmente el uso de

©2003 Guillermo Güichal 9


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

una instrucción, operación o construcción, sino que se darán ejemplos que


muestran su utilización.
• Al no presentar el lenguaje VHDL con todas sus reglas y posibilidades, en
muchos casos se presentan ejemplos que utilizan construcciones antes de haberlas
explicado formalmente. Como se espera que el lector tenga una base de diseño
digital y programación, esto no debería presentar problemas.
• Se pone bastante énfasis en las formalidades y guías que deberían existir al
escribir código (ya sea en un lenguaje de descripción de hardware o cualquier otro
lenguaje de programación). Se presentan los ejemplos con un formato estándar
que se describe en las notas.

Esta es la primera versión de estas notas, y seguramente contiene errores, omisiones o


temas que pueden presentarse de una manera más didáctica. Por favor hacer llegar
cualquier duda, comentario o crítica que ayude a mejorarlas en el foro o wiki del sitio
www.fpga.com.ar.

©2003 Guillermo Güichal 10


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

4 Temas Básicos de Diseño Digital


COMPLETAR CON ALGUNAS NOTAS SOBRE DISEÑO DIGITAL PARA PODER
METER LAS FPGAS y HDLs EN CONTEXTO.

4.1 Diseño Combinacional y Secuencial


4.1.1 Flip-Flops y Latches

4.2 Diseño Secuencial Asincrónico y Sincrónico

4.3 Algunas Notas sobre Diseño Secuencial Sincrónico


4.3.1 Temporizado y Utilización de Registros

4.3.2 Distribución de Reloj

4.3.3 Máxima Frecuencia de Trabajo

4.3.4 Pipelines

4.3.5 Dominios de Reloj

4.3.6 Metaestabilidad en los Flip-Flops

4.4 Autómatas de Estados Finitos (Máquinas de estados finitos)


4.4.1 Máquinas de Mealy

4.4.2 Máquinas de Moore

4.4.3 Codificación de estados. Mínima, One-hot, One-cold, Grey, etc.

4.5 Integridad de Señal


4.5.1 Que afecta la integridad de señal y que es. Como afecta fuera y dentro
del chip (FPGA?)
Ver nota Altera de PLD design line. Chip-level concerns include improper I/O buffer
design and inadequate return-current paths. Package-level issues include high package
inductance, mismatched traces, improper routing and inadequate return-current paths,
while board-level issues include crosstalk, reflections, signal attenuation and EMI/EMC.

©2003 Guillermo Güichal 11


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

4.5.2 Terminaciones de Señales


Usar terminaciones para evitar rebotes en diseños de alta velocidad. Terminaciones
internas en las FPGAs.

4.6 Interfaces Eléctricas


Estándares de interfase posibles con las FPGAs actuales. Resistencias de pull-up/down
internas. Flancos lentos y rápidos. etc.,

4.7 Potencia y Consumo de los Circuitos


Puede ser importante. Potencia estática vs dinámica. Dificultoso de calcular para las
FPGA. Hay herramientas que analizan y calculan. Hay que analizar los requerimientos de
la aplicación para ver si la potencia es una limitación y/o diseñar las fuentes de
alimentación (aplicaciones móviles con baterías, etc.).

Las FPGA tienen grandes cantidades de entradas salidas que pueden requerir mucha
corriente. Se deben usar capacitores de desacople y tener en cuenta las especificaciones
de los fabricantes sobre la cantidad de salidas que pueden cambiar al mismo tiempo.

©2003 Guillermo Güichal 12


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

5 Diseño Digital con FPGAs y HDLs


Para poder atacar un problema complejo (sistema) la mejor manera que tenemos es
dividirlo. De esta manera se pueden atacar problemas de menor complejidad y mas
fáciles de analizar. Este es el camino que generalmente usamos para diseñar un sistema
digital. Las decisiones que se tomen al principio para dividir el problema pueden afectar
el resultado final. En algunos casos debemos volver al principio y replantear la
arquitectura después de haber resuelto el problema. La experiencia y conocimientos sobre
el problema, las posibles soluciones y la tecnologías disponibles ayudarán a que la
decisión que se tome sea la mas acertada. Este proceso se esquematiza en la Figura 1.

Figura 1 Esquema del proceso de diseño de un sistema complejo

©2003 Guillermo Güichal 13


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Un sistema puede estar compuesto por varios subsistemas, no todos ellos digitales o
electrónicos. La primer decisión será entonces que partes del sistema se implementarán
como subsistemas digitales. En el sistema digital, los siguientes pasos se siguen en cada
nivel de la jerarquía del diseño, cada vez con mayor nivel de detalle.

Especificación - Arquitectura - Diseño lógico - Layout (disposición y conexionado)

La especificación es muy importante pare definir bien los límites de lo que se quiere
fabricar. A partir de la especificación se puede definir una arquitectura con los diferentes
componentes que implementan cada función del sistema. Para el diseño se debe definir el
funcionamiento de cada uno de esos componentes.

Un sistema digital y sus componentes pueden definirse a distintos niveles de abstracción


y en tres dominios diferentes: Comportamiento, estructural y físico. En la Figura 2 se
muestra el diagrama "Y" de Gajski y Kahn que representa los niveles de abstracción y
dominios para un circuito.

Figura 2 Diagrama de Gajski - Kahn

Dominio Comportamiento: Describe lo que hace un sistema (funcionamiento)


Nivel Algoritmo: Describe el comportamiento del sistema como operaciones
sobre las entradas para producir las salidas deseadas sin detallar los cambios en el
tiempo ni las señales internas.

©2003 Guillermo Güichal 14


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Nivel RTL: Describe el comportamiento de todas las señales (entradas, internas y


salidas) en el tiempo (para cada ciclo de reloj en sistemas sincrónicos)

Dominio Estructural: Describe al sistema como una interconexión de componentes


(esquemático)
Nivel P-M-S (Processor Memory Switch): Describe la estructura como la
interconexión de elementos de procesamiento, memoria e interconexión, sin
mayores detalles de implementación.
Nivel Registros: Describe la estructura como la interconexión de registros y
lógica de interconexión.

Dominio Físico: Describe la implementación física del sistema (plano).

Para lograr tiempo más rápidos de diseño, menos errores, y mayor productividad, lo ideal
sería poder trabajar al máximo nivel de abstracción posible (algoritmos), sin entrar en los
detalles de bajo nivel. Desafortunadamente, esto no es siempre posible con la tecnología
existente (pero esta cambia permanentemente). El nivel de abstracción dependerá
entonces de la aplicación y restricciones sobre el diseño. Si se debe diseñar un integrado
full-custom analógico es probable que se trabaje al nivel de ecuaciones diferenciales, al
nivel de transistores y haciendo el layout manual. Si se diseña un integrado digital con
bloques predefinidos (IP, Cores) y adquiridos a terceros se trabajará a un nivel de
abstracción mucho mayor (floorplanning, RTL). En el ciclo de diseño con FPGAs, gran
parte del aspecto físico ha sido solucionado por el fabricante. En general se trabaja al
nivel de transferencia de registros con algunas herramientas que ayudan a diseñar a
niveles de algoritmo.

5.1 Metodología General de Diseño Digital


Al desarrollar cualquier sistema digital es importante seguir ciertas pautas de trabajo y
tener en cuenta factores muy diversos para que el diseño pueda terminarse a tiempo y
funcione correctamente. A medida que los diseños se hacen más complejos, la necesidad
de seguir un método ordenado para lograr buenos resultados se hace más importante. Los
lenguajes de descripción de hardware, si se utilizan correctamente, pueden utilizarse en
varios pasos del proceso de desarrollo, no solo para diseñar sino también para especificar
y documentar el sistema que se quiere desarrollar.

Las grandes capacidades de los PLDs y herramientas de diseño disponibles permiten que
los diseños implementados sobre FPGAs sean cada vez mas complejos. En muchos casos
varias personas pueden estar trabajando sobre el mismo producto, incluso en localidades
separadas. Para poder atacar el problema del diseño de sistemas digitales complejos (ya
sea para desarrollos sobre FPGAs, ASICs o PCBs) es importante tener una metodología
de trabajo que permita planificar y ordenar el trabajo.

Como ejemplo, en la Figura 3 se muestra un esquema de un método que permite ordenar


el trabajo de diseño. Según su autor (ver Referencias), la "Metodología Universal de
Diseño" define pasos que permiten:

©2003 Guillermo Güichal 15


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

• Diseñar un dispositivo libre de defectos de manufactura, que funciona de manera


adecuada y se integra con el sistema.
• Diseñar el dispositivo de manera eficiente, sin malgastar recursos ni tiempo.
• Planificar el diseño de manera eficiente, crear un cronograma razonable y asignar
los recursos necesarios para las diferentes tareas de manera ordenada.

En muchos casos el proceso es no lineal. Si se descubren fallas o problemas en las


especificaciones, se debe volver a iterar sobre los pasos anteriores para corregirlos.

El ciclo comienza con un conjunto de requerimientos para la fabricación de un


dispositivo o sistema. Estos requerimientos pueden venir de un cliente, de otro grupo de
trabajo dentro de la misma empresa o del mismo grupo de trabajo que necesita desarrollar
una parte de un sistema mas grande.

Figura 3 - Metodología Universal de Diseño

©2003 Guillermo Güichal 16


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

5.1.1 Especificación y Diseño


Una especificación permite que todas las personas involucradas en un proyecto
comprendan cual es el dispositivo que se va a desarrollar. Las personas que forman parte
de un proyecto incluyen no solo a los desarrolladores, sino también a clientes, gerencia,
personal de otras áreas de la empresa, etc.

Las especificaciones deberían describir la solución de manera de cumplir con los


requerimientos que se piden para el dispositivo. Al haber una especificación formal, las
bases sobre las que trabajar en un diseño quedan preestablecidas y se minimizan los
errores por diferencias de apreciación o entendimiento entre los participantes.

Una especificación debería comprender los siguientes puntos:

• Diagrama en bloques del sistema externo, que muestra como y donde encaja el
dispositivo dentro del sistema completo.
• Diagrama en bloques interno que muestra los principales bloques funcionales.
• Descripción de las entradas/salidas, incluyendo interfaces lógicas, eléctricas y
protocolos de comunicación.
• Estimaciones de tiempos que se deben cumplir, incluyendo tiempos de "setup" y
"hold" para las entradas/salidas y frecuencias de reloj.
• Estimación de la complejidad y/o magnitud del dispositivo, dado en número de
compuertas equivalentes o número de circuitos integrados necesarios.
• Especificación física del dispositivo. Tamaño, empaquetamiento, conectores, etc.
• Estimación del consumo de potencia del dispositivo.
• Precio estimado del dispositivo.
• Procedimientos de verificación y validación para el dispositivo.

Después de escribir las especificaciones es importante hacer una revisión con todos los
miembros del equipo. De esta revisión podrán surgir cosas que no se tuvieron en cuenta
individualmente y que produzcan modificaciones. La especificación también incluye la
metodología de verificación del dispositivo. Estas muchas veces se dejan para el final del
proyecto y no se definen ni llevan a cabo de manera adecuada.

La especificación es un documento activo, que se modifica de acuerdo en los cambios de


requerimientos y a medida que se tiene más información sobre el proyecto.

Una vez que se escribe la especificación se puede utilizar para seleccionar componentes y
tecnologías que se utilizarán para el proyecto. El diseño deberá hacerse siguiendo
métodos aceptados y confiables. El proceso de diseño es en general un ciclo, e incluye
varios pasos intermedios.

©2003 Guillermo Güichal 17


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

5.1.2 Verificación
La verificación engloba varios pasos menores, y al revisar pueden surgir cosas que
obligan a volver atrás hacia pasos anteriores. Dependiendo del dispositivo y tecnología
utilizada, pero en general sigue los siguientes pasos:

• Simulación: es en general un proceso continuo, ya que al simular se pueden


encontrar problemas que hacen volver sobre el diseño y hacer cambios. Las
simulaciones se hacen sobre pequeñas partes del sistema y sobre el sistema
completo. Se debe llevar a cabo una simulación funcional, pero también puede
incluir simulaciones de temporizado, consumo de potencia y otros parámetros.
• Revisión: En este paso se revisan los resultados de la simulación y se analiza el
comportamiento del dispositivo. Es importante que participen ingenieros externos
al proyecto y personas que conozcan el sistema en su totalidad.
• Implementación Física: Una vez que se ha aceptado el diseño se lleva a cabo la
implementación física final del dispositivo.
• Verificación Formal: En este paso se verifica la implementación física para
asegurarse que su funcionamiento coincide con las simulaciones hechas
anteriormente. En este paso se deben también evaluar los tiempos, consumo de
potencia y cualquier otro parámetro de importancia.

5.1.3 Pasos Finales


Si todos los pasos se siguieron correctamente la revisión final debería ser solo una
formalidad. Se verifica que el dispositivo está listo para ser entregado o integrado al
sistema.

La integración y verificación en el contexto del sistema general es muy importante. Si los


pasos se siguieron correctamente, cualquier modificación que surja de esta integración
será en general pequeña y no requerirá grandes cambios.

Cualquier problema o falla que se encuentre debe ser documentarse y analizada para
poder corregirla en una próxima versión del dispositivo y evitarla en el futuro.

5.2 Diseño Digital Utilizando Lenguajes de Descripción de Hardware


Los lenguajes de descripción de hardware (HDLs) permiten modelar sistemas digitales
completos. Mediante diferentes herramientas de software estos modelos pueden luego
sintetizarse para implementarlos como circuitos reales. La utilización de HDLs para
sintetizar sistemas digitales y la utilización de PLDs permiten crear prototipos
funcionales en plazos relativamente cortos. Esto hace que todo el proceso de desarrollo
de un sistema digital sea mucho más simple y rápido en comparación con metodologías
clásicas (desarrollo con discretos sobre PCBs o el diseño de circuitos integrados).
Los modelos de hardware usando HDLs pueden ser estructurales, de comportamiento o
una mezcla de estos dos. A nivel estructural se describe la interconexión y jerarquía entre
componentes. A nivel de comportamiento de hardware se describe la respuesta
entrada/salida de un componente. El comportamiento de un sistema puede modelarse a

©2003 Guillermo Güichal 18


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

distintos niveles de abstracción o detalle: algoritmos y comportamiento general, nivel de


transferencia de registros, nivel de compuertas, etc. El tipo de modelo más usado para
síntesis es el denominado RTL (Register Transfer Level), o de nivel de transferencia de
registros. Existen herramientas que permiten sintetizar circuitos a partir de modelos de
abstracción más elevados, pero en general lo hacen llevando el diseño a un nivel de
descripción como RTL antes de sintetizarlo.
La utilización de HDLs para síntesis puede tener como objetivo la creación de un circuito
integrado de propósito específico (ASIC) o la implementación del circuito en alguna
lógica programable (PLD). Independientemente del objetivo, no todas las construcciones
posibles de los lenguajes de descripción de hardware pueden sintetizarse y transformarse
en circuitos. Esto puede deberse a las limitaciones de las herramientas utilizadas o a que
el circuito descrito por el modelo VHDL no puede implementarse físicamente. En general
el diseñador debe seguir ciertas pautas de modelado, que dependerán de su objetivo y de
las herramientas que utiliza, para que el modelo pueda sintetizarse. Esto es aún más
importante para lograr implementaciones óptimas sobre la arquitectura para la que se está
diseñando el circuito.

5.3 Flujo de Diseño para Lógicas Programables


Cuando se diseña con lógicas programables, cualquiera sea el método usado para diseñar
el circuito (HDLs, esquemáticos, etc.), el proceso desde la definición del circuito por el
desarrollador hasta tenerlo funcionando sobre un PLD implica varios pasos intermedios y
en general utiliza una variedad de herramientas. A este proceso se lo denomina ciclo o
flujo de diseño.

5.3.1 Flujo de Diseño (Design Flow)


Durante el proceso de creación de un sistema digital desde el código fuente
(esquemáticos, VHDL, etc.) a la implementación en un PLD hay varios pasos
intermedios. Para cada uno de estos pasos se utilizan herramientas de software diferentes
que pueden o no estar integradas bajo un ambiente de desarrollo. En muchos casos las
herramientas utilizadas en cada paso del diseño son provistas por diferentes empresas. La
Figura 4 muestra el ciclo de diseño típico para lógicas programables. Dependiendo de las
herramientas utilizadas, este ciclo puede tener variaciones o las tareas llamarse con otros
nombres.
A continuación se describe cada uno de los pasos del ciclo de diseño. Se agrega su
denominación en inglés entre paréntesis, ya que estos son los términos que se encontrarán
en las herramientas de desarrollo.
• Descripción del Diseño: este es el paso en el que se describe el diseño, muchas
veces usando un lenguaje de descripción de hardware como el VHDL. Muchas
herramientas permiten ingresar el diseño no solo como HDLs sino también como
un diagrama esquemático o estructural, una representación gráfica de una
máquina de estados o una tabla de entrada-salida. Estas herramientas simplifican
en gran medida el diseño y simplifican mucho la tarea del diseñador. El código
HDL puede ingresarse utilizando cualquier editor de texto, pero se recomienda

©2003 Guillermo Güichal 19


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

uno que tenga coloreado automático de sintaxis ("syntax highlighting") ya que


ayuda y hace más fácil esta etapa.

Figura 4 - Flujo de diseño para lógicas programables

• Generación o Traducción (Generate, Translate): Este paso tiene sentido


cuando el diseño se hace mediante algunas de los métodos mencionados
anteriormente en vez de en VHDL. En este paso se traducen todos los módulos a
VHDL. Para los módulos ingresados como VHDL, las herramientas generalmente
hacen una copia a una librería interna. En esta etapa se hace un análisis del VHDL
para verificar la sintaxis y semántica de los módulos. También se hace una

©2003 Guillermo Güichal 20


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

elaboración de los archivos, que consiste en replicar los componentes que se


utilizan más de una vez en el diseño para hacer copias únicas y definir un
conexionado adecuado.
• Compilado (Compile): Los simuladores actuales compilan el código VHDL a un
formato que permite una simulación mas rápida y eficaz. Esto se hace en este
paso.
• Simulación y verificación: En este paso se simula el comportamiento del diseño
y se evalúa su comportamiento. La simulación puede hacerse en tres etapas
diferentes del diseño. La primera es sobre el código VHDL original para verificar
el correcto funcionamiento del diseño. La segunda es después de sintetizar el
circuito, y se simulan la implementación real sobre el PLD, ya sea con o sin la
anotación de tiempos. La tercer etapa en la cual se puede simular el diseño es
después de la Ubicación e Interconexión. Esta es la más exacta y la mas engorrosa
y lenta, ya que incluye la información final lógica y temporal el diseño sobre el
PLD.
• Síntesis (Synthesis): En este paso se traduce el VHDL original a su
implementación con lógica digital, utilizando los componentes específicos del
PLD que va a utilizarse. Esta traducción puede llegar hasta el nivel más básico de
elementos lógicos (CLBs, LUTs, FFs) o hasta un nivel superior, en el que el
diseño se presenta en módulos básicos estándar provistos en una librería por el
proveedor del PLD.
• Ubicación e Interconexión (Place and Route): El PLD está compuesto por
muchos bloques idénticos, como se presentó en las secciones anteriores. En este
paso, cada componente del diseño sintetizado se ubica dentro del PLD específico.
También se interconectan los componentes entre sí y con los pines de entrada-
salida.
• Tareas Adicionales: Las tareas adicionales dependen del fabricante y las
herramientas. Puede definirse la interconexión de las con los pines físicos del
PLD ingresar condiciones de entorno físico para guiar a la herramienta de
Ubicación e Interconexión, seleccionar áreas del PLD para ubicar los bloques
lógicos, etc.
• Anotación de Retardos: Como en todo circuito digital, las señales tendrán un
retardo de propagación que influirá sobre su comportamiento. Con estos retardos
puede anotarse el diseño compilado para una simulación que incluya información
de temporizado mas cercana a la implementación real. Una vez sintetizado el
diseño, puede hacerse una estimación de los retardos de propagación que habrá
entre las señales. Después de la ubicación e interconexión, el cálculo de retardos
es mucho mas exacto.
• Generación de Binarios: Después de la Ubicación e Interconexión se genera
algún archivo ya sea para poder utilizar el sistema en un diseño mas complejo o
para programar un PLD.
• Configuración de PLD: Con el archivo binario generado puede configurarse
directamente un PLD a través de alguna de las opciones de configuración. Estas
opciones dependerán de las herramientas y del PLD que se esté utilizando.
• Programación de Memoria (PROM): Muchas FPGA no pueden configurarse de
manera permanente y requieren algún tipo de memoria para leer la configuración

©2003 Guillermo Güichal 21


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

cuando se les aplica tensión de alimentación. En la etapa de producción deben


configurarse memorias PROM y conectarlas a la FPGA en el circuito impreso.
• Verificación (automática): Una vez integrada la FPGA con su programación al
sistema debe hacerse una verificación para controlar que el diseño sobre en la
FPGA funciona bien (las FPGAs pueden tener fallas internas) y que la FPGA se
integra bien al sistema en el que está. Pueden usarse técnicas y herramientas de
verificación automáticas para evaluar si el dispositivo y el diseño están
funcionando como debieran.

En la figura, las flechas de líneas punteadas que vuelven al comienzo indican las
iteraciones que muchas veces se dan al trabajar en un diseño nuevo. Después de simularlo
o configurar un PLD, pueden descubrirse fallas o haber cambios de requerimientos que
obligan al diseñador a volver y modificar la descripción del diseño.

5.4 Lenguajes de descripción de hardware


Los lenguajes de descripción de hardware (HDLs) permiten modelar sistemas digitales
completos. Al utilizar un HDL para modelar un sistema, es importante recordar que se
está modelando hardware, y no escribiendo software. El software se caracteriza por ser de
secuencial, una CPU ejecutará cada instrucción después de la anterior. Los efectos de una
instrucción dependen exclusivamente de los efectos de las instrucciones anteriores. En el
hardware, sin embargo, hay muchas tareas que suceden de manera concurrente y la
variable tiempo juega un papel predominante. Un cambio en el tiempo de propagación
de una compuerta, el retardo de una traza en una plaqueta, o el no cumplir con los
tiempos de establecimiento de un circuito puede cambiar de manera radical el
comportamiento de un sistema electrónico digital. Para poder modelar hardware los
HDLs permiten describir la concurrencia y paralelismo que se observa en un sistema de
hardware (muchas cosas y muchas señales cambian al mismo tiempo).
Usando HDLs, los sistemas digitales pueden describirse de diferentes maneras. Estos
modelos pueden ir desde el nivel abstracto de un algoritmo o el comportamiento general
de un circuito hasta un modelo al nivel de interconexión compuertas lógicas. En una
descripción estructural, se definen de manera precisa las interfases de cada componente
de un sistema y sus interconexiones. Así se arma un jerarquía de componentes, desde los
más básicos hasta el nivel superior que describe el sistema completo. Los HDLs también
permiten describir el comportamiento de los componentes. Para poder describir los
procesos concurrentes que caracterizan un sistema de hardware. Utilizando un conjunto
de instrucciones secuenciales puede modelarse el comportamiento de un sistema digital y
controlar la variable tiempo en los modelos.
Aunque hay muchos lenguajes de descripción de hardware, dos predominan actualmente
el mundo del desarrollo de hardware digital: Verilog y VHDL. De los demás lenguajes,
muchos son propietarios, desarrollados por los distintos proveedores de herramientas o
PLD. En la actualidad casi todos los fabricantes de PLD y proveedores de herramientas
de desarrollo proveen soporte para VHDL y Verilog. En la actualidad están surgiendo
nuevos lenguajes que incorporan mayores facilidades y prestaciones, de acuerdo a las

©2003 Guillermo Güichal 22


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

nuevas tecnologías y necesidades de los desarrolladores. A continuación se presenta una


breve introducción a cada lenguaje

5.4.1 VHDL
Las siglas VHDL provienen de “VHSIC Hardware Description Lenguaje” y a su vez
VHSIC quiere decir “Very High Speed Integrated Circuit”. O sea que VHDL significa
lenguaje de descripción de hardware para circuitos integrados de alta velocidad. Sus
orígenes datan de la década de 1980. El departamento de defensa de Estados Unidos y el
IEEE patrocinaron un programa de desarrollo para un lenguaje con el que se pudieran
modelar circuitos integrados de alta complejidad. Un lenguaje de estas características
permitiría describir los circuitos para su documentación y además modelarlos y
evaluarlos mediante simulaciones antes de incurrir en los grandes gastos de fabricación.
El VHDL nació entonces como un lenguaje de modelado y documentación de sistemas
electrónicos digitales. El lenguaje se estandarizó mediante el estándar 1076 del IEEE en
1987 (VHDL-87). Este estándar fue extendido y modificado en 1993 (VHDL-93) y 2002
(VHDL-2002).
En la actualidad, VHDL se utiliza no solo para modelar circuitos electrónicos sino
también para crear, o sintetizar, nuevos circuitos. La capacidad de sintetizar circuitos a
partir de los modelos en VHDL (u otro lenguaje de descripción de hardware) surgió
después de la creación del lenguaje, con la aparición de herramientas que traducen los
modelos VHDL a circuitos reales.

5.4.2 Verilog
El lenguaje Verilog fue desarrollado por Gateway Design Automation en 1984. En 1988
Synposis presentó la primera herramienta de síntesis basada en Verilog. Más tarde
Cadence Design Systems adquirió Gateway Design Automation y luego “abrió” el
lenguaje para que otros proveedores pudieran desarrollar herramientas de simulación y
síntesis utilizando Verilog. En 1995 el lenguaje Verilog se transformó en un estándar del
IEEE. Mientras que la sintaxis del VHDL es parecido a los lenguajes de programación
Ada y Pascal, el Verilog proviene del C y tiene una sintaxis mas parecida a este.

5.4.3 Otros
En la actualidad los dos lenguajes mencionados, VHDL y Verilog, son los mas utilizados
para la síntesis automática de hardware. Hay mucho esfuerzo de investigación y
desarrollo (e incluso algunas herramientas comerciales) que aceptan la descripción de
algoritmos en otros lenguajes con un mayor nivel de abstracción.

Muchos vendedores de FPGAs proveen herramientas o "toolboxes" que se integran a


lenguajes de modelado como Matlab y Simulink. Una vez probado un algoritmo con estas
herramientas se genera de manera automática el hardware necesario para implementarlo.

Una de las líneas de desarrollo principales es la de poder describir los sistemas con un
nivel de abstracción mayor al RTL en un único lenguaje Después se especificarían las
restricciones necesarias para los resultados y las herramientas decidirían que parte
conviene implementar en hardware y que partes en software.

©2003 Guillermo Güichal 23


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

En general todas las herramientas actuales, aunque permiten describir o modelar los
sistemas con un lenguaje mas abstracto que el RTL terminan generando alguna versión
de código RTL antes de sintetizar un circuito.

5.5 Herramientas de Desarrollo


La facilidad de desarrollo de sistemas sobre PLDs depende en gran medida del software y
hardware que permite crear y probar los diseños de una manera simple y eficiente. Al
conjunto de estas aplicaciones se los denomina herramientas de desarrollo. A
continuación se describen algunas características de estas herramientas para los distintos
pasos del ciclo de diseño.

5.5.1 Descripción del Diseño


En la creación de fuentes se usan diferentes herramientas para facilitar el diseño. Algunas
herramientas comunes:
Estas herramientas incluyen: Modelos de comportamiento. Diferentes niveles. Interfases
gráficas, etc.

5.5.2 Generación o Traducción


Se lleva todos los tipos de fuentes, tales como representaciones gráficas de máquinas de
estado o diagramas esquemáticos. a un lenguaje de descripción de hardware. Los más
comunes son VHDL o Verilog.

5.5.3 Simulación
La simulación de un sistema descrito de modelos en HDL merece algunos comentarios.
Los lenguajes de descripción de hardware modelan o describen, mediante instrucciones
secuenciales, bloques de hardware que funcionarán de manera concurrente, es decir, al
mismo tiempo. Las señales de los bloques pueden afectarse mutuamente. Simular esto
tiene su complejidad, y dentro de los estándares que definen los lenguajes de descripción
de hardware VHDL y Verilog se especifica como se deben simular los procesos
concurrentes.

5.5.4 Notas Manejo del tiempo en VHDL


La simulación en VHDL se basa en incrementos finitos de tiempo. El paso de simulación
estará dado por el tiempo especificado en el código para cambios en las señales o por un
factor denominado retardo delta ("delta delay"). Este retardo delta es un micro-paso de
simulación que se utiliza cuando no se especifica un retardo en la asignación del valor de
una señal. Puede haber una cantidad indefinida de retardos delta en un paso de
simulación. En la descripción que sigue se mencionan de manera general algunas
características de VHDL. Aunque todavía no se ha presentado ninguna característica
específica del lenguaje, el lector con una base de diseño de hardware podrá seguirla sin
problemas. Un proceso en VHDL es la descripción de un bloque de hardware que actúa
de manera concurrente (al mismo tiempo) con todos los demás procesos.

Es importante tener en cuenta que ninguna asignación de valores a una señal en hardware
será inmediata. Es decir, si se utiliza la operación X <= ‘1’ que indica la asignación un

©2003 Guillermo Güichal 24


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

valor lógico ‘1’ a la señal X, este cambio nunca se producirá inmediatamente, sino que
habrá un retardo (como mínimo de un retardo delta) para la asignación. Con esto en
mente, puede analizarse un ciclo de simulación en VHDL que se comporta de la manera
mostrada en la Figura 5.

Al comenzar la simulación (tiempo de simulación cero) se asigna valores iniciales a las


señales. Después de asignar los valores a las señales, se ejecutan todos los procesos hasta
que estos lleguen a un estado de reposo. En general, los procesos incluirán asignaciones
de nuevos valores para algunas señales. Estos cambios o asignaciones en los valores de
las señales se agendan para un tiempo posterior. Las señales recién se actualizarán
después de un retardo, nunca inmediatamente.

Figura 5 - Ciclo de simulación

Cuando los procesos están en un estado de reposo (todos los procesos en VHDL tienen
un estado de reposo) se incrementa el tiempo de simulación como para cambiar la señal
que tiene la próxima transición. Este retardo será el menor tiempo de todas las
asignaciones de señal hecha por los procesos, y puede ser un retardo delta o un tiempo
especificado por el código. Después de cambiar la(s) señal(es) se examinan nuevamente
los procesos para ver si esos cambios estimulan o disparan el comportamiento de algún
proceso o puede continuar la simulación. Si se dispara algún proceso, este se evalúa
nuevamente de la manera descrita anteriormente. Si no se dispara ningún proceso se
procede a incrementar el tiempo hasta la próxima transición de señal. Esto se repite hasta
llegar a un tiempo en la que no hay ninguna transición de señal y todos los procesos están
en reposo. Este proceso de simulación permite obtener resultados determinísticos.

A continuación se presenta un ejemplo para explicar mejor el proceso de simulación en


VHDL. La Figura 6 muestra un circuito digital y los valores iniciales de las señales A, B,

©2003 Guillermo Güichal 25


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

C, X e Y. Todas las compuertas están definidas para no tener retardo de propagación, por
lo que el simulador usará el valor de un retardo delta. A los 50 ns de simulación la
entrada A pasa de ‘1’ a ‘0’.

Figura 6 - Circuito digital combinacional

La siguiente tabla muestra los pasos en la simulación al cambiar la señal A de 1 a 0 a los


50 ns. Cuando cambia A se evalúan los procesos a los que afecta esa señal. El único
proceso que se dispara es el inversor, y su salida X se agenda para cambiar de 0 a 1. En
delta 2 se cambia la señal X y se observa a que procesos afecta. Se agendan para cambiar
las señales Y y C. En delta 3 se cambian esas señales y se nota que solo se afecta el
proceso AND de salida. Se agenda el cambio de C y en delta 4 se cambia C a su valor
final.

Tabla 1 Ejemplo del pasos de simulación y cambios en las señales

Tiempo Delta A B X Y C Proceso


0 ns 1 1 0 1 0 Entrada y salidas estables
50 ns 0 0 1 0 1 0 Cambio en la entrada A. Evaluar inversor
1 0 1 1 1 0 Cambio en X. Evaluar NAND, Evaluar AND
2 0 1 1 0 1 Cambio en Y, C. Evaluar AND
Todos los procesos en reposo (actualización
3 0 1 1 0 0 de salida definitiva)

El pulso de un delta tiene sentido ya que al estar definidos los retardos sobre las
compuertas al valor por defecto de un retardo delta, el tiempo de propagación a través de
dos compuertas (NAND-AND) es mayor que a través de una sola(AND), generando el
pulso (o “glitch”) en la salida C.

©2003 Guillermo Güichal 26


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6 Dispositivos Lógicos Programables


Los dispositivos lógicos programables son circuitos integrados digitales que no tienen
una función predefinida por el fabricante. Su función puede ser definida (o programada)
por el usuario. Permiten reemplazar grandes diseños digitales que antes se
implementaban con componentes discretos (como compuertas y flip-flops) por un solo
integrado. Debido a la gran capacidad lógica que tienen los dispositivos modernos,
sistemas completos pueden desarrollarse sobre un solo circuito integrado. Esto da lugar a
las denominaciones System-on-a-Programmable Chip, o SoPC (sistema sobre un circuito
integrado programable) y System-on-a-Reprogammable Chip (SoRC).

Los dispositivos actuales (CPLD y FPGAs) tienen una capacidad lógica de hasta millones
de compuertas, incluyen interfaces programables para varios estándares de interfase
eléctrica y tienen bloques de funciones especiales embebidos entre la lógica programable
tales como memoria, multiplicadores o CPUs completas. Esta gran capacidad y variedad
de los dispositivos los hace sumamente útiles a la hora de crear prototipos, desarrollo
rápido de nuevos productos, para los productos que deben ser reconfigurables por
naturaleza o productos que se producen en bajos volúmenes y para los cuales no es
económicamente viable crear un integrado a medida.

Uno de los factores más importantes para el auge de las FPGA es el conjunto de
herramientas disponibles. Entre los puntos a destacar de las herramientas de software
disponibles en el mercado pueden nombrarse los siguientes:

• La practicidad de usar lenguajes de descripción de hardware (HDL o Hardware


Description Language) para sintetizar circuitos
• La integración de los flujos de diseño en un solo ambiente que hacen posible el
prototipeado rápido con poco tiempo de uso de las herramientas.
• La integración de los simuladores con el ambiente de desarrollo que permiten una
rápida verificación de los sistemas diseñados
• Las interfases cada vez más amigables, que incluyen interfases gráficas, sistemas
de desarrollo integrados, la capacidad de desarrollar sistemas utilizando diversas
metodologías (esquemático, maquina de estado, HDL, etc.), etc.
• El soporte de diseño para FPGA por parte de las herramientas clásicas utilizadas
para el diseño de circuitos electrónicos (Orcad, etc.).
• La disponibilidad de herramientas gratuitas o a bajo costo por parte de los
vendedores de PLDs
• Las librerías de componentes integradas con las herramientas de software, que
permiten hacer diseños de manera rápida.
• Guías y “Templates” automáticos para el diseño de circuitos básicos.

En resumen, la facilidad de uso de herramientas de desarrollo para PLDs ayudan a que


una gran cantidad de usuarios puedan rápidamente desarrollar un sistema utilizando
PLDs.

©2003 Guillermo Güichal 27


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.1 Evolución de los Primeros Dispositivos Lógicos Programables

Los primeros dispositivos lógicos programables fueron las memorias PROM. Para ello se
utilizan como entradas las líneas de dirección a la memoria. De esta manera la memoria
provee una tabla de decodificación completa de las entradas, y puede utilizarse para
implementar cualquier función lógica combinacional.

Los primeros dispositivos diseñados específicamente para implementar funciones


digitales programables fueron los PLA, introducidos al mercado en la década de 1970 por
Philips.

Figura 7 - Esquema de un PLA

La base teórica de estos dispositivos es que cualquier ecuación lógica puede reducirse a
una suma de productos. El corazón electrónico de estos dispositivos consiste en un
bloque que permite negar las entradas y dos niveles de compuertas: un nivel de
compuertas AND y un nivel OR. Mediante fusibles pueden programarse las
interconexiones entre las entradas y la lógica. Así los PLA permiten implementar
cualquier suma de productos de sus entradas. La Figura 7 muestra un esquema básico de
un típico dispositivo PLA.

Debido a las limitaciones en la velocidad de las conexiones programables y los


problemas en el proceso de manufactura de las PLA, surgieron dispositivos con un solo
nivel de lógica programable denominados PAL (recordar que los PLA tienen dos niveles
programables: un nivel AND y un nivel OR). Los PAL se basan en el mismo principio
que las PLA, pero tienen un nivel de lógica AND programable mientras el nivel de lógica
OR es fijo. Esto limita la cantidad de funciones que pueden definirse con un dispositivo

©2003 Guillermo Güichal 28


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

dado, así que los fabricantes de PAL los ofrecían en una variedad de configuraciones para
adecuarlos a las necesidades del usuario. Muchos PAL además incorporaron registros
sobre las salidas y realimentación para implementar circuitos secuenciales. La Figura 8
muestra un esquema de una posible configuración de un PAL.

Figura 8 - Esquema de un PAL

Los dispositivos denominados GAL son un poco mas complejos que los PAL
mencionados anteriormente. Incluyen un nivel de lógica AND a la entrada y luego un
bloque lógico denominado macrocelda a la salida, en reemplazo del nivel OR. La
denominación GAL fue utilizada en principio por Lattice, y luego licenciada a otros
fabricantes. Las Figura 9 y Figura 10 muestran el diagrama funcional de una GAL
completa y de una macrocelda de un dispositivo GAL22V10 de Lattice Semiconductors.
La macrocelda de estas GAL se denomina OLMC, por "Output Logic Macro Cell".

©2003 Guillermo Güichal 29


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 9 - Diagrama funcional de una GAL 22V10 de Lattice Semiconductors


(Fuente: hoja de datos de Lattice Semiconductors GAL 22V10 - www.latticesemi.com)

Figura 10 - Diagrama funcional de una macrocelda del GAL 22V10 de Lattice Semiconductors
(Fuente: hoja de datos de Lattice Semiconductors GAL 22V10 - www.latticesemi.com)

©2003 Guillermo Güichal 30


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.2 CPLDs
Los CPLDs son dispositivos que combinan varios bloques lógicos similares a las PAL o
GAL con una matriz de interconexión programable. Estos dispositivos se fabrican con
distintas capacidades para adaptarlos a las necesidades del usuario. Como ejemplo, la
familia MAX7000 de alto rendimiento de Altera se manufactura en versiones desde 32
hasta 512 macroceldas, con 36 a 212 entradas/salidas según el dispositivo y
empaquetamiento (packaging) que se elija. Las Figura 11 y Figura 12 muestran la
estructura general y una macrocelda de estos CPLDs. Como se de las figura, estos
dispositivos incluyen además de las macroceldas, un arreglo de interconexión
programable (PIA), una red de distribución de reloj dedicada y bloques de entrada salida
que permiten interfases compatibles con diferentes estándares eléctricos. Los bloques
lógicos AND y OR están ambos incluidos en la macrocelda del dispositivo.

Figura 11 - Estructura funcional de los CPLD MAX7000 de Altera


(Fuente: hoja de datos de Altera Familia MAX7000 - www.altera.com)

©2003 Guillermo Güichal 31


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 12 - Esquema de una macrocelda de los CPLD MAX7000 de Altera


(Fuente: hoja de datos de Altera Familia MAX7000 - www.altera.com)

6.3 FPGAs
La arquitectura de una FPGA consiste en arreglos de bloques lógicos que se comunican
entre si a través de canales de conexión verticales y horizontales. La Figura 13 muestra
un esquema de esta estructura. La principal diferencia entre las FPGA y CPLDs es que en
general los bloques lógicos de las FPGA no implementan la lógica usando compuertas
sino con generadores de funciones. En la siguiente sección se estudiará en mayor detalle
la arquitectura de una FPGA típica.

Figura 13 - Esquema básico de la arquitectura de una FPGA

©2003 Guillermo Güichal 32


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

En las Figura 14 se muestra la arquitectura general de una FPGA de la familia Spartan IIe
de Xilinx. Esta FPGA contiene cinco elementos principales:

• Bloque de entrada-salida (IOB o Input-Output Block): estos bloques proveen la


interfase entre las patitas o "pines" del integrado y la lógica interna.
• Bloque lógico configurable (CLB o Configurable Logic Block): Estos son los
bloques básicos que se utilizarán en la implementación de un circuito digital.
• Bloque de distribución y compensación de reloj (DLL o Delay Locked Loop):
Estos bloques controlan los dominios de reloj dentro del integrado y compensan
por retardos que pueda haber entre el reloj externo y el interno.
• Bloque de memoria (BLOCK RAM): Estos bloques son memorias dedicadas
integradas dentro de la lógica programable.
• Estructura de interconexión: Es una estructura versátil y multi-nivel de
interconexión entre los otros componentes de la FPGA.

Figura 14 - Diagrama en bloques de una FPGA Spartan IIe de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

En las siguientes figuras se muestran algunos ejemplos de la arquitectura general de


algunas FPGAs de distintos fabricantes.

©2003 Guillermo Güichal 33


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 15 - Diagrama en bloques de una FPGA Cyclone II EP2C20 de Altera


(Fuente: hoja de datos Altera Familia Cyclone 2 www.altera.com)

Figura 16 - Arquitectura de una FPGA ProAsicPlus de Actel


(Fuente: hoja de datos Actel Familia ProAsicPlus www.actel.com)

Además de los bloques lógicos básicos, que ocupan la mayor parte de las FPGAs (CLBs,
Logic Array, Logic Tile, etc.), estos dispositivos constan de bloques que cumplen ciertas
funciones específicas. En las siguientes subsecciones se presentan en mayor detalle

©2003 Guillermo Güichal 34


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

algunos de los bloques o módulos específicos que pueden conformar una FPGA. No
todos los bloques se encuentran en todas las FPGA, aunque casi todas tienen la
estructura general presentada al principio de esta sección. La arquitectura específica de
cada FPGA dependerá del fabricante y la aplicación a la que está orientada.

6.3.1 Bloque Lógico Programable


Todas las FPGA tienen algún tipo de bloque lógico programable. Este es el corazón de la
FPGA, y permite implementar las diferentes funciones lógicas. En la Figura 17 se
muestra un esquema del bloque lógico programable (CLB) de una FPGA de la familia
Spartan IIe de Xilinx.

Figura 17 –Esquema del bloque lógico configurable de una FPGA Spartan IIe de Xilinx
(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

Cada CLB esta compuesto por dos bloques iguales denominados “slices”. Cada "slice"
contiene dos generadores de funciones y un multiplexor MUXF5. El multiplexor combina
los resultados de los generadores de funciones dentro de cada "slice" del CLB.
Las dos "slices" están unidas por un multiplexor MUXF6, que puede seleccionar la salida
de una u otra “slice” hacia la salida del CLB. Esto permite implementar cualquier función
de 6 entradas, un multiplexor de 8:1 o determinadas funciones lógicas de asta 19
entradas. Además de poder implementarse lógica combinacional, cada “slice” contiene

©2003 Guillermo Güichal 35


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

recursos para implementar circuitos secuenciales y operaciones aritméticas eficientes. La


Figura 18 muestra estos componentes en más detalle para un ‘slice” del CLB.

Figura 18 - Esquema interno de medio bloque lógico configurable de una Spartan 2e de Xilinx
(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)
En esta figura se ven los generadores de funciones, compuesto por una tabla de entrada-
salida (LUT o Look-Up Table) de cuatro entradas y una salida. Estas tablas pueden
implementar cualquier función lógica de cuatro entradas y una salida, así como también
utilizarse como memorias distribuidas de 16 x 1 bit. Las salidas de las LUT pasan a los
bloques de control, que contiene lógica que permite optimizar funciones aritméticas. Los

©2003 Guillermo Güichal 36


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

elementos que permiten implementar lógica secuencial son los elementos de


almacenamiento que se ven sobre las salidas del “slice”. Estos pueden configurarse como
flip-flops D con reloj o como latches controlado por nivel.

Como ejemplos, y sin entrar en detalles, en la Figura 19 y Figura 20 se muestran dos


ejemplos de bloques lógicos para otras FPGAs. Hay FPGAs que tienen bloques
configurables mas simples y otras (especialmente las de última generación) cuyos
bloques lógicos son bastante más complejos.

Figura 19 - Esquema del CLB de una FPGA Spartan 3 de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 3 www.xilinx.com)

©2003 Guillermo Güichal 37


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 20 - Esquema del Elemento Lógico de una FPGA Cyclone II de Altera


(Fuente: hoja de datos Altera Familia Cyclone II www.altera.com)

6.3.2 Bloque de Entrada / Salida


Las interfaces de entrada-salida son otro de los componentes particulares que tienen las
FPGAs. La familia de FPGAs Spartan IIe de Xilinx, por ejemplo, divide las
entradas/salidas del integrado en bancos que se pueden configurar para tener una interfase
con lógica de diferentes estándares eléctricos de manera independiente. Los bancos se
configuran aplicando diferentes tensiones de alimentación a los pines denominados VccO
y VREF. Al utilizar diferentes valores de VccO para los distintos bancos se podrá tener
un sistema con interfase a diferentes familias lógicas dentro de la misma FPGA. Las
entradas de reloj están asociadas a diferentes bancos de entrada-salida, para permitir que
haya diferentes dominios de reloj con interfases eléctricas diferentes. La Figura 21
muestra un esquema de estos bancos de entrada-salida.

©2003 Guillermo Güichal 38


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 21 –Distribución de los bancos de entrada/salida en una FPGA Spartan IIe de Xilinx
(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)
La siguiente tabla muestra el valor de VccO para las diferentes interfases lógicas.

Tabla 2 - Tensión VccO para diferentes interfases lógicas de la familia Spartan IIe de Xilinx
Valor de VccO Lógica de interfase
3.3V PCI, LVTTL, SSTL3 I, SSTL3 II, CTT, AGP, LVPECL, GTL, GTL+
2.5V SSTL2 I, SSTL2 II, LVCMOS2, LVDS, Bus LVDS, GTL, GTL+
1.8V LVCMOS18, GTL, GTL+
1.5V HSTL I, HSTL III, HSTL IV, GTL, GTL+

Además de la tensión VccO, para varios de las interfases lógicas debe configurarse la
tensión de referencia VREF y agregarse resistencias de terminación sobre la plaqueta en
las entradas-salidas de la FPGA. Cada bloque de entrada-salida tiene una resistencia de
“pull-up” y “pull-down” configurables que permiten fijar el valor lógico mediante
programación.

Internamente, cada bloque de entrada-salida de la familia Spartan IIe de Xilinx tiene la


estructura mostrada en la Figura 22. Los elementos de entrada-salida de las FPGAs de
Altera Cyclone II tienen la estructura mostrada en la Figura 23.

©2003 Guillermo Güichal 39


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 22 - Esquema de un bloque de entrada-salida (IOB) de una FPGA Spartan IIe de Xilinx
(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

Figura 23 - Esquema de un bloque de entrada-salida de una FPGA Cyclone II de Altera


(Fuente: hoja de datos Altera Familia Cyclone II www.altera.com)

©2003 Guillermo Güichal 40


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Los bloques de entrada-salida de muchas FPGAs tienen elementos de almacenamiento


integrados que permiten controlar mejor los tiempos de propagación entre las patitas
(pines) del integrado y la lógica interna. Además cada bloque de entrada-salida cuenta
con “buffers” programables que pueden configurarse para tres estados y colocar la salidas
de la FPGA en alta impedancia (estado ‘Z’).

6.3.3 Bloque de Control de Reloj


El sistema de control del reloj consiste en bloques de control integrados a la red de
distribución de reloj. La red de distribución de reloj en las FPGA asegura retardos parejos
a todos los bloques lógicos de la FPGA. Cada fabricante utiliza una arquitectura diferente
para el control y distribución de reloj. La siguiente Figura 24 muestra el esquema de
distribución de reloj para la familia Spartan IIe de Xilinx.

Figura 24 – Red global de distribución de reloj en la FPGA Spartan IIe de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)
A continuación se presentan dos ejemplos de bloques de control para FPGAs de
diferentes fabricantes.

La familia Spartan IIe de Xilinx tiene bloques específicos para control de reloj
denominados DLL (Delay Locked Loop). La Figura 25 muestra un esquema básico de la
estructura de un DLL. Estos bloques sincronizan el reloj interno al reloj externo del
sistema, controlan el desplazamiento de fase entre los relojes, sincronizan los diferentes
dominios de reloj y aseguran un retardo de distribución del reloj pareja para la lógica
interna de la FPGA.

©2003 Guillermo Güichal 41


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 25 –Esquema básico de un bloque de control de reloj de la FPGA Spartan IIe de Xilinx
(Fuente: hoja de datos Xilinx Spartan 2e www.xilinx.com)
La familia Stratix de Altera tiene los bloques de control de reloj que se muestran en la
Figura 26.

Figura 26 –Esquema de un bloque de control de reloj de la FPGA Stratix de Altera


(Fuente: hoja de datos Altera Familia Stratix www.altera.com)

©2003 Guillermo Güichal 42


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Estos bloques (Enhanced PLL) permiten controlar la fase y frecuencia del reloj, el
sistema de distribución de reloj y el estándar eléctrico de interfase entre otras cosas.

6.3.4 Memoria
La memoria es un componente muy utilizado en diseños digitales. Varias familias de
FPGA contienen bloques de memoria embebida integrados con la lógica programable. En
general estos bloques básicos de memoria pueden utilizarse en diferentes configuraciones
para generar RAMs y ROMs de diferentes tamaños. Además de memorias embebidas, las
FPGAs basadas en memoria SRAM pueden usar las tablas LUT de los bloques lógicos
como memoria.

La Figura 27 muestra un esquema de una celda de memoria básica de la familia Spartan


IIe de Xilinx. Este bloque se denomina BLOCK RAM y es una memoria de puerto dual
(dual-port), que puede leerse y escribirse al mismo tiempo.

Figura 27 – Diagrama de un bloque de memoria de la FPGA Spartan IIe de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

Estos bloques de memoria pueden usarse como memorias de puerto dual, puerto simple,
RAMs o ROMs. Para entender la versatilidad de estos bloques de memoria, en la
siguiente tabla se muestran las opciones de configuración. Las interfases de dirección y
datos (ADDRA, ADDRB, DIA, DOB, DOA) se pueden configurar para diferentes
tamaños de memoria.

©2003 Guillermo Güichal 43


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Tabla 3 - Posibles configuraciones de las celdas de BLOCK RAM de la familia Spartan IIe de Xilinx
Ancho de la palabra de Profundidad de Bus de Bus de datos
datos (bits) la memoria direcciones
1 4096 ADDR<11:0> DATA<0>
2 2048 ADDR<10:0> DATA<1:0>
4 1024 ADDR<9:0> DATA<3:0>
8 512 ADDR<8:0> DATA<7:0>
16 256 ADDR<7:0> DATA<15:0>

Además de poder configurar cada bloque, varios bloques pueden conectarse utilizando
lógica externa para implementar memorias de otros tamaños y colas FIFO o FILO.

La Figura 28 muestra un bloque de memoria de Actel, que puede configurarse como


memoria de puerto simple, dual o multi-puerto.

Figura 28 -Esquema de un bloque de memoria de Actel configurada como memoria multi-puerto


(Fuente: Nota de Aplicación de Actel: "Implementing Multi-Port
Memories in Actel ProAsicPlus Devices" - www.actel.com)

6.3.5 Bloque de Procesamiento de Señal


Varias FPGA contienen bloques específicos que optimizan en hardware ciertas funciones
especiales. Las FPGA de la familia Stratix de Altera, por ejemplo, contienen uno o más
módulos de procesamiento de señal entre los bloques de lógica programable de propósito
general. Estos bloques permiten desarrollar ciertas funciones específicas típicas de las
aplicaciones de procesamiento de señal de manera muy eficiente. Pueden configurarse de
varias maneras diferentes según las necesidades del usuario. Como muestra la Figura 29,
este bloque contiene lógica para implementar operaciones de multiplicación-acumulación
que requerirían de muchos recursos y ciclos de reloj si se implementaran utilizando

©2003 Guillermo Güichal 44


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

lógica de propósito general. Al igual que los otros bloques, los bloques específicos
pueden interconectarse a los demás bloques utilizando la matriz de intercone3xión
programable de la FPGA.

Figura 29 – Bloque de procesamiento de señal de la familia Stratix de Altera


(Fuente: hoja de datos Altera Familia Stratix www.altera.com)

©2003 Guillermo Güichal 45


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.3.6 CPUs Embebidas


La familia de FPGAs de Xilinx Virtex II-PRO contiene una CPU Power PC 405 de IBM
y lógica de interconexión embebida dentro de lógica programable. Esto permite utilizar
toda la potencia de una CPU integrada con la flexibilidad de los periféricos diseñados
mediante lógica programable. Los bloques específicos integrados en el silicio de las
FPGAs se denominan "hardcores". La Figura 30 muestra un esquema de la arquitectura
del Virtex II-PRO.

Figura 30 - CPU PC405 embebida en una Virtex II Pro de Xilinx


(Fuente: hoja de datos Xilinx Familia Virtex 2 Pro www.xilinx.com)

Altera ofrece la FPGA Excalibur que contiene un microcontrolador ARM922T integrado


a un costado de lógica programable. La lógica programable del Excalibur puede ser de
hasta un millón de compuertas. El micro es de arquitectura RISC de 32 bits, y puede
correr a una frecuencia de reloj de hasta 200 MHz.

Por otro lado también pueden diseñarse microcontroladores o procesadores usando


solamente la lógica de configuración de las FPGAs. Altera ofrece el microcontrolador
Nios, de tecnología RISC de 16 bits que puede utilizarse sobre varias de las FPGA de
Altera. A este tipo de diseño se lo denomina "softcore", ya que a FPGA no tiene ningún
bloque específico para la CPU implementado sobre el circuito integrado. Hay muchos
micros "softcore" públicos y propietarios. Xilinx ofrece el Microblaze y Actel ofrecerá un
micro de la familia ARM.

©2003 Guillermo Güichal 46


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.3.7 Matriz de Interconexión


Para poder implementar circuitos lógicos, los elementos lógicos presentados en las
secciones anteriores no solo deben configurarse adecuadamente sino que también deben
conectarse entre si. La estructura de interconexión interna de un PLD consiste en un
conjunto de alambres o trazas que pueden conectarse mediante elementos de conexión
programables. Las herramientas de “localización e interconexión” (place and route) son
las encargadas de decidir en que elementos lógico se implementará la lógica diseñada por
el usuario y como deben programarse las interconexiones para que el diseño funcione
según las especificaciones de tiempo y retardos que se han definido.

A modo de ejemplo, se describirá a continuación la arquitectura de interconexión de las


FPGA Spartan IIe de Xilinx. Estas FPGA tienen dos niveles de interconexión. Por un
lado tienen una interconexión de propósito general a través de la matriz de
interconexionado general o GRM por sus siglas en inglés. Por otro lado contienen
recursos de interconexión local. Además de los ya mencionados, las FPGA Spartan IIe
contienen recursos de interconexión dedicados a señales de tres estados, de entrada-salida
y recursos de interconexión global para la distribución de reloj y señales específicas.

Los recursos de interconexión local, mostrados en la Figura 31, permiten hacer las
conexiones entre los elementos internos de un bloque lógico o CLB, como las tablas de
búsqueda (LUT), los flip-flop y las realimentaciones dentro del CLB. Además, el
interconexionado a este nivel provee conexiones a la matriz de interconexionado general
y a los CLB adyacentes. Las conexiones a los CLB adyacentes permiten optimizar los
diseños al evitar los retardos y la utilización de recursos de la matriz general de
interconexionado.

La mayor parte de las señales se conectarán a través de la matriz general de


interconexionado (GRM). Los elementos de la GRM se encuentran entre los CLB, en los
canales de interconexión horizontales y verticales de la FPGA. Permiten hacer la
interconexión entre las trazas horizontales y verticales y hacia los CLB. A través de ellos
se configuran las conexiones entre CLBs no adyacentes y hacia los bloques de
entrada/salida.

Los recursos de interconexionado global que no forman parte de la GRM permiten


distribuir señales con un fan-out grande, como son las señales de reloj y posiblemente las
señales de reset. La Figura 32 muestra un esquema de la red dedicada de distribución de
señales de alto “fan-out”. Esta red de distribución global tiene dos niveles y puede llevar
las señales de reloj a todos los bloques lógicos con poca diferencia de tiempo (skew)
entre ellos.

©2003 Guillermo Güichal 47


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 31 - Caminos de interconexión local en la FPGA Spartan IIe de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

Figura 32 - Red dedicada de distribución de reloj en la FPGA Spartan IIe de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 2e www.xilinx.com)

6.4 Granularidad de los Dispositivos Lógicos Programables (PLDs)


La granularidad de un dispositivo lógico programable está dada por la funcionalidad
básica que provee cada bloque de configuración lógica, o la relación entre las celdas
lógicas y los recursos de interconexionado. Algunos parámetros para definir la
granularidad de un dispositivo programable son:
• Número de funciones que puede implementar cada celda lógica
• Número de compuertas NAND de dos entradas equivalente por cada celda
lógica

©2003 Guillermo Güichal 48


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

• Número total de transistores por celda lógica


• Área total normalizada de lógica configurable (relación de área lógica/área de
interconexionado)
• Número de entradas y salidas por celda lógica

Algunos dispositivos tienen arquitecturas con celdas lógicas que pueden implementar
funciones lógicas complejas, de varias entradas/salidas. A estas se las denomina de
granularidad gruesa. Otras arquitecturas están formadas por celdas básicas que solo
permiten implementar lógica muy simple. A estas se las denomina de granularidad fina..

La granularidad de un dispositivo lógico influirá en la manera que se implemente una


función lógica dada, en su frecuencia máxima de funcionamiento y en la utilización que
se hace del dispositivo.

Un bloque lógico grande puede implementar lógica más compleja y por lo tanto se
necesitan menos bloques para una función dada. Por otro lado cada bloque consume más
área que puede desaprovecharse.

Una arquitectura de granularidad fina será típicamente más densa y tendrá menor retardo
de interconexión entre celda y celda. Sin embargo, para una función dada, se deberán
conectar un mayor número de celdas. En general la mejor granularidad dependerá de la
aplicación y las restricciones que hay sobre el diseño. Para una FPGA basada en tablas de
búsqueda (Look Up Table o LUT) la mejor relación entradas salidas del bloque lógico es
4 a 1. Esto es lo que utilizan los dos fabricantes principales de FPGAs basados en
tecnología SRAM. Para mayor información ver la sección Referencias.

Algunas características de cada tipo de arquitectura son las siguientes:

Arquitecturas con granularidad fina


• Celdas implementan funciones lógicas parciales de n entradas
• Relación de entradas a registros por celda muy baja (2/4 a 1)
• Ejemplo: ProAsicPlus de Actel

Figura 33 Bloque Lógico (Logic Tile) de la ProAsicPlus de Actel


(Fuente: hoja de datos Actel Familia ProAsicPlus - www.actel.com)

©2003 Guillermo Güichal 49


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Arquitecturas con granularidad media


• Celdas implementan funciones completas de n entradas
• Relación de entradas a registros por celda de 6/8 a 1
• Buenas para implementar máquinas de estado y lógica secuencial compleja
• Ejemplo: Xilinx Spartan 3:

Figura 34 Slice de Spartan 3 de Xilinx


(Fuente: hoja de datos Xilinx Familia Spartan 3 www.xilinx.com)

©2003 Guillermo Güichal 50


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Arquitecturas con granularidad gruesa


• Celdas estilo PLD de arreglos de términos
• Relación de entradas a registros de 32 a 1
• Buenas para lógica combinacional como decodificación de direcciones,
funciones aritméticas,
• Pobres para arquitecturas con colas (pipelines)
• Ejemplo: Altera MAX 3000

Figura 35 Macrocelda de un CPLD MAX3000 de Altera


(Fuente: hoja de datos Altera Familia MAX3000 www.altera.com)

Arquitecturas mixtas
• Combinan celdas con granularidad fina y gruesa
• Muchas veces tienen recursos de interconexión dedicados para cada tipo de
celda
• Ejemplo: ispXPGA de Lattice Semiconductors

©2003 Guillermo Güichal 51


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 36 Unidad Funcional Programable PFU del ispXPGA de Lattice


(Fuente: hoja de datos Lattice Semiconductors Familia ispXPGA - www.latticesemi.com)

©2003 Guillermo Güichal 52


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.5 Tecnología de Configuración de los PLDs


La tecnología .utilizada para configurar los elementos de un PLD, ya sean los bloques
lógicos o las interconexiones, dependen del fabricante y el dispositivo. Entre los
dispositivos reprogramables, se destacan las tecnologías EEPROM, SRAM y Flash. Los
dispositivos que solo pueden configurarse una vez en general utilizan tecnologías de
antifusible. Cada tecnología tiene sus ventajas y desventajas respecto a las otras. En la
Tabla 4 se resumen algunas de estas características

Tabla 4 Características de las Tecnologías de Configuración de PLDs


Tecnología Ventajas Desventajas
EEPROM • No volátil • Requiere tensiones altas para configurar y
• Puede probarse en un 100% borrar
• Software simple • Requiere programador
• Tecnología base muy conocida • Mayor consumo de potencia
• Tolerancia media a la radiación
• Requiere mucha área para implementarse
(integrados grandes)
SRAM • Reconfigurable. Puede cambiarse el • Volátil. Se debe reprogramar después de cortar
diseño solo cambiando la PROM de la alimentación
configuración en la placa final • Requiere memoria (PROM) externa
• No requiere programador • Tiempo de encendido “lento” (debe
• Proceso de manufactura igual que la configurarse)
lógica • Mayor utilización de área en el integrado
• Puede probarse en un 100% • No muy tolerante a la radiación
• Tecnología integrada con la lógica
(manufactura fácil, menor costo)
Flash • No volátil • Requiere programador
• Tiempo de encendido rápido • Requiere tensiones altas
• Menor potencia que SRAM • La misma velocidad que SRAM
• Menor área que SRAM y antifusible • Menor cantidad de reprogramaciones
• Programable sobre la placa (no tan
fácil)
Antifusible • No volátil • No pueden reconfigurarse
• Mayor densidad • Requiere programador
• Mucha tolerancia a la radiación • No puede evaluarse. Si se comete un error, se
(aplicaciones espaciales) pierde el integrado
• Tiempo de encendido muy rápido
• Baja potencia

A continuación se dan algunos ejemplos de dispositivos que utilizan cada tecnología.

SRAM: Virtex II, Virtex4, Spartan2e, Spartan 3 de Xilinx. Stratix, Cyclone y Apex de
Altera
Flash: Actel ProAsic, ProAsicPlus
Antifusible: Actel A54SX, Quicklogic pAsic
EEPROM: Altera MAX7000, Cypress Ultra37000
EEPROM + SRAM: Lattice Semiconductor ispXPGA

©2003 Guillermo Güichal 53


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

6.6 Tendencias Actuales y Futuras


A continuación se nombran algunas tendencias que pueden observarse en la industria de
de las lógicas programables, no solo de los dispositivos en sí sino de las herramientas y
usos de estos dispositivos.

• Desarrollo de FPGAs con mayor capacidad, más velocidad, menos consumo de


potencia y menor costo.
• Integración en hardware sobre las lógicas programables de bloques específicos
como ALUs, componentes para procesamiento digital de señal, integración con
uP y uC, memorias, etc.
• Integración y mezcla entre FPGAs y circuitos integrados de propósito específico
(ASICs). Componentes que pueden pasar directamente de un prototipo sobre una
FPGA a un ASIC sin esfuerzo de diseño adicional.
• Enfoque sobre la reutilización de propiedad intelectual. Modelo de negocios en el
que no solo se provee el hardware (PLDs) sino también propiedad intelectual por
un costo.
• Cambios en las herramientas de software para tener mayor integración entre los
diferentes usuarios y en los distintos pasos del proyecto. Esto incluye el manejo
de grupos de trabajo, el manejo de la propiedad intelectual, la documentación de
proyectos integrada a las herramientas de diseño, la transferencia de los diseños
para FPGAs a ASICs, etc.
• Integración con herramientas y otros software de desarrollo de mayor nivel, como
son Matlab y herramientas para el diseño integrado de software y hardware. (HW-
SW co-design).
• Integración del manejo de configuración de FPGAs con las herramientas de
diseño de plaquetas (PCBs), para poder configurar el interconexionado interno del
SoPC de manera integral con el conexionado hacia los componentes externos.
• Instrumentos, tales como analizadores lógicos, que permiten observar la lógica de
interna de las FPGA en tiempo real al mismo tiempo que se observan otras
señales, externas a la FPGA.
• Sistemas con aplicaciones que utilicen la reconfiguración o reprogramación de las
FPGAs directamente en el producto final según la necesidad del momento.
• Integración de bloques lógicos programables alrededor de lógica fija en ASICs o
integrados estándar.
• etc.

En los primos años probablemente se verá una mayor incorporación de las lógicas
programables en los diseños, junto a una mayor variedad, diversidad, nuevas ideas y
diseños basados en lógicas y plataformas programables.

6.7 Notas a Junio 2005


Estas notas se comenzaron a escribir en el 2003, y a Junio del 2005 muchos de los
aspectos tecnológicos están des actualizados respecto de los dispositivos actuales, y
algunos comentarios sobre tendencias son una realidad. Parece imposible tratar de
actualizar la información para reflejar las últimas tendencias en estas notas. Para eso se

©2003 Guillermo Güichal 54


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

refiere al lector a los sitios web de los fabricantes de FPGAs listados al final de las notas.
La presentación anterior debería servir para poner en tema al lector y presentarle los
conceptos básicos sobre estas tecnologías. Para obtener mas detalles referirse a las
páginas web de los fabricantes (Ver referencias).

©2003 Guillermo Güichal 55


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7 Primeros Pasos con VHDL


7.1 Notas Preliminares Sobre Formato de VHDL y los Ejemplos
Antes de continuar se describirán algunos puntos básicos para poder comprender los
ejemplos y explicaciones que se presentan en las siguientes secciones.

7.1.1 Formato del Código de Ejemplo


En los ejemplos presentados en este texto se tratará de mantener las siguientes reglas para
facilitar su comprensión y el aprendizaje de VHDL.
• Las palabras reservadas de VHDL se escribirán en negrita
• Se seguirá un formato estándar para el código
• Solo se presentarán los casos y construcciones más utilizadas y las orientadas a la
síntesis para FPGAs

7.1.2 Capitalización en VHDL


VHDL no es sensible a la capitalización y no distinguirá las palabras que solo se
diferencian por letras mayúsculas. Por ejemplo, las palabras begin, BEGIN, Begin y
bEGin serán tratadas de la misma manera por el analizador de VHDL

En general es una buena práctica mantener el mismo formato a través de todo el diseño y
por todos los miembros del equipo. En este texto se usarán palabras reservadas en
minúscula con algunas palabras especiales en mayúscula.

7.1.3 Comentarios en VHDL


Los comentarios en VHDL se indican con un doble guión “--". Abracan desde “--" hasta
el final de la línea

Ejemplos:
-- A<= ‘1’ Esto es un comentario de una línea completa. No hace nada
A <= ‘1’; -- Esto es una asignación de la señal a con un comentario al final
-- Esto es un comentario que me dará error porque
pasa a la otra línea y el analizador de VHDL no entiende la segunda línea

En VHDL no existen los comentarios multi-línea, y debe comentarse línea por línea si se
quiere comentar un bloque completo de código

7.1.4 Delimitadores de Código en VHDL


Las instrucciones en VHDL se terminan con “;” y aunque se pueden escribir varias
instrucciones por línea esa práctica no se recomienda y no se usará en este texto.

Ejemplos:
A <= ‘1’; -- Una asignación a la señal A

©2003 Guillermo Güichal 56


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

B <= ‘0’; -- Una asignación a la señal B


C <= ‘0’; D <= ‘1’; -- Doble asignación en una línea NO RECOMENDADO

Los bloques lógicos en VHDL se delimitan por las palabras reservadas begin y end.

Ejemplos:
-- Definición de una arquitectura
architecture Comportamiento of Contador is
begin
-- Instrucciones que modelan la arquitectura
end architecture Comportamiento;

-- Definición de un proceso
P_IncrementoCuenta : process(Clock_IN)
begin
-- Instrucciones que definen el proceso
end process; --Se debe cerrar con la palabra reservada process

7.2 Estructura Básicas de un Modelo en VHDL


Con VHDL, un módulo o componente de hardware se modela en dos secciones. Una es la
interfase del componente, denominado entidad y la otra es la arquitectura que describe
su funcionamiento interno. Este modelo permite esconder los detalles internos de
implementación e incluso definir varias implementaciones para un componente sin
afectar la interfase externa.

7.2.1 Entidades y Arquitecturas


La siguiente Figura 37 ilustra el concepto de definición de un componente en dos
secciones y presenta las palabras clave (en negritas) utilizadas por VHDL para definirlas.
La primer sección declara el componente o entidad y define las señales de interfase Para
declarar la entidad se utiliza la palabra reservada entity.

©2003 Guillermo Güichal 57


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 37 Declaración de un componente en VHDL

La estructura básica mas simple de la declaración se muestra con el siguiente ejemplo de


la declaración de un contador de 6 bits.

entity Contador is
port(
Reset_IN : IN std_logic;
Clock_IN : IN std_logic;
Cuenta_OUT : OUT std_logic_vector(5 downto 0)
);
end Contador;

Cuadro 1 Declaración de Entidad

La palabra reservada entity especifica que comienza con la declaración de una entidad de
hardware. Esta entidad tendrá el nombre “Contador”.A continuación se definen las
señales de interfase mediante la palabra port.

Los tipos de señales de interfase o “ports” pueden tener los siguientes modos:
• IN Señal de entrada al componente
• OUT Señal de salida del componente
• INOUT Señal bidireccional. Usada para interfases de tres estados.
• BUFFER Señal de salida que puede leerse internamente. No recomendada
para diseños sintetizables.

©2003 Guillermo Güichal 58


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

En general, los tipos de los “ports” que se recomiendan para diseños sintetizables son
std_logic y std_logic_vector1, que definen señales de 1 bit o varios bits de ancho
respectivamente.

La entidad termina con la palabra reservada end. Notar el uso del “;” para terminar cada
instrucción y su uso en la separación de la declaración de las señales de interfase.
La descripción del funcionamiento del componente se define en la segunda sección de
definición del componente, denominada arquitectura. De la misma manera que una
función en hardware puede ser diseñada de diferentes maneras, el comportamiento de un
componente puede modelarse de muchas maneras diferentes en VHDL.

En general la sección de arquitectura tendrá la estructura mostrada a continuación.

architecture Comportamiento of Contador is


-- En esta sección se declaran las señales usadas en
-- el modelo

begin – Comienzo de la especificación del comportamiento


-- En esta sección se define el comportamiento
-- utilizando las construcciones de VHDL necesarias
-- según el modelo que se implemente

-- .........

end architecture Comportamiento;

Cuadro 2 Declaración de arquitectura

El modelado del comportamiento puede ser de muchas maneras diferentes, pero en


general pueden dividirse en dos categorías principales. Los modelos de comportamiento y
los estructurales. Estos modelos se presentan por separado a continuación, pero debe
tenerse en cuenta que VHDL no impone restricciones a mezclar los tipos de modelo
dentro de una arquitectura, aunque esta no es una práctica recomendada.

7.2.2 Modelos de comportamiento


En los modelos de comportamiento el funcionamiento del componente se modela a través
del comportamiento de las señales a través de compuertas y registros internos. Este
modelo de funcionamiento puede ser en la forma de un algoritmo general, al nivel de
transferencia de registros (register transfer level o RTL), flujo de datos o una mezcla de
ellos. El elemento de construcción básico en el modelo de comportamiento en VHDL es
el proceso (process).

1
Los tipos std_logic y std_logic_vector están definidos en librerías estándar de IEEE que se describirán
más adelante.

©2003 Guillermo Güichal 59


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

En el siguiente ejemplo se muestra un proceso y una asignación concurrente que definen


el comportamiento del contador de 6 bits declarado más arriba.

architecture Comportamiento of Contador is


-- Declaración de las señales usadas en la arquitectura
signal Cuenta_REG : std_logic(5 downto 0);

begin – Comienzo de la especificación del comportamiento

-- Conexión del registro con el puerto de salida


Cuanta_OUT <= Cuenta_REG;

-- Este proceso cuenta los ciclos de reloj en


-- cada flanco ascendente de Clock_IN
P_IncrementaCuenta : process(Reset_IN, Clock_IN)
begin
if Reset_IN = ‘1’ then
Cuenta_REG <= “000000”; -- Reset vuelve todo a 0
elsif (Clock_IN’event and Clock_IN = ‘1’) then
Cuenta_REG <= Cuenta_REG + 1; -- Incrementa cuenta
end if; -- Fin if(Reset, Clock)
end process; -- Fin de Proceso Incrementa Cuenta
end architecture Comportamiento;

Cuadro 3 Modelo de comportamiento para un contador

Para el siguiente ejemplo, se supone que hay una entidad “LogicaVaria” declarada que
tiene varias entradas y cuya salidas son funciones lógicas AND y OR de las entradas. A
continuación se muestran dos posibles arquitecturas de comportamiento para este
componente.

En el primer ejemplo se utilizan instrucciones concurrentes para asignar las salidas


directamente. En el segundo ejemplo se utiliza un proceso que se disparará ante un
cambio de cualquiera de las entradas. Este proceso cambia el valor de las señales
internas que actúan solo como cables hacia los puertos de salida. El funcionamiento de
ambos modelos es exactamente el mismo y pueden definirse una variedad de modelos
con el mismo comportamiento.

architecture Comportamiento1 of LogicaVaria is


-- No hay señales internas que declarar

begin – Comienzo de la especificación del comportamiento

SalidaAnd_OUT <= Entrada1_IN and Entrada2_IN;


SalidaOR_OUT <= Entrada1_IN or Entrada2_IN;

©2003 Guillermo Güichal 60


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

end architecture Comportamiento1;


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

architecture Comportamiento2 of LogicaVaria is


intSalidaAnd : std_logic; -- Señales internas declaradas
intSalidaOr : std_logic; -- solo para aclarar la lógica

begin – Comienzo de la especificación del comportamiento

SalidaAnd_OUT <= intSalidaAnd;


SalidaOr_OUT <= intSalidaOr;

ProcesoCalculoLogica : process(Entrada1_IN, Entrada2_IN)


begin
intSalidaOr <= Entrada1_IN or Entrada2_IN;
intSalidaAnd <= Entrada1_IN and Entrada2_IN;

end process; -- Fin de ProcesoCalculoLogica

end architecture Comportamiento2;

Cuadro 4 Modelos de comportamiento

7.2.3 Modelos Estructurales


Como al armar una plaqueta con diferentes componentes e interconectarlos, VHDL
permite armar modelos estructurales y así dar una jerarquía al diseño. En los modelos
estructurales se interconectan diferentes componentes utilizando un mapeo de
componentes básicos mediante señales que actúan como cables de interconexión. Las
interconexiones se hacen “mapeando” los puertos definidos en las declaraciones de las
entidades de los componentes básicos.

Para el siguiente ejemplo se supone que existen dos componentes CompuertaAnd y


CompuertaOr predefinidos en la misma librería, ambas con dos entradas y una salida.
Siguiendo el ejemplo anterior para la entidad “LogicaVaria”, una arquitectura estructural
para este componente se muestra en el Cuadro 5.

architecture Estructura of LogicaVaria is


-- Declaración de los componentes básicos utilizados en
-- la arquitectura. Solo es necesario si se utiliza
-- VHDL-87.
component CompuertaAnd
port(EntradaAnd1_IN : IN std_logic;
EntradaAnd2_IN : IN std_logic;
SalidaAnd_OUT : OUT std_logic;

©2003 Guillermo Güichal 61


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

);
component CompuertaOr
port(EntradaOr1_IN : IN std_logic;
EntradaOr2_IN : IN std_logic;
SalidaOr_OUT : OUT std_logic;
);

begin – Comienzo de la especificación de estructura

-- La instrucción “port map” conecta las señales con los


-- puertos de los componentes básicos.
-- El símbolo => indica conexión. A la izquierda
-- están los puertos de los componentes básicos y
-- a la derecha señala las señales o puertos de la entidad
-- superior (en este caso LogicaVaria)

ComponenteBasicoAnd : CompuertaAnd
port map (EntradaAnd1_IN => Entrada1_IN,
EntradaAnd2_IN => Entrada2_IN,
SalidaAnd_OUT => SalidaAnd_OUT
);

ComponenteBasicoAnd : CompuertaOr
port map (EntradaOr1_IN => Entrada1_IN,
EntradaOr2_IN => Entrada2_IN,
SalidaOr_OUT => SalidaOr_OUT
);

end architecture Estructura;

Cuadro 5 Modelo estructural

En este ejemplo se conectaron dos componentes básicos que implementan una compuerta
AND y una OR de dos entradas y una salida para definir el funcionamiento del
componente LogicaVaria. Notar el símbolo de conexión “=>” (diferente al de asignación
para señales “<=” ) y el uso de los separadores “,” entre los diferentes puertos de los
componentes básicos. Otra cosa que se debe destacar es que no hay ningún problema en
que las señales o puertos de varios componentes en la jerarquía tengan el mismo nombre,
como puede verse en la conexión de las señales de salida.

En el modelo estructural pueden apreciarse dos partes principales. Una es la declaración


de los componentes antes del comienzo (begin) de la arquitectura utilizando la palabra
component. La otra es crear una "instancia" (instantiation) de los componentes dentro de
la arquitectura. Instancia se refiere a crear una copia de un componente, dándole un
nombre único dentro del diseño. Puede verse la instancia de un componente como la
creación de una copia del componente dentro del componente actual. Los puertos del
componente se conectan a diferentes señales mediante el mapeo con las palabras port
map. En el ejemplo todos los puertos de los componentes se interconectan de manera

©2003 Guillermo Güichal 62


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

explícita a señales declaradas anteriormente. También pueden dejarse señales abiertas,


por ejemplo cuando no se utilizan algunas salidas. Esto se hace usando la palabra open en
la “instancia”. Por ejemplo, si no se quiere conectar la salida de la compuerta AND,
puede usarse

ComponenteBasicoAnd : CompuertaAnd
port map (EntradaAnd1_IN => Entrada1_IN,
EntradaAnd2_IN => Entrada2_IN,
SalidaAnd_OUT => open
);

lo que dejará desconectada la salida. No pueden dejarse desconectadas las entradas.

En el ejemplo presentado se interconectan los puertos de los componentes con señales


usando una asociación por nombre. Una asociación por nombre es el uso de la expresión
(Puerto => SeñalALaQueSeConecta) que se utiliza para cada señal del puerto del
componente. También puede hacerse una asociación por lugar, pero eso no es
recomendable y no se presentarán ejemplos de ello en este texto.

Muchas herramientas de desarrollo permiten armar un componente con una arquitectura


estructural de manera gráfica. Esto se hace representando cada componente básico por un
símbolo gráfico que tiene indicadas sus puertos de entrada y salida. Estos puertos se
interconectan con líneas como se haría al diseñar un circuito con una herramienta de
captura de esquemáticos (como Orcad o PowerLogic). La herramienta de diseño traduce
luego el diagrama esquemático a su representación en VHDL para el análisis y
elaboración. En la Figura 38 se muestra un ejemplo de representación grafica de un
esquemático tomado de la herramienta ISE 6.2 de Xilinx.

Figura 38 Representación gráfica de un modelo estructural con las herramientas de Xilinx


(Fuente: Captura de pantalla de Herramienta Esquemática ECS de Xilinx)

©2003 Guillermo Güichal 63


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.3 Elementos del Lenguaje VHDL


En esta sección se presentan los elementos básicos del lenguaje VHDL para familiarizar
al lector con algunas expresiones y operadores antes de comenzar con los elementos y
construcciones mas complejas del lenguaje.

7.3.1 Palabras Reservadas


Las siguientes son las palabras reservadas en VHDL. No deberán utilizarse como
nombres de ningún tipo que no sea como instrucciones de VHDL.

abs, access, alter, alias, all, and, architecture, array, assert, attribute
begin, block, body, buffer, bus
case, component, configuration, constant
disconnect, downto
else, elsif, end, entity, exit
file, for, function
generate, generic, group2, guarded
if, impure2, in, inertial2, inout, in, is
label, library, linkage, literal2, loop
map, mod
nand, new, next, nor, not, null
of, on, open, or, others, out
package, port, postponed2, procedure, process, protected2,3, pure2
range, record, register, reject2, rem, report, return, rol2, ror2
select, severity, shared2, signal, sla2, sll2, sra2, srl2, subtype
then, to, transport, type
unaffected2, units, until, use
variable
wait, when, while, with
xnor2, xor
Cuadro 6 Palabras reservadas de VHDL

7.3.2 Símbolos Especiales


Algunos símbolos especiales usados por VHDL y sus y ejemplos se dan en la siguiente
tabla

Los operadores pueden sobrecargarse y tener diferentes significados para diferentes tipos
en diferentes librerías.

2
Estas no son palabras reservadas en VHDL-87
3
Estas no son palabras reservadas en VHDL-93

©2003 Guillermo Güichal 64


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Tabla 5 Símbolos especiales de VHDL


Símbolo Significado Ejemplos de uso
“ Agrupa valores de bits std_logic_vector := “001000”
Forma cadenas de texto “Una cadena”
“una cadena con “”comillas””.”
# Divisor para números en base 2 a 16 2#1001000# -- número binario
16#af125f# -- número hexadecimal
& Operador de concatenación “001” & “111” -- equivalente a “001111”
‘ (comilla Atributos Clock’event A’left B’high
simple) Calificación de tipo ambiguo unsigned’(“10001”)
Caracteres ‘A’ ’c’ ‘ ’
Valores de dígitos de bit ‘0’ ‘1’ ‘Z’ (alta impedancia)
( ) Subprogramas, para agrupar operadores function ()
y dar prioridad en expresiones, etc. (A + B) * 4
* Multiplicación A := A * 4;
+ Suma o identidad A+B
Cuenta_REG + 1
- Resta o negación A–B
Cuenta_REG – 1
, (coma) Separa listas de parámetros port map(A => A, B => B)
. (punto) Punto decimal 0.5 2#0.100#
Jerarquía en librerías use ieee.std_logic_1164.all
/ División A := A / 4;
: Especificación de tipo signal A : std_logic;
constant C : integer;
; Fin de instrucción A_REG <= ‘1’;
< Menor en comparaciones if (A < B) then
= Igual en comparaciones if (A = ‘0’) then
> Mayor en comparaciones if (A > 0) then
[ ]
| (barra Múltiples opciones en una condición when 1 | 2 | 3 => -- Cuando la expresión sea
vertical) -- 1 o 2 o 3
=> Opciones case, when when “000” =>
Mapeo de puertos en arquitecturas port map(A => A, B => B)
estructurales
Para dar valor a bits no asignados de (others => ‘0’)
vectores
** Exponencial
:= Asignación para variables VariableA := 1
/= No igual en comparaciones if (A /= ‘0’) then
>= Mayor o igual en comparaciones if (A >= 2) then
<= Asignación para señales A <= ‘1’; -- A toma el valor ‘1’
Menor o igual en comparaciones if (A <= 3) then
<> Usado para indicar rango indefinidos (natural range <>)
\ Usado para definir identificadores \C:\\Xilinx\CarpetaProyecto\
extendidos
_ (Guión Usado para separar números o cadenas 124_321 2#0110_1100#
bajo) de bits largas b”0100_0110” X”12FD_C46B_4567”

©2003 Guillermo Güichal 65


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.3.3 Identificadores
Los identificadores se utilizan para dar nombre a los elementos de un diseño, ya sea
señales, variables o cualquier otro elemento del diseño.

Los identificadores pueden utilizar los caracteres alfanuméricos y el guión bajo “_”.
Deben comenzar con una letra y no pueden tener mas de dos guiones bajos seguidos ni
terminar con un guión bajo. Recordar que no deben usarse palabras reservadas como
identificadores y que VHDL no diferenciará identificadores solo por las mayúsculas.

Ejemplos:
constant UTN_CUENTA_MAXIMA : integer := 56; -- Una constante
signal CuentaDeReloj_REG : std_logic_vector(3 downto 0); -- Una señal
variable CuentaModulo1_VAR : std_logic_vector(3 downto 0); -- Una variable

A partir de VHDL-93 se permite definir identificadores extendidos utilizando el símbolo


“\”. Estos identificadores extendidos pueden tener cualquier símbolo sin las limitaciones
de los identificadores básicos de VHDL. Esto se hace para poder comunicarse con
herramientas de desarrollo que aceptan identificadores con formatos diferentes a los de
VHDL.

7.3.4 Números
Los números pueden representarse en diferentes bases y formatos. Hay dos tipos básicos
de números, los enteros (integer) y reales (real). Se puede usar notación exponencial con
ambos tipos de número. Los números pueden representarse en cualquier base de 2 a 16
usando #.

Los reales son números representan aproximaciones a números fraccionarios y contienen


un punto decimal con al menos un número antes y uno después. En general los reales no
se utilizan en diseños para síntesis.

Ejemplos de números reales:


1.23 1.2e4 1.23e-4 0.5 2#0.10# 8#0.4#

Ejemplos de números enteros:


1 2 3467 2#01110# 16#0AFD24#

7.3.5 Cadenas de bits


Para poder representar los valores básicos binarios de señales de diferentes anchos VHDL
define las cadenas de bits. Estas pueden estar definidas en base binaria, octal o
hexadecimal

Ejemplos de cadenas de bits


B”1100000” (8 bits) b”100_000” (7 bits) o” 530” (9 bits) O”54” (6 bits)
x”FA” (8 bits) x”A3B6C1” (24 bits) X”F160_1234” (32 bits)

©2003 Guillermo Güichal 66


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.4 Tipos en VHDL


VHDL es un lenguaje de tipos fuertes (strong typing) como el Ada o Pascal4. Esto
significa que no pueden asignarse valores a señales o variables que no sean del tipo
declarado para esa señal o variable. Para poder asignar un tipo diferente, el programador
debe llamar explícitamente a una función de conversión de tipo.

Hay cuatro clases de objetos en VHDL: constantes, variables, señales y archivos. El tipo
de un objeto es muy importante, ya que no solo define que valores podrá tomar, sino
también que operaciones se pueden realizar sobre él.

7.4.1 Tipos Comunes


VHDL tiene solo unos cuantos tipos predefinidos. También está diseñado para que haya
mucha flexibilidad para definir nuevos tipos. En algunos casos los tipos más utilizados no
son los predefinidos sino tipos estándares definidos por el usuario. La tabla presenta
algunos de los tipos más utilizados.

Tabla 6 Tipos más utilizados en VHDL


Tipo Comentario
bolean Tipo buleano, toma los valores TRUE o FALSE
carácter Contiene todos los caracteres ISO de 8 bits
integer Valores enteros. Como mínimo deben incluir los valores desde
el (- 231 + 1) hasta el (231-1)
real Usado para representar valores fraccionarios
time Usado para controlar tiempo en los modelos. Especialmente
importante durante las simulaciones.
std_logic Usada para señales
std_logic_vector Definido a partir de std_logic, permite tener señales de un ancho
de varios bits

7.4.2 Declaración de Tipos


Como ya se mencionó, es muy simple definir nuevos tipos en VHDL. Un tipo que toma
un rango de valores se declara de la siguiente manera

type IdentificadorDeTipo is range MenorValor to MayorValor;


type IdentificadorDeTipo is range MayorValor downto MenorValor;

Cuadro 7 Declaración de tipos

4
A diferencia del C que tiene tipos débiles y en el que pueden asignarse valores de un tipo diferente al
declarado para las variables (tales como asignar a una variable del tipo float un valor int).

©2003 Guillermo Güichal 67


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Ejemplos:
type tdDiaDelMes is range 0 to 31;
type tdHorasDelDia is range 0 to 23;
Mas ejemplos de tipos:
type tdMinutos is range 0 to 59;
type tdUnTipoRaro is range 59355 downto -456;

7.4.3 Tipos enumerados


También pueden declararse tipos que toman un número discreto de valores usando la
declaración:

type IdentificadorDeTipo is (Valor1, Valor2, Valor2, ...);

Cuadro 8 Declaración de tipo enumerado

Ejemplos:
type tdCPUCycle is (fetch, decode, execute1, execute2);
type tdCicloLectura is (comienzo, lectura, fin);
type tdOctal is (‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ’6’, ‘7’);
type tdLogica3Estados is (‘0’, ‘1’, ‘Z’);

7.4.4 Subtipos
Así como se pueden definir nuevos tipos, fácilmente se pueden definir subtipos a partir
de tipos ya declarados. La siguiente expresión permite hacer esto.

subtype Subtipo is Tipo range ValorMenor to ValorMayor;

Cuadro 9 Declaración de subtipos

7.4.4.1 Tipo Natural y Positivo


El estándar VHDL incluye dos subtipos definidos de la siguiente manera. Un tipo muy

subtype natural is integer range 0 to EnteroMasAlto; -- Los enteros de 0 al mas alto


subtype positive is integer range 1 to EnteroMasAlto; -- Los enteros de 1 al mas alto

©2003 Guillermo Güichal 68


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.4.5 Tipos Físicos


VHDL puede definir tipos físicos para representar valores de cantidades físicas del
mundo real. Al declarar un tipo físico se define una unidad primaria y unidades
secundarias. El cuadro muestra algunos ejemplos de declaraciones de tipos físicos.

-- Declaración de un tipo para medidas


type tdLongitud is range 0 to 1E9;
units
um;
mm = 1000 um;
cm = 10 mm;
m = 100 cm;
pulgada = 25400 um; -- Multiplicador debe ser entero
-- No puede ser pulgada = 25.4 mm
pie = 12 pulgada;
end units tdLongitud;

Cuadro 10 Declaración de tipo físico

7.4.5.1 Tipo Tiempo


El tipo físico predeterminado tiempo (time) es muy importante ya que es muy usado al
modelar retardos. La declaración de time es la siguiente.

type time is (rango depende de la implementación);


units
fs;
ps = 1000 fs;
ns = 1000 ps;
us = 1000 ns;
ms = 1000 us;
sec = 1000 ms;
min = 60 sec;
hour = 60 min;
end units time;

Cuadro 11 Tipo físico tiempo (time)

7.4.6 Tipos compuestos


VHDL permite declarar tipos compuestos por mas de un valor. Un tipo compuesto es un
conjunto o agrupación de valores que se trata como una unidad. Los tipos compuestos en
VHDL pueden ser arreglos (array) o records (record).

©2003 Guillermo Güichal 69


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.4.6.1 Arreglos
Un arreglo (array) es una colección de valores todos del mismo tipo. Se describe la
declaración de tipos arreglos con varios ejemplos. Aunque todavía no se han descrito los
objetos variable y constant se usan para ayudar a entender como se accede a los
elementos de un arreglo.

type tdByteC is array (0 to 7) of std_logic; -- Indice


-- creciente
type tdByteD is array (7 downto 0) of std_logic; -- Indice
-- decreciente
-- Tipo auxiliar para los siguientes ejemplos
type tdEstadosControlador is (Inicial, Espera, Ejecucion,
Abrir, Cerrar, Fin);

-- Tipos arreglos a partir de un tipo enumerado


type tdContadorEstados is array (Inicial to Ejecucion)
of natural;
-- O lo mismo pero especificando el tipo original
type tdContadorEstados is array (tdEstadosControlador range
Inicial to Ejecucion) of natural;

-- Una vez que se ha definido un tipo arreglo se pueden definir


-- objetos de esa clase y se direccionan de la siguiente manera

constant PalabraDeControl : tdByteC := (‘0’, ‘1’, ‘0’, ‘0’,


‘1’, ‘0’, ‘1’, ‘0’);
-- La palabra reservada others se refiere a todos los elementos
-- que no han sido nombrados explicitamente
variable PalabraDeControl : tdByteD;
PalabraDecontrol (1) := ‘1’;
PalabraDecontrol (4) := ‘1’;
PalabraDecontrol (6) := ‘1’;
PalabraDeControl := (others => ‘0’); -- Todos los elementos !!!
-- Ahora uso others para definir los elementos 0,2,3,5 y 7
PalabraDecontrol := (1 =>‘1’, 4 =>‘1’, 6 =>‘1’, others => ‘0’);

variable ContadorEstados : tdContadorEstados;


ContadorEstados(Inicial) := 0;
ContadorEstados(Espera) := 0;
ContadorEstados(Inicial) := ContadorEstados(Inicial) + 1;

variable ContadorPrincipio : tdContadorEstados;


-- Ejemplo de asignación por posición
ContadorPrincipio := (0, 0 ,0);

-- Ejemplo de asignaciones nombrada (named)


ContadorPrincipio := (Inicial to Ejecucion => 0);
-- Otro ejemplo
ContadorPrincipio := (Inicial => 0,

©2003 Guillermo Güichal 70


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Ejecucion => 0,
others => 0); -- Queda solo Espera

Cuadro 12 Arreglos

Del ejemplo pueden destacarse varias cosas.


• Un arreglo puede ser ascendente o descendente y eso definirá cual es el elemento
que queda más a la izquierda.
• Un arreglo puede definirse a partir de un tipo enumerado.
• Los elementos de un arreglo pueden accederse usando el nombre del arreglo
seguido del índice entre “( )”. Ej.: Arreglo(0) := …
• Los elementos de un arreglo pueden accederse usando notación por posición e
indicando los valores para todos sus elementos entre “( )” Ej.: Arreglo := (3, 2…)
• Los elementos de un arreglo pueden accederse usando los índices de manera
explícita con notación nombrada. Ej.: Arreglo := (0 =>3, 1 => 2…)
• La palabra reservada others se utiliza para acceder a todos los elementos de de un
arreglo que no hayan sido definidos.

7.4.6.2 Arreglos sin Rangos Predeterminados


VHDL permite definir tipos de arreglos sin rangos predeterminados. Estos arreglos se
denominan unconstrained arrays. El rango se da al declarar un objeto de ese tipo. A
continuación se muestran dos ejemplos de arreglos de este tipo muy utilizados en VHDL.

type std_logic_vector is array (natural range <> ) of std_logic;

type string is array (natural range <> ) of character;

Cuadro 13 Arreglos sin rango predeterminado

El primero es std_logic_vector, definido en el paquete std_logic_1164 y es el tipo más


utilizado para señales de ancho de más de un bit. Los paquetes se presentan más adelante.

El segundo es un tipo predefinido de VHDL, string, y permite definir cadenas de


caracteres. No se utilizan para diseños sintetizables

El valor de los índices o rango se dan al declarar un objeto como se muestra en los
ejemplos

Ejemplos:
-- string. No usado en diseños sintetizables
constant Cadena: string (0 to 10); -- Rango definido explicitamente
variable Cadena: string := “Cadena de caracteres “; -- Rango definido
-- de manera implícita

©2003 Guillermo Güichal 71


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- std_logic_vector. Buena práctica siempre definirla como (MSB downto 0)


constant PalabraControl : std_logic_vector (3 downto 0) := “1001”;
constant PalabraControl : std_logic_vector (15 downto 0) := X“F5D6”;
signal PalabraEntrada : std_logic_vector (3 downto 0);

7.4.6.3 Records
Un record es una colección de valores que no deben ser todos del mismo tipo. Se
presentarán mediante un ejemplo en el cuadro siguiente.

-- Un record que agrupa varios valores para llevar un


-- control de tiempo en horas, minutos y segundos
type tdTiempo is record
seg : integer range 0 to 59;
min : integer range 0 to 59;
horas : integer range 0 to 23;
end record tdTiempo;

-- Declaración y asignación para un objeto del tipo tdTiempo


constant Espera : tdTiempo := (seg => 4, min => 21, horas => 0);

Cuadro 14 Declaración de un record

7.4.7 Calificación y Conversión de Tipos


Si varios tipos definen el mismo valor posible puede ser que un valor se pueda interpretar
de manera ambigua. Para especificar el tipo explícitamente se usa la comilla simple.

Ejemplos:
unsigned’(“01001”) -- “01001” puede interpretarse como signed o unsigned
tdNivelLogico’(high) -- Si tdNivelLogico es un subtipo de tdNivelValido que
-- también puede tomar el valor high

Como VHDL es un lenguaje con tipos fuertes, cuando se necesita convertir de un tipo a
otro se debe especificar una conversión explícitamente. Esto se hace utilizando el tipo al
que se quiere convertir seguido del valor de otro tipo entre paréntesis.

Ejemplos:
real(3) -- Para convertir el entero 3 a real
integer (4.5) -- Para redondear el real 4.5 a entero

©2003 Guillermo Güichal 72


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.5 Objetos en VHDL


Como se mencionara anteriormente, hay cuatro clases de objetos que pueden declararse
en . En esta sección se presentarán las constantes, variables y señales. Los archivos no
pueden usarse para diseños sintetizables y se describirán en otra sección.

7.5.1 Constantes
Las constantes son tipos en las que se almacenan datos que no cambian. Como su nombre
lo indica, se mantienen constantes en el tiempo. Las constantes se utilizan para poder
asignar tipos definidos a valores. Se utilizan para parametrizar valores que se repetirán en
distintos lugares del diseño y evitar “números mágicos”, que aparecen en el código pero
no se entiende bien que significan ni que tipo tienen. En vez de esto, puede definirse un
paquete que contenga todas las constantes usadas en el proyecto, con tipos nombres que
tengan sentido al leer el código.

Las constantes se declaran como se muestra en el cuadro.

-- Declaración de constantes
-- El formato usado en este ejemplo para los
-- identificadores de constantes es el recomendado
-- en varias guías de código VHDL

constant ADC_VALOR_MAXIMO : integer := 3000;


constant ADC_VALOR_MINIMO : integer := -3000;

constant CONTADOR_ANCHO_DE_CUENTA : natural := 2;

constant TIEMPO_SIMULACION_MAXIMO : time = 200 ns;

Cuadro 15 Declaración de constantes

7.5.2 Señales
Las señales son la representación de las conexiones de hardware que toman valores
lógicos. En general deben utilizarse señales al hacer un diseño que será sintetizado. Los
tipos de señales mas utilizados son los mostrados en las declaraciones del cuadro. Estos
tipos se han definido por un estándar del IEEE que se describe más adelante. EL
operador para asignación de valores a una señal es el símbolo “<=”.

-- Declaración de señales usadas en un modelo

signal Reloj : std_logic;


signal Reset : std_logic;
signal InterrupcionCPU : std_logic;

©2003 Guillermo Güichal 73


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

signal Cuenta_REG : std_logic_vector(5 downto 0);


signal ADCData_REG : std_logic_vector(ADC_MSB downto 0);

-- Asignación de valores de señales.


Cuenta_REG <= “0111111”;
ADCData_REG <= ADCData_IN;
Reloj <= ‘1’;
Reloj <= ‘0’;
BufferSalida <= “ZZZZZZZZ”; -- Señal a tres estados
BufferSalida <= (others => ‘Z’) -- Señal a tres estados

-- Asignación de valores de señales con retardo.


Cuenta_REG <= “0111111” after 1 ms;
ADCData_REG <= ADCData_IN after 2 ps;
Reloj <= ‘1’ after 20 ns;
Reloj <= ‘0’ after 20 ns;
BufferSalida <= (others => ‘Z’) after 40 ns;

Cuadro 16 Declaración y uso de señales

En simulación las señales toman sus valores un delta de tiempo después de que se ejecuta
la instrucción, como se explicara en la sección 5.5.3. Al sintetizar un circuito, la
asignación puede verse como una conexión física, o un cable.

7.5.3 Variables
Las constantes pueden almacenar datos para utilizarlos en el modelo. Se asemejan a las
variables de otros lenguajes de programación. Las variables toman los valores
instantáneamente al asignarse en el código. El operador de asignación para las variables
es “:=”. Para diseños sintetizables se recomienda utilizar señales, pero las variables son
muy útiles al diseñar bancos de prueba.

-- Declaraciones de variables
variable A : integer;
variable B : integer := 56;
variable C : natural := 2#100_0111;
variable ValorMaximo_VAR : std_logic_vector(1 downto 0);
variable TiempoDeEspera : time := 0 ns;

-- Asignación de valores de variables


A := 45; -- El tipo de A debe aceptar el valor 45
C := B; -- Ambas variables del mismo tipo
TiempoViejo := TiempoActual;

Cuadro 17 Declaración de variables

©2003 Guillermo Güichal 74


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.6 Librerías y Paquetes


En VHDL los componentes se describen utilizando entidades y definiendo arquitecturas
por separado. Estos bloques se denominarán unidades de diseño. Al analizar el código,
cada unidad se asigna a una librería de una manera dependiente de las herramientas
utilizadas. A esto se lo denominará unidad de librería.

7.6.1 Librerías
Una librería se define como una colección de unidades de librería. Dependiendo de la
herramienta y el sistema operativo de la computadora que se utilice una librería puede ser
una carpeta directorio o una base de datos que contenga los nombres de las entidades y
arquitecturas que le pertenecen. Esto significa que una librería es solo una manera de
agrupar diferentes unidades para organizarlas, darles una jerarquía y poder reutilizarlas de
una manera ordenada. VHDL reserva el nombre de librería work para la librería del
diseño actual.

Si se necesita acceder a entidades, declaraciones o funciones de otra librería se debe


utilizar la instrucción library. La librería work se agrega al diseño en el que se está
trabajando de manera implícita. Supongamos que hay un conjunto de componentes que se
quieren reutilizar y han sido asignados a una librería llamada CompuertasBasicas en
algún diseño anterior. Para utilizar esos componentes se debe agregar lo siguiente antes
de la especificación de una arquitectura.

-- Para usar las compuertas básicas se debe agregar la


-- librería que las contiene

library CompuertasBasicas;

architecture Estructural of LogicaCompleja is


begin
-- Aquí pueden utilizarse los componentes declarados en
-- la librería CompuertasBasicas

end architecture Estructural;


Cuadro 18 Uso de una librería

La localización de la librería no está especificada por VHDL sino por la herramienta que
se está utilizando. Por ejemplo, la herramienta puede tener un menú donde se seleccionan
las librerías y se especifica el lugar dentro del disco rígido donde estas se localizan. Esa
información luego queda guardado en una base de datos para poder procesarla cuando el
analizador encuentra la directiva library en el VHDL.

7.6.2 Paquetes (Packages)


Un paquete (package) en VHDL es otras unidad de diseño además de las entidades y
arquitecturas que contiene definiciones de objetos que pueden ser utilizados por otros

©2003 Guillermo Güichal 75


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

módulos. Las clases de objetos que se puede colocarse en un paquete incluyen


declaraciones de señales, tipos, constantes, funciones, procedimientos y componentes.

-- Declaración de un paquete

package NombrePaquete is
-- Declaraciones de constantes
constant ... ;
-- Declaraciones de tipos
type ... ;
subtype ... ;
-- Declaraciones de señales
signal ...
-- Declaraciones de subprogramas
function F1(...) return ... ;
function F2(...) return ... ;
...
end package NombrePaquete;
-- ----------------------------------------------------- --
-- Definición del cuerpo del paquete

package body NombrePaquete is


function F1(...) is
...

function F2(...) is
...

end package body NombrePaquete;

Cuadro 19 Declaración de paquetes

La estructura de definición de paquete tiene primero una declaración en la que se define


la interfase con el paquete. En esta sección se deben especificar todas las declaraciones
de los ítems que luego serán visibles a las unidades en las que se incluya el paquete. La
segunda sección del paquete es el cuerpo (body) en el cual se implementan los
subprogramas. Esto permite esconder la implementación del funcionamiento de los ítems
del paquete. En el cuadro se muestra el formato general de un paquete.

Las señales que se definen en un paquete serán globales y podrán accederse por cualquier
entidad que utilice el paquete. Lo mismo sucede con los tipos y constantes definidas en el
paquete. Estas podrán ser utilizadas en cualquier archivo en el que se incluya el paquete.

La expresión utilizada para utilizar un paquete de una librería dada redescribe a


continuación

©2003 Guillermo Güichal 76


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- Para agregar un item declarado como NombreItem


-- en un paquete NombrePaquete de una librería
-- NombreLibreria debe usarse la instrucción use

library NombreLibreria; -- Declara que se usara la libreria


use NombreLibreria.NombrePaquete.NombreItem; -- Uso del
-- paquete

-- Para agregar todos los tipos y constantes de


-- una libreria
library NombreLibreria; -- Declara que se usara la libreria
use NombreLibreria.NombrePaquete.all; -- Uso del paquete

Cuadro 20 Uso de un paquete

7.6.3 Paquetes de Lógica Estándar del IEEE


Como puede verse de la sección donde se describen los tipos en VHDL el lenguaje tiene
una gran capacidad para extender los tipos y definir y sobrecargar operadores y
funciones. Para estandarizar el IEEE desarrolló un paquete lógico estándar denominado
std_logic_1164. Aunque no es realmente parte de VHDL, este paquetes es tan utilizado
que casi podría considerarse un aparte del lenguaje. Se recomienda siempre usar los tipos
definidos en estos paquetes, como se detallará mas adelante.

Además de definir el paquete std_logic_1164, el IEEE definió un paquete con


operaciones aritméticas para números representados por vectores de bits. Este paquete se
denomina numeric_std y es el recomendado para diseños sintetizables.

Para utilizar la lógica 1164 del IEEE o los paquetes numéricos estándar con las
operaciones aritméticas sobre la lógica estándar se debe agregar el use de los paquetes
adecuados.

-- Utilización de los paquetes lógicos estándar del IEEE


library ieee;
use ieee.std_logic_1164.all; -- Lógica estándar
use ieee.numeric_std.all; -- Operaciones aritméticas

Cuadro 21 Uso de los paquetes estándar IEEE

©2003 Guillermo Güichal 77


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.6.3.1 Lógica estándar std_logic y std_ulogic definidos en std_logic_1164


El paquete std_logic_1164 dentro de la librería ieee define un tipo std_ulogic con nueve
valores posibles.

Tabla 7 Valores posibles para lógica std_logic


Valor Descripción Valor Descripción
‘U’ Sin inicializar ‘W’ Desconocido débil
‘X’ Desconocido forzado ‘L’ 0 débil
‘0’ 0 forzado ‘H’ 1 débil
‘1’ 1 forzado ‘-‘ No importa
‘Z’ alta impedancia

A partir de esta lógica también se define el subtipo std_logic. Este tipo es lo que se
denomina lógica resuelta ya que incluye funciones que definen que pasa cuando varias
salidas se conectan a una señal.

Los valores débiles y forzados se incluyen para poder modelar hardware que tiene
diferentes capacidades de controlar una señal. Por ejemplo, si una señal tiene un buffer de
tres estados que la maneja (posibles valores ‘0’, ‘1’ y ‘Z’) y además una resistencia de
“pull-up” a la tensión de alimentación con un valor alto (valor ‘H’). Si la salida del buffer
es alta impedancia (‘Z’) el valor de la señal estará dado por la resistencia, pero si el buffer
tiene una salida lógica, esta forzará el valor de la señal mas allá de la resistencia de “pull-
up”.

Del tipo std_logic se define el tipo std_logic_vector que es un arreglo (array) de


std_logic. std_logic_vector es un arreglo sin límites, y el valor de los índices máximo y
mínimo se dan al declarar el objeto de ese tipo.

Estos tipos se nos permite modelar señales y buses de diferentes anchos. Los tipos
std_logic y std_logic_vector son los recomendados para su uso y son los que se usarán
en los ejemplos de este texto.

Ejemplo de uso del tipo std_logic en la declaración de una entidad :


entity Contador is
port(
Clock_IN : IN std_logic;
Reset_IN : IN std_logic;
Cuenta_OUT : OUT std_logic_vector (31 downto 0)
);

Ejemplo de uso del tipo std_logic en la declaración de señales en una arquitectura


signal Cuenta_REG : std_logic_vector (31 downto 0);
signal intFinDeCuenta : std_logic;

©2003 Guillermo Güichal 78


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.6.3.2 Detección de flancos de señales definidos en std_logic_1164


El paquete std_logic_1164 contiene las siguientes funciones que son muy útiles para
simplificar la sintaxis en los procesos para síntesis, como ya se verá mas adelante.

Tabla 8 Funciones de detección de flanco de señales


Función Tipo que Descripción
devuelve
rising_edge(S) boolean Devuelve TRUE si hay un flanco ascendente
sobre S, sino devuelve FALSE.
falling_edge(S) boolean Devuelve TRUE si hay un flanco descendente
sobre S, sino devuelve FALSE.

7.6.4 Aritmética sobre lógica estándar


El paquete numeric_std define dos nuevos tipos a partir de la std_logic. Estos son
signed y unsigned, usados para representar números enteros con y sin signo
respectivamente. Además de esos dos tipos, define las operaciones dadas en la siguiente
tabla. En la tabla se enumeran las operaciones y el resultado de operar sobre los distintos
tipos.

Los paquetes std_logic_arith, std_logic_unsigned y std_logic_signed son paquetes de


Synopsis, Inc. que se distribuyen como parte de la librería IEEE. Estos paquetes cumplen
la misma función para cadenas de bits del tipo std_logic_vector. En std_logic_arith se
definen las operaciones sobre tipos del tipo signed y unsigned, mientras que en los otros
dos se definen conversiones para poder usar las funciones aritméticas con tipos
std_logic_vector. Si se desea utilizar estos paquetes, se debe incluir el paquete
std_logic_arith y solo uno de los otros dos paquetes. Así las señales del tipo
std_logic_vector serán tratadas como con signo o sin signo según cual paquete se haya
incluido. Estos paquetes surgieron antes de la librería estandarizada numeric_std. Como
se mencionó antes, este paquete numeric_std no define operaciones sobre los vectores
estándar, sino que obliga al programador a declarar explícitamente las cadenas de bits
como del tipo signed o unsigned antes de poder realizar operaciones aritméticas sobre
ellos. Al utilizar los paquetes std_logic_arith junto a std_logic_signed o
std_logic_unsigned se puede operar directamente sobre std_logic_vector, por lo que
resultan más prácticos.

A continuación se resumen las opciones de encabezamientos recomendados para usar


diferentes paquetes. Las siguientes líneas deben incluirse de la manera especificada en los
diseños para usar los tipos std_logic_vector.

-- Encabezamiento para usar los tipos std_logic y std_logic_vector sin operaciones


aritméticas
library ieee;
use std_logic_1164.all;

©2003 Guillermo Güichal 79


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- Encabezamiento para usar los tipos std_logic y std_logic_vector y tratarlos como


-- números con signo (complemento a dos) en las operaciones aritméticas
library ieee;
use std_logic_1164.all;
use std_logic_arith.all;
use std_logic_signed.all;

-- Encabezamiento para usar los tipos std_logic y std_logic_vector y tratarlos como


-- números sin signo en las operaciones aritméticas
library ieee;
use std_logic_1164.all;
use std_logic_arith.all;
use std_logic_unsigned.all;

Tabla 9 Resumen de tipos de las operaciones aritméticas


Oper. Operación Tipo del Tipo del Tipo del Longitud del
operando operando resultado resultado
izquierdo derecho
abs valor absoluto signed signed Longitud del operando
- negación
+ suma unsigned unsigned unsigned La mas grande de los
- resta signed signed signed dos operandos
* multiplicación unsigned natural unsigned Suma de las longitudes
/ división natural unsigned unsigned Longitud del izquierdo
rem resto signed integer signed Longitud de operando
mod módulo integer signed signed derecho
= igualdad unsigned unsigned boolean
/= diferente signed signed boolean
< menor unsigned natural boolean
<= menor o igual natural unsigned boolean
> mayor signed integer boolean
>= mayor o igual integer signed boolean
sll corrimientos unsigned integer unsigned Longitud del operando
srl lógicos signed integer signed del tipo vector de bits
rol rotaciones
ror
not negación unsigned unsigned Longitud del operando
signed signed
and operaciones unsigned unsigned unsigned Longitud de los
or lógicas signed signed signed operandos.
nand Ambos deben ser de
nor igual longitud.
xor
xnor

©2003 Guillermo Güichal 80


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.7 Construcciones Básicas de VHDL


En esta sección se presentarán las construcciones básicas de modelado. Como se ha visto
de las secciones anteriores El VHDL es muy flexible y una misma tarea o función puede
modelarse de muchas maneras diferentes. Las descripciones y ejemplos dados estarán
orientados a diseños sintetizables. Los ejemplos se presentarán siguiendo prácticas
recomendadas para el código que facilitan su entendimiento y reutilización. Esto no
significa que no haya otras estructuras y maneras diferentes de definir la misma
funcionalidad para un modelo, o que las presentadas sean las únicas estructuras
sintetizables.

Como se ha visto anteriormente, un componente en VHDL se define utilizando dos


unidades de diseño: entity y architecture. Es buena práctica incluir ambas unidades5
para un componente en un solo archivo que tenga el mismo nombre que la entidad,
separadas de otras declaraciones de entidades y arquitecturas. Esto facilita la
comprensión del diseño, ayuda a localizar rápidamente los componentes y ayuda a
reutilizar el código.

En términos generales, la arquitectura de un componente puede ser un modelo de


comportamiento o estructural. No conviene mezclar ambos modelos y no se hará en este
texto. Un modelo estructural incluye todos los componentes básicos y las señales que los
interconectan. Utiliza las palabras port map para logar esta interconexión, como se
mostró en la sección 7.2.3. Es importante destacar que en VHDL-87 se deben declarar los
componentes básicos que se usarán usando la palabra component antes del begin de la
arquitectura. En VHDL-93 pueden usarse componentes directamente destacando
explícitamente a que librería pertenecen. En los apéndices pueden consultarse ejemplos
de este tipo de modelo que servirán como guía para nuevos diseños.

La estructura general de un componente en el que se modela su comportamiento es la


mostrada en el cuadro. En este esquema se van las declaraciones de la entidad y
arquitectura, y dentro de la arquitectura varias secciones básicas.

En la arquitectura, antes de la palabra begin se definen todas las señales internas que se
utilizarán en el modelo. Después de la palabra begin recién comienza una serie de
operaciones que concurrentes que se ejecutarán en paralelo. Esto permite modelar el
verdadero funcionamiento del hardware ya que en general habrá muchas tareas
ejecutando en paralelo e interactuando entre sí.

entity Componente is
port(

Declaración de puertos de entrada salida

);

5
Si existe más de una arquitectura para una entidad todas deberían estar definidas en el mismo archivo.

©2003 Guillermo Güichal 81


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

end Componente;

-- ---------------------------------------------------- --
architecture Comportamiento of Componente is

Declaración de señales internas del componente

begin – Comienzo de la especificación del comportamiento
-- En esta sección se define el comportamiento
-- utilizando las construcciones de VHDL necesarias
-- según el modelo que se implemente

Serie de operaciones concurrentes:

Operación concurrente 1 (proceso u operación aislada)

Operación concurrente 2 (proceso u operación aislada)

proceso A

Declaración de variables internas del componente
begin -- Comienzo de las instrucciones secuénciales del proceso

operaciones secuenciales

end process;

proceso B

Declaración de variables internas del componente
begin -- Comienzo de las instrucciones secuénciales del proceso

operaciones secuenciales

end process;

end architecture Comportamiento;

Cuadro 22 Esquema básico de un componente en VHDL

7.7.1 Declaración de señales


Todas las señales que se utilizan internamente en el componente deben declararse. Los
tipos recomendados de señales para diseños sintetizables son std_logic,
std_logic_vector, signed y unsigned, como se explicara en la descripción de paquetes en
secciones anteriores. Para diseños sintetizables no se deben asignar valores iniciales a las
señales ya que estos no tienen sentido en una implementación de hardware real.

©2003 Guillermo Güichal 82


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Ejemplos: signal intCuenta : unsigned(5 downto 0);


signal ADCData_REG : signed(11 downto 0);
signal Reloj : std_logic;
signal FinDeCuenta_REG : std_logic;

7.7.2 Operaciones Concurrentes


Las operaciones concurrentes modelan procesos que suceden en paralelo en el hardware.
En VHDL todas las operaciones concurrentes se ejecutan al mismo tiempo. VHDL tienen
varias instrucciones concurrentes y un mecanismo para agrupar instrucciones
secuenciales para que funcionen como una sola instrucción concurrente. Este mecanismo
se denomina proceso (process)

Algo importante a tener en cuanta para diseños sintetizables sobre PLDs es que a una
señal se le debe asignar un valor en solo una operación concurrente. Es decir, dos
operaciones concurrentes no pueden tratar de asignar un valor a la misma señal. Si se
piense que significaría esto en hardware se vería que habría dos o mas componentes o
elementos lógicos con sus salidas conectadas a la misma señal.

7.7.2.1 Flujo de datos


La manera más simple de modelar una operación concurrente es usando las asignación
para señales “<=”. Este operador indica que el resultado de la expresión a la derecha debe
asignarse a la señal de la izquierda. Obviamente la señal y el resultado de la evaluación
de la expresión deben ser del mismo tipo. Estas asignaciones se sintetizarán como lógica
combinacional. La expresión de la derecha debe utilizar operadores que estén definidos
para las señales utilizadas y que además sean sintetizables. Los operadores lógicos
LISTA, de suma “+” y resta “–“ y la multiplicación y división por factores de 2 son en
general sintetizables.

Todas las operaciones mostradas dentro de la arquitectura del siguiente cuadro son
concurrentes, eso significa que no importa en que orden se escriban ya que se evaluarán
todas al mismo tiempo.

library ieee;
use ieee.std_logic_1164.all; -- Lógica estándar

entity Logica2Entrdas is
port (
Entrada1_IN : IN std_logic;
Entrada2_IN : IN std_logic;
SalidaAnd_OUT : OUT std_logic;
SalidaOr_OUT : OUT std_logic;
SalidaNand_OUT : OUT std_logic;
SalidaNor_OUT : OUT std_logic -- No hay ; aquí

©2003 Guillermo Güichal 83


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

);
end Logica2Entrdas;

architecture Comportamiento of Logica2Entrdas is


-- Señales internas utilizadas
signal intSalidaAnd : std_logic;
signal intSalidaOr : std_logic;

begin
-- Operaciones concurrentes que modelan flujo de datos
SalidaAnd_OUT <= intSalidaAnd;
SalidaOr_OUT <= intSalidaOr;
SalidaNand_OUT <= not intSalidaAnd;
SalidaNor_OUT <= not intSalidaOr;

intSalidaAnd <= Entrada1_IN and Entrada2_IN;


intSalidaOr <= Entrada1_IN or Entrada2_IN;

end architecture Comportamiento;

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

library ieee;
use ieee.std_logic_1164.all; -- Lógica estándar
use ieee.std_logic_arith.all; -- Lógica estándar

entity Logica2Entrdas is
port (
Entrada1_IN : IN std_logic;
Entrada2_IN : IN std_logic;
SalidaAnd_OUT : OUT std_logic;
SalidaOr_OUT : OUT std_logic;
SalidaNand_OUT : OUT std_logic;
SalidaNor_OUT : OUT std_logic -- No hay ; aquí
);
end Logica2Entrdas;

architecture Comportamiento of Logica2Entrdas is


-- Señales internas utilizadas
signal intSalidaAnd : std_logic;
signal intSalidaOr : std_logic;

begin
-- Operaciones concurrentes que modelan flujo de datos
SalidaAnd_OUT <= intSalidaAnd;
SalidaOr_OUT <= intSalidaOr;
SalidaNand_OUT <= not intSalidaAnd;
SalidaNor_OUT <= not intSalidaOr;

©2003 Guillermo Güichal 84


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

intSalidaAnd <= Entrada1_IN and Entrada2_IN;


intSalidaOr <= Entrada1_IN or Entrada2_IN;
end architecture Comportamiento;
Cuadro 23 Ejemplo de arquitectura definida como flujo de datos

Otras manera de definir la misma lógica se muestra en el siguiente cuadro. En este


ejemplo no se utilizan señales internas, sino que todas las salidas se definen como
funciones de las entradas. En general las herramientas de síntesis son los suficientemente
“inteligentes” como para optimizar esta lógica y sintetizar ambas arquitecturas a la misma
implementación. Esta implementación dependerá del PLD que se esté utilizando.

architecture Comportamiento of Logica2Entrdas is


begin
-- Operaciones concurrentes que modelan flujo de datos
SalidaAnd_OUT <= Entrada1_IN and Entrada2_IN;
SalidaOr_OUT <= Entrada1_IN or Entrada2_IN;
SalidaNand_OUT <= not (Entrada1_IN and Entrada2_IN);
SalidaNor_OUT <= not (Entrada1_IN or Entrada2_IN);

end architecture Comportamiento;

Cuadro 24 Otro ejemplo de flujo de datos

7.7.2.2 Palabra reservada AFTER


En los siguientes ejemplos se presentan asignaciones de señal que utilizan la palabra
clave palabra clave after.

-- Operaciones concurrentes que modelan flujo de datos


-- con retardo entre cambios en las entradas y salidas
-- a la lógica
Salida1_OUT <= Entrada1_IN and Entrada2_IN after 20 ns;

Logica1 <= Entrada1_IN or Entrada2_IN after 40 ps;

Registro_REG <= not (Entrada1_IN and Entrada2_IN) after 4 ps;

Salida_OUT <= not (Entrada1_IN or Entrada2_IN) after 2 ms;

Cuadro 25 Uso de la palabra AFTER

Como VHDL permite modelar el comportamiento eventos en el tiempo, incluye la


palabra reservada after que en el contexto presentado significa “después de” “luego de”.
Esta palabra permite modelar retardos entre el evento que provoca los cambios en una

©2003 Guillermo Güichal 85


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

señal y la actualización de la señal. Mediante esta palabra se pueden modelar retardos en


compuertas, tiempos de repuesta de componentes, etc. La palabra after no es tenida en
cuanta al sintetizar un diseño, ya que los retardos en un circuito sintetizados dependerán
del PLD y de cómo se haya implementado la lógica.
La palabra reservada alter puede ser utilizada en cualquier asignación de señal, ya sea en
una instrucción concurrente o secuencial.

7.7.2.3 Expresión with … select

La expresión with … select modela un multiplexor, en el que de acuerdo a alguna señal


de control puede seleccionarse el valor a aplicar a una señal . El formato y algunos
ejemplos se muestran en el cuadro.

-- Formato general de la expresión "with... select"


with SenalDeControl select
SenalDeDestino <= Fuente1 when Condicion1,
Fuente2 when Condicion2,
...
FuenteN when others;

-- Ejemplo 1 – Con SenalDeControl de 2 bits


with SenalDeControl select
SenalDeDestino_OUT <= Fuente1_IN when “00”,
Fuente2_IN when “01”,
Fuente4_IN when “10”,
Fuente5 when others;

-- Ejemplo 2 - Operación concurrente with ... select


with Seleccion_IN select
Salida1_OUT <= Datos1_IN when "001",
Datos2_IN when "010",
“010101” when "100",
"XXXXXX" when others;

Cuadro 26 Uso de la expresión WITH … SELECT

Deben especificarse todos los casos, y para ello es conveniente usar la palabra others
para asignar los valores que faltan y completar los casos. Se debe tener en cuenta que los
valores posibles de las señales del tipo std_logic no son solo ‘1’ y ‘0’, sino que hay otros
tales como ‘Z’, ‘U’. Eso hace que haya más combinaciones posibles en un select que las
esperadas. Como no tiene sentido preguntar por opciones como ‘Z’ o ‘U’ ya que esto no
es sintetizable y probablemente ni siquiera tenga sentido durante simulaciones, la palabra
others debe incluirse siempre para el último caso y así evitar problemas.
Otro puno importante es que muchas herramientas aceptan el valor ‘X’ para las señales
de salida. Esto se muestra en el Ejemplo 2, y permite que se optimice la lógica en el
momento de la síntesis.

©2003 Guillermo Güichal 86


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.7.2.4 Expresión when, else


La expresión when … else es otra operación concurrente que puede usarse para modelar
lógica con prioridades.

-- Formato de when... else


SenalDeDestino <= Fuente1 when Condicion1 else
Fuente2 when Condicion2 else
...
OtraFuente when Condicion3 else
FuenteN ; -- Caso por defecto

-- Ejemplo 1 de when... else con la misma señal de control


SenalDeDestino_OUT <= Fuente1 when SenalDeControl=”00” else
Fuente2 when SenalDeControl=”01” else
Fuente3 when SenalDeControl=”10” else
Fuente4 ; -- Caso por defecto

-- Ejemplo 2 de when... else con condiciones varias


SenalDeDestino_OUT <= Fuente1 when Control = ”00” else
Fuente2 when Control /= ”01” else
Fuente3 when OtroControl = ”101” else
Fuente4 ; -- Caso por defecto

-- Ejemplo 3 de when... con una condición compleja


SenalDeDestino <= ‘1’ when X = ‘0’ and Y = ‘1’;

-- Ejemplo 3 de when... con una condición compleja y ejemplos de


-- la palabra after
OtraSenal <= ‘1’ after 4 ns when X = ‘0’ and Y = ‘1’
else ‘0’ after 3 ns;

Cuadro 27 Uso de la expresión WHEN… ELSE

En el ejemplo 1 se modela una lógica de asignación que toma decisiones sobre una sola
señal de control. Muchas herramientas reconocerán en esto un multiplexor y lo
sintetizarán como tal, pero no es la manera recomendable de modelarlo, ya que las
palabras else indican prioridad. En esta operación no es necesario especificar todos los
casos, pero debe tenerse en cuanta que al no hacerlo se inferirá un match para guardar el
valor de salida anterior.

Las condiciones de asignación a su vez no deben ser necesariamente sobre la misma señal
de control, y esto se muestra en el ejemplo 2. En este caso no se infiere un multiplexor
sino que se genera lógica combinacional con prioridades para implementar el circuito
modelado. La segunda condición se prueba solo si no se cumple la primera, la tercera si
no se cumplen ni la primera ni la segunda, y así hasta llegar a la última. Si ninguna de las
condiciones se cumple se mantendrá el valor anterior utilizando un “latch”. Para evitar

©2003 Guillermo Güichal 87


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

este “latch“ se debe incluir el último else sin condición final y asignar un valor por
defecto.

7.7.3 Operaciones secuenciales


Antes de presentar los procesos, que son la operación concurrente clave, se deben
presentar las operaciones secuenciales. Las instrucciones secuenciales se ejecutarán una
tras otra, de manera similar a las instrucciones de un lenguaje de programación
convencional. La principal diferencia es que el bloque de instrucciones secuenciales
agrupadas por un proceso se ejecutarán en paralelo con los otros procesos y operaciones
concurrentes. En la sección sobre procesos se explicará este mecanismo en más detalle.

7.7.3.1 Instrucción WAIT


Además de la palabra reservada after presentada anteriormente, la otra instrucción que
modela el tiempo en VHDL es la instrucción wait. Esta instrucción es una instrucción
secuencial, y por lo tanto solo se utilizará dentro de un proceso. Permite suspenderlo por
un período determinado de tiempo o hasta que se cumpla alguna condición. Los usos de
la instrucción wait y algunos ejemplos se muestran en el cuadro.

-- Formatos posibles para la instrucción wait

wait; -- Suspende el proceso para siempre

wait on Señal; -- Suspende el proceso hasta que ocurra


-- un evento sobre la señal

wait for Tiempo; -- Suspende el proceso un intervalo


-- fijo de tiempo

wait until (Expresión buleana);


-- Suspende el proceso hasta que se la
-- evaluación de la expresión devuelva TRUE

-- Ejemplos de uso de la instrucción wait. En general se


-- utiliza para modelos NO SINTATIZABLES

-- --------------------------------------------------------- --
-- wait on ...
SenalAccion_OUT <= ‘1’;
wait on PulsoRespuesta_IN; -- Espero un cambio en la entrada

-- Instrucciones secuenciales en un proceso de suma de 1 bit


-- con acarreo
Resultado <= A xor B after 20 ns;

©2003 Guillermo Güichal 88


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Carry <= A and B after 20 ns;


wait on A, B; Suspende hasta que cambie A o B

-- --------------------------------------------------------- --
-- wait for ...
wait for 10 ns; -- Suspende 10 nanosegundos
wait for 40 ms; -- Suspende 40 milisegundos

-- usando una constante predefinida


wait for ADC_TIEMPO _CONVERSION;

-- --------------------------------------------------------- --
-- wait for y wait solo
--
-- Generación de un pulso de 200 ns
Reset_OUT <= ‘1’; -- Pulso de la señal reset en ‘1’
wait for 230 ns; -- Ancho del pulso es 230 ns
Reset_OUT <= ‘0’; -- Señal reset a ‘0’
wait; -- Suspende para siempre. El reset queda
-- en el ultimo valor asignado (‘0’)

-- --------------------------------------------------------- --
-- wait until ...
SenalAccion_OUT <= ‘1’;
wait until (PulsoRespuesta_IN = ‘1’); -- Espero que la entrada
-- se haga ‘1’
-- ... condiciones mas complejas...
wait until (Senal1 = ‘0’ and Entrada2 = ‘0’);

wait until (((Entrada1 and Entrada2) xor Entrada3 )= ‘0’);

Cuadro 28 Uso de la palabra WAIT

Pueden armarse expresiones más complejas con la instrucción wait utilizando


combinaciones de los tres formatos for, on, until. Como en general la expresión wait no
es sintetizable6 y lo presentado alcanza para armar bancos de prueba simples, estas
expresiones no se presentarán de manera exhaustiva en este texto. Puede consultarse la
bibliografía para una mayor explicación y ejemplos varios.

6
La expresión wait es sintetizable solo en procesos sincrónicos que usan el wait para esperar un evento en
la señal de reloj, como se detallará en la sección 0.

©2003 Guillermo Güichal 89


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

7.7.3.2 Expresión if… elsif… else


La expresión if permite condicionar la ejecución de instrucciones secuenciales. Cuando la
condición buleana de la instrucción if se evalúa a TRUE se ejecutarán las instrucciones
secuénciales que la siguen. Sino se saltearán. La instrucción elsif permite anidar
condiciones, generando una lógica de prioridad. Si no se da primer condición se evalúa la
segunda, y así sucesivamente. La condición else permite que se de un caso por defecto,
que se ejecutará solo si no se cumple ninguna de las condiciones anteriores. Siempre se
debe cerrar un lazo if con una instrucción end if. Los cuadros muestran el formato
general y dan ejemplos para la utilización de las instrucciones if, elsif, else.

-- Formato general de la instrucción secuencial if


-- Solo es necesario que haya una condición if...los elsif y
-- else son optativos
if (Condición 1) then
... -- Instrucciones secuenciales que se ejecutan si
-- se cumple la condición 1
elsif (Condición 2) then
... -- Instrucciones secuenciales que se ejecutan si
-- se cumple la condición 2 (y no se cumplió la
-- condición 1)
elsif (Condición 3) then
... -- Instrucciones secuenciales que se ejecutan si
-- se cumple la condición 3 (y no se cumplieron las
-- condiciones 1 ni 2)
elsif (Condición 4) then
... -- Instrucciones secuenciales que se ejecutan si
-- se cumple la condición 4 (y no se cumplieron las
-- condiciones 1, 2 ni 3)
...
...
...

else
... –- Instrucciones que se ejecutan solo si no se da
-- ningún caso de las condiciones anteriores

end if;

Cuadro 29 Uso de la expresión IF, ELSIF, ELSE

-- Ejemplos de instrucciones if

-- --------------------------------------------------------- --
-- Una sola condición

-- Si la cuenta llega a su valor final volver a cero

©2003 Guillermo Güichal 90


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

if (Contador_REG = VALOR_MAXIMO) then


Contador_REG <= (others => ‘0’);
end if;

-- --------------------------------------------------------- --
-- if, elsif

-- Reset asincrónico y ejecución sincrónica


if (Reset_IN = ‘1’) then
-- Dar valores iniciales a los registros
Registro_REG <= (others => ‘0’);
elsif (Rising_Edge(Clock_IN)) then
.. -- Instrucciones secuenciales sincrónicas
end if;

-- --------------------------------------------------------- --
-- if, else
-- Detecto el signo de una entrada y lo guardo a un registro
if (DatoEntrada_IN(MSB) = ‘0’) then
Signo_REG <= ‘0’;
else
Signo_REG <= ‘1’;
end if;

-- --------------------------------------------------------- --
-- if elsif else
-- Un ejemplo raro que no modela nada
if (Control_IN = “00”) then
Salida_REG <= Entrada0_IN;
elsif (Entrada1_IN = “0100”) then
Cualquiercosa_REG <= ”1100000”;
elsif (Cualquiercosa_REG = ”1111111”) then
TodosUnos_OUT <= ‘1’;
else
Salida_REG <= Entrada3_IN;
end if;

-- --------------------------------------------------------- --
-- if else anidados
if (Control_IN = CONTROL_LEO_SIGNO) then
if (DatoEntrada_IN(MSB) = ‘0’) then
Salida_REG <= ‘0’;
else
Salida _REG <= ‘1’;
end if;
elsif (Control_IN = CONTROL_LEO_LSB) then
Salida_REG <= DatoEntrada_IN(0);
else
Salida_REG <= ‘0’;
end if;

©2003 Guillermo Güichal 91


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- --------------------------------------------------------- --
-- Todos los casos
-- Esto implementa un multiplexor usando if (la instrucción
-- case es la mas recomendada en estos casos)
if (Control_IN = “00”) then
Salida_OUT <= Entrada0_IN;
elsif (Control_IN = “01”) then
Salida_OUT <= Entrada1_IN;
elsif (Control_IN = “10”) then
Salida_OUT <= Entrada2_IN;
else
Salida_OUT <= Entrada3_IN;
end if;

Cuadro 30 Ejemplos de la expresión IF, ELSIF, ELSE

7.7.3.3 Expresión null


En algunos casos es necesario modelar que hay situaciones en las que no se debe tomar
ninguna acción. Esto puede hacerse en VHDL usando la instrucción null. Esta es una
instrucción secuencial y puede usarse en cualquier estructura secuencial. Se utiliza
muchas veces en expresiones como case donde deben explicitarse las acciones para todas
las alternativas posibles. En este caso se usa la palabra null para especificar que en
algunos casos no se debe hacer nada. Se mostrarán ejemplos de su uso en la sección
donde se describe la expresión case.

7.7.3.4 Expresión case


Cuando las opciones que se desean evaluar son mutuamente excluyentes y no se necesita
una lógica de prioridad, la expresión a usar es case. Esta expresión utiliza la palabra
when para evaluar las diferentes opciones en paralelo y siempre debe terminarse con un
end case. Todas las opciones deben tenerse en cuanta en la expresión. Puede utilizarse la
barra vertical “|” para agrupar varias opciones y la palabra others para declarar un caso
para las opciones que no se evalúan de manera explícita. Las opciones deben ser . En el
cuadro se presenta el formato general de la instrucción case.

-- Formato general de la instrucción secuencial case


case ExpresiónSelectora is
when Condición 1 =>
... -- Instrucciones secuenciales que se ejecutan si
-- ExpresiónSelectora resulta en la condición 1
when Condición 2 =>
... -- Instrucciones secuenciales que se ejecutan si
-- ExpresiónSelectora resulta en la condición 2
when Condición 3 | Condición 4 =>
... -- Instrucciones secuenciales que se ejecutan si

©2003 Guillermo Güichal 92


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- ExpresiónSelectora resulta en la condición 3 o 4


...
...
when others =>
... -- Instrucciones secuenciales que se ejecutan si
-- ExpresiónSelectora no resulta ser ninguna de las
-- opciones anteriores
end case;

Cuadro 31 Uso de la Expresión CASE

En el siguiente cuadro se presentan ejemplos que ayudará a entender el uso de la


instrucción case.

-- Ejemplos de instrucciones case


-- --------------------------------------------------------- --
-- Multiplexor utilizando la expresión case
case Control_IN is
when ”00” =>
Salida_OUT <= Entrada0_IN;
when ”01” =>
Salida_OUT <= Entrada1_IN;
when ”10” =>
Salida_OUT <= Entrada2_IN;
when others =>
Salida_OUT <= Entrada3_IN;
end case;

-- --------------------------------------------------------- --
-- Ejemplo para una máquina de estado
...
-- Declaración del tipo para estados
type tdEstado is (
EsperarDato,
LachearDato,
PulsoAlADC
);
...
-- Declaración de estado actual y siguiente
signal EstadoActual : tdEstado ;
signal EstadoSiguiente : tdEstado ;
...
-- CASE dentro de un proceso combinacional que asigna el
-- próximo estado según el estado actual y las entradas.
-- El estado inicial y la asignación de EstadoSiguiente a
-- EstadoActual se hacen en otro proceso sincrónico con reset
case EstadoActual is
when EsperarDato =>
if (ADCDataAvailable_IN = '1') then

©2003 Guillermo Güichal 93


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

EstadoSiguiente <= PulsoAlADC;


else
EstadoSiguiente <= EsperarDato;
end if;
when LachearDato =>
EstadoSiguiente <= EsperarDato;
when PulsoAlADC =>
EstadoSiguiente <= LachearDato;
when others =>
EstadoSiguiente <= EsperarDato;
end case;

-- CASE dentro de un proceso sincrónico que asigna las señales


-- internas y las salidas
...
-- A algunas señales se les da valores por defecto que se
-- sobre escriben en la expresión case
...
case EstadoActual is
when EsperarDato =>
DatosInternos_REG <= DatosADC_IN;
Read_N_REG <= '0';
NuevaMuestra_REG <= '1';
when PulsoAlADC =>
Read_N_REG <= '0';
when others =>
null;
end case;

Cuadro 32 Ejemplos de la expresión CASE

El uso de null en la segunda expresión case significa no hacer nada. Se debe tener en
cuanta que no hacer nada significa mantener el valor de salida anterior, y esto implica
generar latches o realimentar señales adicionales. Si lo que realmente sucede es que no
importa que valor tenga la señal se con esa combinación del case, puede dejarse algún
caso deseado como caso por defecto y así simplificar la lógica generada.

7.7.3.5 Procesos (process)


El tipo fundamental de operación concurrente es el proceso (process). El proceso es el
bloque clave para modelar la interacción compleja entre señales. El proceso en si
contiene operaciones secuenciales que se tratarán en bloque como una operación
concurrente. Esto significa que el proceso se ejecutará en paralelo con otros procesos y
operaciones concurrentes, y que el tiempo de ejecución de un proceso (es decir, la
ejecución de todas sus instrucciones secuenciales) será netamente cero7. Las operaciones
secuenciales utilizadas dentro de los procesos se describen en las siguientes secciones.

7
La asignación de señales en simulación siempre tiene un retardo mínimo de al menos un retardo delta,
como se describe en la sección 5.5.3.

©2003 Guillermo Güichal 94


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

En simulación, los procesos permanecen inactivos hasta que algún evento los hace
ejecutar. Un evento se entiende como un cambio en el valor de una señal. Los procesos se
dicen que son “sensibles” a las señales que causan su ejecución, y hay varias maneras de
especificar cuales serán las señales que causan que un proceso ejecute. Al sintetizar el
diseño, los procesos se implementarán como circuitos combinacionales o secuenciales
que efectúan la operación modelada. Los circuitos implementados producirán cambios en
sus salidas ante eventos en las señales a las que son “sensibles”.

El cuadro muestra el formato básico de un proceso.

-- Formato general de un proceso


NombreDeProceso : process(Señal1, señal2, ...)
...
Declaración de tipos internos al proceso...
Declaración de variables internas al proceso...
Declaración de constantes internas al proceso...
... más declaraciones internas al proceso

begin -- Comienzo de las instrucciones secuenciales


...
Instrucción secuencial
Instrucción secuencial
...
...más instrucciones secuenciales
...
end process NombreDeProceso;

Cuadro 33 Declaración de un proceso

Del formato básico mostrado pueden destacarse las secciones principales.


• Declaración del proceso y lista de sensibilidad (señales entre paréntesis)
• Declaración de variables, constantes, funciones y procedimientos
• Bloque secuencial

Declaración del proceso: Se recomienda dar un nombre al proceso para ayudar en la


depuración y mejor comprensión del código. Después del nombre se utiliza la palabra
clave process.

Lista de sensibilidad: Un proceso debe tener alguna manera de suspender su ejecución.


La lista de sensibilidad es una de las maneras de definir que señales actúan sobre un
proceso. La otra es la utilización de la instrucción wait. Cuando se utiliza una lista de
sensibilidad no puede usarse la palabra wait para suspender un proceso.

Declaraciones: Pueden declararse funciones, constantes y variables que se utilizarán en


el proceso.

©2003 Guillermo Güichal 95


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Instrucciones secuenciales: Estas están entre las palabras begin y end. Todas las
instrucciones secuenciales de un proceso se ejecutarán como un bloque en paralelo con
los otros procesos y demás expresiones concurrentes.

El proceso se ejecutará solo cuando haya un cambio en alguna señal de su lista de


sensibilidad. Si el proceso no tiene lista de sensibilidad se ejecutará cuando se cumpla la
condición dada en la instrucción wait. Solo puede usarse uno de los métodos para
suspender un proceso Cuando se utiliza una lista de sensibilidad no puede usarse la
palabra wait entre las instrucciones secuenciales.

Al diseñar circuitos para sintetizar sobre lógicas programables (FPGAs, CPLDs u otros
PLDs) es mejor que los modelos en VHDL se adapten a la lógica básica de los PLDs. No
hacerlo significa en muchos casos generar lógica adicional que ocupará mayor cantidad
de recursos del PLD innecesariamente. En algunos casos puede ser que el proceso
directamente no pueda sintetizarse. El cuadro muestra los patrones (templates) de
procesos recomendados para diseños sintetizables.

-- Formatos básicos de los procesos recomendados para diseños


-- sintetizables
-- --------------------------------------------------------- --
-- PROCESO 1
-- --------------------------------------------------------- --
-- Este proceso se sintetiza como flip-flops + lógica
-- combinacional.
-- Contiene un reset asincrónico que puede usarse para dar
-- valores iniciales conocidos a las señales y un bloque
-- sincrónico.
--
Proceso1 : process (Clock_IN, Reset_IN) -- Solo reloj y reset
begin
if (Reset_IN = '0') then -- Test active level of
-- asynchronous reset
...
... -- Instrucciones secuenciales asincrónicas
...
elsif Rising_edge(Clock_IN) then -- Evalúa el flanco de reloj
...
... -- Instrucciones secuenciales sincrónicas
...
end if;
end process Proceso1;

-- --------------------------------------------------------- --
-- PROCESO 2
-- --------------------------------------------------------- --
-- Este proceso genera solo lógica combinacional
--

©2003 Guillermo Güichal 96


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Proceso2 : process (Entrada1, ...) –- Todas las entradas a la


-- lógica en la lista
begin
... –- Se asigna salidas para todas las opciones
... -- combinacionales sin realimentación para que no
... –- se infieran latches
end process Proceso2;

-- --------------------------------------------------------- --
-- PROCESO 3
-- --------------------------------------------------------- --
-- Este proceso se sintetiza como flip-flops + lógica
-- combinacional.
--
Proceso3 : process (Clock_IN) -- Solo el reloj en la
-- lista de sensibilidad
begin
if Rising_edge(Clock_IN) then -- Solo se evalúa flanco de reloj
...
... -- Instrucciones secuenciales sincrónicas
...
end if;
end process Proceso3;

-- --------------------------------------------------------- --
-- PROCESO 4
-- --------------------------------------------------------- --
-- Este proceso se sintetiza como flip-flops + lógica
-- combinacional.
-- Contiene solo lógica sincrónica. Es equivalente al Proceso 3
--
Proceso4 : process – Sin lista de sensibilidad
begin
wait until Rising_edge(Clock_IN); -- Espera un flanco de reloj
...
... -- Instrucciones secuenciales sincrónicas
...
end process Proceso4;

-- --------------------------------------------------------- --
-- PROCESO 5
-- --------------------------------------------------------- --
-- Este proceso se sintetiza como un latch transparente +
-- lógica combinacional.
--
Proceso5 : process (Entrada1, ...) –- Todas las entradas a la
-- lógica en la lista
begin
if Enable = '1' then
...
... -- Instrucciones secuenciales con latch

©2003 Guillermo Güichal 97


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

...
end if;
end process Proceso5;

Cuadro 34 Declaración de procesos para síntesis

Como se verá en el próximo capítulo, para diseños orientados a FPGAs es recomendable


generar procesos sincrónicos con una señal de reset asincrónica. También es posible que
se necesiten procesos totalmente combinacionales. Estos dos procesos son los procesos 1
y 2 mostrados en el cuadro. A continuación siguen dos procesos equivalentes. Estos
procesos son sincrónicos sin señal de reset. En general no se recomienda usar sistemas
que utilicen latches como el presentado en el proceso 5.

7.7.4 Operaciones secuenciales, retardos delta y síntesis


Debido a la manera en que VHDL simula y sintetiza las instrucciones secuenciales en un
proceso pueden surgir algunas confusiones al observar su funcionamiento. El cuadro
muestra un ejemplo para explicar esto.

-- Ejemplo para explicar el funcionamiento de instrucciones


-- secuenciales

X <= ‘1’;
if (X = ‘1’) then
Y <= ‘0’;
else
Y <= ‘1’;
end if;
X <= ‘0’;
Cuadro 35 Retardos delta en procesos secuenciales

Si se supone que las instrucciones mostradas en el cuadro son parte de un proceso y se


analizan de manera secuencial, muchos usuarios esperarían que al finalizar, la señal Y
tenga el valor ‘0’. ¡Esto puede no suceder nunca! A continuación se explicará porque.

Para explicar el procesamiento del proceso, VHDL utiliza retardos-delta. Si se supone


que el valor de X al comenzar el proceso (asignado en algún momento anterior de alguna
manera no descripta) no es ‘1’, al procesar la instrucción X<= ‘1’, no se asignará en ese
instante el valor ‘1’ a X, sino que se agendará como se ha explicado en la sección 5.5.3.
Luego se analizará la instrucción if (X = ‘1’). La decisión tomada en este momento no
dependerá del valor asignado en la instrucción anterior a X (que todavía no ha sido
asignado, sino que solo agendado), sino del valor actual de X (que no es ‘1’). A Y se le
agendará entonces el valor ‘1’ de la rama else. Luego se procesará la operación X <= ‘0’.
Otra vez, este valor no se asignará instantáneamente sino que se agendará,
sobrescribiendo la asignación ‘1’ que estaba agendada. Después de haber procesado todas
las instrucciones secuenciales se asignan los valores agendados a las señales. En este caso

©2003 Guillermo Güichal 98


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

‘0’ a X y ‘1’ a Y. Es decir, nunca se asigna el valor ‘1’ a X de la primer instrucción. Por
supuesto el circuito sintetizado de estas instrucciones se comportará de la misma manera.
En el siguiente capítulo se presentarán ejemplos de circuitos sintetizados para mostrar
como se implementa en hardware una secuencia de instrucciones como la recién
descriptas.

7.7.5 Visibilidad de las declaraciones de objetos en VHDL


Los objetos declarados en VHDL, ya sean constantes, señales o variables, Podrán ser
usadas solo por las construcciones que las “ven”. Estos objetos tienen una visibilidad
limitada según el lugar de su declaración. En la Figura 39 se muestra un esquema de un
componente. Las líneas a los costados muestran donde es visible cada declaración de
tipo, señal o variable.

Los tipos, constantes y en general todas las declaraciones dentro de un paquete serán
visibles en todo el componente que los use. Para que sean visibles se deben usar antes de
la declaración de entidad o arquitectura respectivamente. Una excepción a esto es cuando
se usan dos paquetes que declaran un objeto con el mismo identificador. Por ejemplo, si
en el ejemplo anterior el usuario declara un tipo std_logic en el paquete “Constantes”, no
podrá usarse ese tipo sin declarar explícitamente a que librería se está haciendo
referencia. Esto se hace usando el nombre de la librería, paquete y tipo separado por “.”
de la siguiente manera:

signal SenialDePrueba : ieee.std_logic_1164.std_logic;

Las constantes genéricas no han sido descriptas todavía, pero tienen una visibilidad que
abarca la declaración de interfase y toda la arquitectura del componente.

Las señales de interfase declaradas en la entidad con port serán visibles dentro de toda la
arquitectura definida para esa entidad.

Las declaraciones de tipos, constantes y señales hechas en una arquitectura serán visibles
para toda la arquitectura. Es decir que estas señales podrán usarse en cualquier proceso o
construcción concurrente dentro de la arquitectura.

Las variables declaradas en cada proceso tendrán una visibilidad local a cada proceso.

Se deben mencionar en esta sección, aunque no se han presentado, los procedimientos y


funciones. Estas se pueden declarar en las regiones de declaración de la arquitectura o de
los procesos (antes de la palabra begin). Si se declaran como parte de la declaración de la
arquitectura serán visibles en toda la arquitectura. Si se declaran dentro de un proceso
solo podrán verse dentro del proceso. A su vez las variables declaradas dentro de los
procesos y funciones tendrán una visibilidad local, y no podrán ser vistas por
construcciones externas.

©2003 Guillermo Güichal 99


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 39 Visibilidad de las declaraciones en VHDL

©2003 Guillermo Güichal 100


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

8 Más VHDL
8.1 Introducción
En la sección de introducción al VHDL se presentaron las estructuras y construcciones
básicas y se dieron ejemplos para poder comenzar a crear diseños sintetizables. En esta
sección se dan algunos otros conceptos de VHDL, se ahonda en el tema de optimización
para síntesis con ejemplos concretos y se presenta la metodología de prueba utilizada
para validar un diseño, los bancos de prueba (testbench).

8.2 Parámetros Genéricos


VHDL permite escribir modelos parametrizables utilizando una lista de constantes
genéricas en la declaración de una entidad. Esto se hace declarando una interfase genérica
con la palabra generic, de una manera similar a la declaración de la interfase con la
palabra port. De esta manera se puede diseñar un componente flexible y reutilizable.

8.2.1 Declaración de parámetros genéricos


Utilizando constantes genéricas pueden parametrizarse tanto la estructura como el
comportamiento de un componente. Las constantes genéricas son visibles a partir de su
declaración hasta el final de la declaración de la entidad y en toda(s) la(s) arquitecturas
del componente. Se tratan como constantes dentro de declaración de interfase y la
arquitectura de la entidad.

El Cuadro 36 muestra el formato de una declaración de entidad con parámetros genéricos.

-- Formato de una declaración de entidad con genéricos


entity Componente is
generic(
ParametroGenerico1 : TipoDelGenerico1 := ValorPorDefecto1;
...
... – Declaración de interfase genérica
...
ParametroGenericoN : TipoDelGenericoN := ValorPorDefectoN
);
port(
.. – Declaración de interfaces
);
end Componente;

Cuadro 36 Formato de declaración con parámetros genéricos


Notar que. Al igual que en la declaración de la interfase con port, el último parámetro no
tiene un punto y coma “;” después de su declaración y antes del paréntesis que cierra la
declaración genérica. La declaración genérica se cierra con un paréntesis y un punto y
coma “);”

©2003 Guillermo Güichal 101


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

El Cuadro 37 y Cuadro 38 muestran dos ejemplos de contadores que utilizan parámetros


genéricos para parametrizar los límites del contador. En el primero se define el bit más
significativo del registro de cuenta como un genérico. Este contador pasará de largo al
llegar a su cuenta máxima (todos los bits en ‘1’) y recomenzará en 0. Para el segundo
contador se define el número de bits (será uno más que el bit más significativo) y el valor
máximo de la cuenta para reestablecer el valor del contador a cero.

-- -----------------------------------------------------------
-- EJEMPLO 1
-- Contador con bit más significativo dado por un parámetro
-- genérico
entity ContadorRollover is
generic(
MSBContador : positive := 31
);
port(
Reset_IN : IN std_logic;
Clock_IN : IN std_logic;
Cuenta_OUT : OUT std_logic_vector(MSBContador downto 0)
);
end ContadorRollover;

architecture Comportamiento of ContadorRollover is


signal Cuenta_REG : std_logic_vector(MSBContador downto 0);

begin
-- La salida esta dada por un registro
Cuenta_OUT <= Cuenta_REG;

-- La cuenta de salida se incrementa y pasa de largo a 0 al


-- llegar al valor máximo
ProcesoCuenta : process(Reset_IN, Clock_IN)
begin

if (Reset_IN = ‘1’) then


Cuenta_REG <= (others => ‘0’);
elsif Rising_Edge(Clock_IN) then
Cuenta_REG <= Cuenta_REG + 1;
end if; -- Reset, Clock
end process ProcesoCuenta;

end Comportamiento;

Cuadro 37 Ejemplo de declaración de entidad y arquitectura con parámetros genéricos

©2003 Guillermo Güichal 102


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- -----------------------------------------------------------
-- EJEMPLO 2
-- Contador con número de bits y valor de la cuenta máxima dado
-- por parámetros genéricos
entity ContadorConLimite is
generic(
CuentaMaxima : positive := 128;
BitsContador : positive := 8
);
port(
Reset_IN : IN std_logic;
Clock_IN : IN std_logic;
Cuenta_OUT : OUT std_logic_vector((BitsContador-1) downto 0)
);
end ContadorConLimite;

architecture Comportamiento of ContadorConLimite is


signal Cuenta_REG : std_logic_vector(BitsContador-1 downto 0);

begin
-- La salida esta dada por un registro
Cuenta_OUT <= Cuenta_REG;

-- La cuenta de salida se incrementa y se vuelve a 0 al llegar


-- a la cuenta máxima
ProcesoCuenta : process(Reset_IN, Clock_IN)
begin
if (Reset_IN = ‘1’) then
Cuenta_REG <= (others => ‘0’);
elsif Rising_Edge(Clock_IN) then
Cuenta_REG <= Cuenta_REG + 1;
if (Cuenta_REG = CuentaMaxima) then
end if; -- Cuenta máxima?
end if; -- Reset, Clock
end process ProcesoCuenta;
end Comportamiento;

Cuadro 38 Ejemplo de declaración de entidad y arquitectura con parámetros genéricos

El Cuadro 39 muestra un ejemplo de la parametrización del comportamiento de un


componente. En este ejemplo además de parametrizarse la estructura, se utiliza un
parámetro genérico para definir el tiempo de propagación de una compuerta usando el
tipo predefinido time. Aunque este componente se sintetizará sin problemas, la
especificación del tiempo de propagación no será tenida en cuanta por las herramientas.
El retardo de propagación en un circuito sintetizado estará dado por la implementación
real en el dispositivo, pero los retardos en los modelos pueden utilizarse para aproximar
el comportamiento post-síntesis o para visualizar mejor los efectos durante la simulación.

©2003 Guillermo Güichal 103


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- -----------------------------------------------------------
-- EJEMPLO 3
-- Modelo de lógica múltiple con señales de ancho variable y
-- retardo entre entrada y salida
entity LogicaMultiple is
generic(
MSB : positive := 8;
TPropagacion : time := 25 ns
);
port(
Entrada1_IN : IN std_logic_vector(MSB downto 0);
Entrada2_IN : IN std_logic_vector(MSB downto 0);
SalidaAnd_OUT : OUT std_logic_vector(MSB downto 0);
SalidaOr_OUT : OUT std_logic_vector(MSB downto 0)
);
end LogicaMultiple;

architecture Comportamiento of LogicaMultiple is


begin

SalidaAnd_OUT <= Entrada1_IN AND Entrada2_IN -- Instrucción en


after TPropagacion; -- varias líneas
SalidaOr_OUT <= Entrada1_IN OR Entrada2_IN after TPropagacion;

end Comportamiento;

Cuadro 39 Ejemplos de declaración de entidad y arquitectura con parámetros genérico físico

8.2.2 Uso de componentes con parámetros genéricos


Hasta ahora solo se describió la declaración de componentes con constantes genéricas. La
flexibilidad de diseño la dan esas constantes al usar los componentes en una arquitectura
estructural. El Cuadro 40 muestra un ejemplo del uso de un componente con constantes
genéricas en un modelo estructural para crear un componente de mayor complejidad. En
este caso el componente superior utiliza dos instancias del mismo componente base, con
diferentes parámetros genéricos en cada instancia. Estos parámetros al igual que las
conexiones de las señales se hacen al usar el generic map y al port map.

©2003 Guillermo Güichal 104


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- -----------------------------------------------------------
-- Utilización de un componente con constantes genéricas en un
-- diseño jerárquico
entity ContadorDualConLimite is
port(
ResetTop_IN : IN std_logic;
ClockTop_IN : IN std_logic;
Cuenta1_OUT : OUT std_logic_vector(3 downto 0);
Cuenta2_OUT : OUT std_logic_vector(4 downto 0)
);
end ContadorDualConLimite;

architecture Estructura of ContadorDualConLimite is

-- Declaración del componente para poder usarlo en la


-- arquitectura
component ContadorConLimite
generic(
CuentaMaxima : positive := 128;
BitsContador : positive := 8
);
port(
Reset_IN : IN std_logic;
Clock_IN : IN std_logic;
Cuenta_OUT : OUT std_logic_vector(BitsContador-1 downto 0)
);
end component;

begin
-- Se crea una instancia del contador de 4 bits y limite
-- máximo = 12 con la salida a la salida 1 del contador dual
Contador12 : ContadorConLimite
generic map (
CuentaMaxima => 12,
BitsContador => 4
)
port map (
Reset_IN => ResetTop_IN,
Clock_IN => ClockTop_IN,
Cuenta_OUT => Cuenta1_OUT
);

-- Se crea una instancia del contador de 5 bits y limite


-- máximo = 25 con la salida a la salida 2 del contador dual
Contador25 : ContadorConLimite
generic map (
CuentaMaxima => 25,
BitsContador => 5
)

©2003 Guillermo Güichal 105


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

port map (
Reset_IN => ResetTop_IN,
Clock_IN => ClockTop_IN,
Cuenta_OUT => Cuenta2_OUT
);

end Estructura;

Cuadro 40 Ejemplo de modelo estructural usando constantes genéricas

En el ejemplo del Cuadro 41 se usa el componente definido en el último ejemplo de la


subsección anterior. En este caso se genera una AND de tres entradas y con un ancho de
señal parametrizado a partir del componente LogicaMultiple. El componente creado tiene
un parámetro genérico con el mismo nombre que los componentes que utiliza. Esto no es
problema ya que al asociar los puertos siempre se usa GenéricoDelComponenteBase =>
GenéricoDelComponenteSuperior, y estos dos genéricos pueden tener el mismo nombre.
Puede notarse que lo mismo sucede con las señales de los puertos.

-- -----------------------------------------------------------
-- Utilización de un componente con constantes genéricas en un
-- diseño jerárquico para generar otro componente con constante
-- genérica
entity CompuertaAnd3Entradas is
generic(
MSB : positive := 3
);
port(
Entrada1_IN : IN std_logic_vector(MSB downto 0);
Entrada2_IN : IN std_logic_vector(MSB downto 0);
Entrada3_IN : IN std_logic_vector(MSB downto 0);
SalidaAnd_OUT : OUT std_logic_vector(MSB downto 0)
);
end CompuertaAnd3Entradas;

architecture Estructura of CompuertaAnd3Entradas is

-- Declaración del componente para poder usarlo en la


-- arquitectura
component LogicaMultiple
generic(
MSB : positive := 8;
TPropagacion : time := 25 ns
);

©2003 Guillermo Güichal 106


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

port(
Entrada1_IN : IN std_logic_vector(MSB downto 0);
Entrada2_IN : IN std_logic_vector(MSB downto 0);
SalidaAnd_OUT : OUT std_logic_vector(MSB downto 0);
SalidaOr_OUT : OUT std_logic_vector(MSB downto 0)
);
end component;

-- Declaración de una señal interna que permite la


-- interconexión de los componente internos
-- El genérico MSB es la definida para CompuertaAnd3Entradas
signal SenialIntermedia : std_logic_vector(MSB downto 0);

begin -- Comienzo de la arquitectura de AND de 3 entradas

-- Se crea una instancia de la compuerta donde solo se usa


-- la parte AND y la salida a una señal interna
Compuerta1DosEntradas : LogicaMultiple
generic map (
MSB => MSB,
TPropagacion => 0 ns
)
port map (
Entrada1_IN => Entrada1_IN,
Entrada2_IN => Entrada2_IN,
SalidaAnd_OUT => SenialIntermedia,
SalidaOr_OUT => open
);

-- Se crea una instancia de la compuerta donde solo se usa


-- la parte AND y una de las entradas es la señal interna
Compuerta2DosEntradas : LogicaMultiple
generic map (
MSB => MSB,
TPropagacion => 0 ns
)
port map (
Entrada1_IN => SenialIntermedia,
Entrada2_IN => Entrada3_IN,
SalidaAnd_OUT => SalidaAnd_OUT,
SalidaOr_OUT => open
);

end Estructura;

Cuadro 41 Otro ejemplo de modelo estructural usando constantes genéricas

©2003 Guillermo Güichal 107


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Del cuadro pueden verse las diferentes secciones. Por un lado está la declaración de la
entidad del nuevo componente (de nivel superior en la jerarquía del diseño). En esta
sección se declaran las constantes genéricas y las interfases o puertos.

Después de esto se declara la arquitectura y dentro de esta los componentes y señales que
se utilizarán. Después de la palabra begin se “instancian” o crean las dos instancias de
los componentes bases. Estos componentes se conectan a las entadas y salidas y entre sí
mediante los port map. El generic map da valores a las constantes genéricas de las
instancias de componentes bases. En este caso se propaga la constante MSB del
componente superior a los componentes base y se da un valor de 0 ns a los retardos. Las
salidas OR de los componentes base se dejan abiertas, y cualquier herramienta de síntesis
optimizará esto deshaciéndose de cualquier lógica no conectada e innecesaria.

8.3 Subprogramas: FUNCTION y PROCEDURE


VHDL provee dos maneras de definir subprogramas que pueden invocarse desde otras
secciones de código: los procedimientos (procedure) y las funciones (function).
La diferencia entre estas dos estructuras es que el procedimiento es una instrucción
secuencial que se utiliza por su cuenta, mientras que una función es parte de una
expresión. En esta sección se dará una breve descripción de cada una de ellas, sin
ahondar en demasiados detalles.

En cuanto a síntesis, las funciones se sintetizarán como un bloque de lógica


combinacional independiente para cada llamado. Los procedimientos son sintetizables si
no utilizan instrucciones de detección de flancos de reloj o wait y se sintetizarán como
lógica combinacional que depende del uso del procedimiento y las optimizaciones que
implementen las herramientas.

8.3.1 Procedimientos
Los procedimientos se utilizan para agrupar instrucciones secuenciales. Un
procedimiento se declara con un nombre y opcionalmente un conjunto de parámetros.
Puede declararse al comienzo de una arquitectura, proceso o en un paquete. Su
visibilidad dependerá de donde está declarado. El Cuadro 42 muestra el formato de
declaración y descripción de un procedimiento

Un procedimiento termina al llegar la secuencia de ejecución a la instrucción end


procedure. Es posible forzar el final de la ejecución en medio del procedimiento usando
la palabra return.

-- Formato de la declaración de un procedimiento sin parámetros


procedure NombreProcedimiento is
...
...-- Declaración de variables locales al procedimiento

©2003 Guillermo Güichal 108


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

begin
...
... -- Instrucciones secuenciales
...
end procedure NombreProcedimiento;

-- Formato de la declaración de un procedimiento con parámetros


procedure NombreProcedimiento (-- Lista de parámetros
ClaseDeParametro Identficador1 : Modo Tipo;
... -- Más parámetros
ClaseDeParametro Identficador N : Modo Tipo
) is
...
...-- Declaración de variables locales al procedimiento

begin
...
... -- Instrucciones secuenciales
...
end procedure NombreProcedimiento;

Cuadro 42 Formato de declaración de procedimientos

Un procedimiento se invoca desde un conjunto de instrucciones secuenciales utilizando


su nombre. El Cuadro 43 muestra la declaración y uso de un procedimiento dentro de un
proceso que satura una señal a un valor máximo.

-- Ejemplo de procedimiento dentro de un proceso sincrónico


ProcesoLecturaADC : process(Reset_IN, Clock_IN)
-- Declaración del procedimiento
procedure SaturarADC is
begin

if (ADCValue_REG > ADC_SATURACION) then


ADCValue_REG <= ADC_SATURACION;
end if;
end procedure SaturarADC;

begin –- Comienzo de la sección secuencial del proceso

if (Reset_IN = ‘1’) then


... –- Valores de reset
elsif Rising_Edge(Clock_IN) then
if ... –- Si se debe leer un dato para leer del ADC
...—- Interfase y lectura del ADC

©2003 Guillermo Güichal 109


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

ADCValue_REG <= ADC_IN;


-- Llamado al procedimiento que satura el valor del ADC
SaturarADC;

end if; -- Si se lee ADC


end if; -- Reset, Clock
end process;

Cuadro 43 Ejemplo de declaración y llamado a un procedimiento en un proceso

Los procedimientos sin parámetros actuarán sobre las señales o variables visibles para
ellos. En el ejemplo anterior, el procedimiento actúa y modifica directamente la señal
ADCValue_REG. Si se utilizan parámetros para declarar y llamar un procedimiento se
podrá utilizar o modificar diferentes variables o señales con cada llamado. Para declarar
un procedimiento con parámetros se utiliza el formato mostrado en el Cuadro 42. Esta es
similar a la declaración de los puertos de una entidad, con los siguientes elementos:

ClaseDeParámetro : constant : constante, utilizada por defecto si el modo es in


variable : variable, utilizada por defecto si el modo es out
signal : señal, modifica directamente a la señal que representa
Identficador : Nombre con el que se identificará al parámetro en las instrucciones dentro
del procedimiento
Modo : in : parámetro de entrada que no se modifica en el procedimiento
out : parámetro que no se lee pero se modifica en el procedimiento
inout : parámetro que se usa internamente y además se modifica en el
procedimiento
Tipo : Tipo del parámetro (ej.: std_logic, boolean, integer, etc.)

Los procedimientos que se declaran al principio de una arquitectura (no dentro de un


proceso específico) solo pueden modificar señales a las que acceden en su lista de
parámetros. No pueden modificar señales declaradas en la arquitectura directamente
como en el ejemplo del Cuadro 43. El Cuadro 44 muestra un ejemplo de esto, con un
procedimiento que no funcionará y uno que si.

-- Ejemplo 1: NO FUNCIONA, NO SE PUEDE ACCEDER A Dato_REG


-- DIRECTAMENTE CON EL PROCEDIMIENTO SaturarADC
... –- Arquitectura de una entidad

architecture Comportamiento of EntradaADC is


-- Declaración de una señal y el máximo valor aceptado
constant LIMITE_MAX : std_logic_vector...
signal Dato_REG : std_logic_vector(15 downto 0);
-- Procedimiento mal hecho que no funcionará
procedure SaturarADC is
begin
if (Dato_REG > LIMITE_MAX) then
Dato_REG <= LIMITE_MAX;

©2003 Guillermo Güichal 110


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

end if;
end procedure SaturarADC;
...

-- Ejemplo 2: ESTE SI FUNCIONA, SE DEBE INVOCAR EL PROCEDIMIENTO


-- CON UN PARAMETROS, NO PUEDE ACCEDER A Dato_REG DIRCTAMENTE
...
architecture Comportamiento of EntradaADC is
-- Declaración de una señal y el máximo valor aceptado
constant LIMITE_MAX : std_logic_vector...
signal Dato_REG : std_logic_vector(15 downto 0);
-- Procedimiento que funciona porque usa un parámetro
procedure SaturarADC(signal Dato : inout
std_logic_vector(15 downto 0)) is
begin
if (Dato > LIMITE_MAX) then
Dato <= LIMITE_MAX;
end if;
end procedure SaturarADC;
...

Cuadro 44 Ejemplos de procedimiento al principio de una arquitectura bien y mal hechos

Un procedimiento puede utilizarse como una instrucción concurrente directamente en la


arquitectura de un componente. El procedimiento se ejecutará con los otras elementos
concurrentes como las asignaciones de señal y los procesos.

Para llamar a un procedimiento se utiliza el nombre del procedimiento seguido de una


lista de asociación si el procedimiento requiere parámetros. Por ejemplo, para llamar al
procedimiento SaturarADC del ejemplo 2 del cuadro anterior para saturar la señal
Dato_REG se utiliza:

SaturarADC (Dato => Dato_REG); -- Se asocia el parámetro Dato del


-- procedimiento con la señal
-- Dato_REG declarada en la
-- arquitectura.

Si hay mas de un parámetro deben separarse con comas como al


asociar un componente usando port map.

8.3.2 Funciones
Las funciones pueden verse como la generalización de expresiones. Son una manera de
definir nuevas operaciones que luego podrán ser utilizadas en expresiones. Estas
operaciones se describen como un conjunto de instrucciones secuénciales que calculan un
resultado. Su declaración, como se muestra en el Cuadro 45 es muy similar a los
procedimientos. La diferencia es que debe declararse un tipo que devolverá el llamado a
la función usando return en la declaración.

©2003 Guillermo Güichal 111


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- Formato de la declaración de una función


function NombreFuncion (parámetros opcionales) return RTipo is
...
...-- Declaraciones

begin
...
... -- Instrucciones secuenciales
...
end function NombreFuncion;

Cuadro 45 Formato de declaración de una función

A diferencia de los procedimientos las funciones deben devolver un valor del tipo
declarado en la declaración usando el formato de la instrucción return :

return expresión; -- Esto devuelve el resultado de expresión,


-- que debe ser del tipo declarado para la
-- función

La lista de parámetros opcionales de una función tiene el mismo formato que el de un


procedimiento con algunas limitaciones y detalles. Los parámetros no pueden ser del tipo
variable, si no especifica la clase del parámetro esta se asume constant y si no se
especifica el modo este se asume in. Así, en una función que solo devolverá un valor a
partir de una serie de señales de entrada puede declararse de manera simple según el
esquema del ejemplo mostrado en el Cuadro 46. Este formato tiene similitud con las
funciones de otros lenguajes de programación.

-- Ejemplo de la declaración de una función con parámetros de


-- entrada constantes
function Mayor (
Entrada1 : std_logic_vector;
Entrada2 : std_logic_vector
) return std_logic_vector is

begin
if (Entrada1 > Entrada2) then
return Entrada1;
else
return Entrada2;
end if;
end function Mayor;
...
...

-- Uso de la función en una expresión concurrente o secuencial

©2003 Guillermo Güichal 112


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Resultado <= Mayor(Entrada1 => DatoADC_IN,


Entrada2 => LimiteUsuario_IN);

-- Uso de la función con asociación por posición


Resultado <= Mayor(DatoADC_IN, LimiteUsuario_IN);

Cuadro 46 Ejemplo de declaración y uso de una función con parámetros de entrada solamente

En este ejemplo los parámetros de entrada no tienen un rango prefijado. Los rangos se
asignarán cuando se llame a la función con parámetros reales. El tipo de la salida no
puede tener un rango predeterminado. En el ejemplo, el rango estará dado por las señales
DatoADC_IN y LimiteUsuario_IN y la señal que se devuelve también dependerá de la
cantidad de bits de estas dos entradas.

8.3.3 Asociación de parámetros por posición y por nombre


Hasta ahora solo se han descrito las listas de asociación por nombre, como las utilizadas
para los port map y llamados de procedimientos, que utilizan el símbolo “=>”. En todos
estos casos pueden asociarse parámetros por posición, como se muestra en el segundo
ejemplo del llamado de la función Mayor. Hay que tener mucho cuidado al hacer esto ya
que pueden cometerse errores de orden y no obtener los resultados deseados. También
hace más difícil la modificación del código. Para los componentes en arquitecturas
estructurales se recomienda la asociación por nombre, pero en llamados a funciones hay
veces que es práctico usar la asociación por posición. En el caso del ejemplo se asociará
DatoADC_IN con Entrada1 porque este es el primer parámetro en la lista, y
LimiteUsuario_IN con Entrada1 porque es el segundo parámetro. En las
asociaciones por nombre no es necesario mantener el orden de los parámetros igual que
en la declaración de la función o procedimiento.

8.4 Instrucción GENERATE


La instrucción generate permite generar múltiples copias de un componente para no
tener que declararlos uno por uno en un diseño estructural. El muestra el formato y un
ejemplo de esta instrucción.

-- Formato de la instrucción generate


Etiqueta : for Identificador in Rango generate
Instrucción concurrente
end generate;

-- ------------------------------------------------------ --
-- Ejemplo de la instrucción generarte para crear un inversor
-- de 16 bits a partir de un componente INV de 1 bit
library ieee;
use ieee.std_logic_1164.all;
library unisim;

©2003 Guillermo Güichal 113


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

use unisim.vcomponents.all;

entity Inversor16 is
port(Entrada_IN : in std_logic_vector(15 downto 0);
Salida_N_OUT : out std_logic_vector(15 downto 0));
end Inversor16;

architecture Estructura of Inversor16 is


-- Declaración del componente primitivo que se usará
component INV
port(I : in std_logic;
O : out std_logic);
end component;

begin
CompGenerado : for índice in 15 downto 0 generate
CompBasico : INV port map (I => Entrada_IN(Indice),
O => Salida_N_OUT(Indice));
end generate;
end Estructura;

Cuadro 47 Uso de GENERATE

8.5 Componentes Básicos de Diseño (Primitivas - Primitives)


Al sintetizar un diseño, las herramientas traducen el código VHDL a un conjunto de
componentes básicos (denominados primitivas) interconectados para proveer la
funcionalidad que se desea. Estas primitivas están formadas por los elementos básicos de
las FPGAs, pero los detalles están escondidos al diseñador. Cada fabricante provee un
conjunto librerías de componentes que están optimizados para su arquitectura en
particular. Estos componentes son óptimos porque hay una relación directa entre ellos y
la funcionalidad provista por los bloques lógicos básicos de la arquitectura del dispositivo

Por ejemplo, los fabricantes proveen una primitiva "sumador", que no existe directamente
en las FPGAs. Esta primitiva está formada por los elementos lógicos, lógica de acarreo,
etc., para cada familia de FPGAs en particular. Las herramientas detectan los sumadores
en el código VHDL y lo traducen a una interconexión del componente "sumador" con
otras primitivas.

8.5.1 Utilización de Primitivas desde VHDL


Las primitivas pueden usarse desde el VHDL, creando una instancia como cualquier otro
componente en una arquitectura estructural. Para utilizarlos se deben declarar los
componentes con los nombres especificados por los fabricantes. Si se utilizan las
herramientas de diseño esquemático provistos por los fabricantes esto es muy directo.

Xilinx provee las denominadas “librerías unificadas”. Con ellas Xilinx unifica los
componentes para todos sus dispositivos programables. Los componentes de las librerías

©2003 Guillermo Güichal 114


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

unificadas se describen en el documento “Libraries Guide” de Xilinx. Las primitivas


incluyen bloques para realizar funciones especiales de entrada/salida, manejo de reloj,
comparadores, contadores, multiplexores, funciones aritméticas, memorias, etc. Cada
fabricante provee esos componentes para su uso de alguna manera.

El Cuadro 48 muestra un ejemplo en que se usa una primitiva de un buffer tipo “BUFG”.
Ese buffer es el buffer de entrada de las señales de reloj en las FPGA. Cuando se hace un
diseño con las herramientas de Xilinx ISE 5, este componente debe incorporarse como
una instancia explícitamente si se conecta una señal que no es una señal de reloj a uno de
estos pines. En la placa D2E de Digilent Inc, el botón está conectado a uno de estos pines,
y para todos los diseños debe agregarse una instancia de BUFG si se desea utilizar.

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

library unisim;
use unisim.vcomponents.all;

entity Componente is
port(
Clock_IN : in std_logic;
Reset_IN : in std_logic;
...
... –- Demás puertos de interfase al componente
);
end Componente;

architecture Estructura of Componente is

signal intReset : std_logic;

component bufg
port ( I : in std_logic;
o : out std_logic);
end component;

begin

BufferReset : bufg
port map (I => Reset_IN,
O => intReset);
-- Resto de la descripción structural utiliza intReset
-- como señal de reset
...
Cuadro 48 Utilización de una instancia de un componente de librería BUFG en una estructura

©2003 Guillermo Güichal 115


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

8.5.2 Librerías de Primitivas (componentes) Específicos para Simulación


Los componentes básicos o primitivas son expresiones directas de la arquitectura básica
de una FPGA. Al crear una instanciar mediante VHDL y sintetizarlos, se transforman
directamente en recursos de la FPGA. Estos estarán configurados de maneras específicas
según su función, fabricante y familia de la FPGA. En general no son compatibles entre
fabricantes, y muchas veces no son compatibles entre distintas familias de FPGAs del
mismo fabricante.

De cualquier manera, un diseño que utilice primitivas debe poder simularse. Para ellos se
necesitan modelos de simulación de estas primitivas. Cada fabricante provee estos
modelos de simulación para sus primitivas. Por ejemplo, Xilinx provee estos modelos en
la librería unisim, Altera en la librería altera_mf y Actel tiene una librería para cada
familia de FPGAs. Si en un diseño se utiliza directamente alguna primitiva (componente)
de Xilinx, por ejemplo, se deben agregar a la lista de librerías las siguientes líneas

library unisim;
use unsim.vComponents.all;

En el ejemplo anterior del uso de BUFG estas líneas aparecen al comienzo del archivo,
antes de la declaración de la entidad.

En el caso de Altera será

library altera_mf;
use altera_mf.altera_mf_components.all;

En general se recomienda tratar de no utilizar primitivas específicas de un fabricante. De


esa manera el diseño será mas fácil de portar de una FPGA a otra. En muchos casos, sin
embargo, se desean utilizar recursos especiales provistos por una familia de FPGAs. Para
poder re-utilizar luego el diseño con otras FPGAs se puede envolver las primitivas en
código VHDL genérico (creando un "wrapper"). De esta manera solo habrá que cambiar
la implementación de ese bloque al cambiar de FPGA, haciendo la tarea un poco mas
simple.

8.5.3 Memoria
La memoria es un componente básico de muchos diseños digitales. Muchas FPGAs
incluyen bloques de memoria entre los elementos lógicos, lo que permite integrarla de
manera rápida y eficiente con los diseños lógicos. Además de la memoria embebida o en
bloque (la que está integrada en el chip junto a la lógica programable), las FPGAs
basadas en memoria SRAM para su configuración permiten usar parte de la lógica como
memoria. Dependiendo de las herramientas, su configuración y el estilo del código HDL,
las memorias pueden . En algunos casos pueden inferirse a partir de la descripción que se
hace en el HDL. En otros casos, si se desea usar un tipo de memoria con una
configuración particular, es posible que haya que crear una instancia explícitamente como
una primitiva.

©2003 Guillermo Güichal 116


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

A continuación se describirán algunas configuraciones para las memoria de las FPGA de


Xilinx. Las FPGA de Xilinx pueden implementar dos tipos de memoria RAM que se
incluyen como primitivas. Una es la memoria RAM en bloque (block RAM), que está
formada por los bloques de memoria embebidos en la FPGA. Esta memoria solo puede
configurarse como memoria (RAM o ROM) y no utilizarse como lógica configurable. La
RAM distribuida (distributed RAM) se implementa utilizando las tablas de búsqueda
LUT de los bloques lógicos como.

Para utiliza cualquiera de los dos tipos de memoria deben inferir o crear una instancia de
alguna versión de ellos en una arquitectura estructural. Hay varias posibilidades de uso y
configuración de las memorias, ya sea con puerto simple, puerto dual, diferentes anchos
de palabra, etc. A continuación se presentarán algunos ejemplos de estos componentes,
tomados de la guía de librerías unificada de Xilinx.

La Figura 40 muestra una memoria RAM de puerto dual de 16 palabras por 1 bit de
ancho. Esta memoria tiene los siguientes puertos interfase.

Tabla 10 Puertos de interfase de la memoria RAM16x1D


Señal Descripción
WE Habilitación de escritura (Write Enable)
WCLK Reloj de escritura (Write Clock)
D Dato escritura
A0..A3 Dirección de escritura
DPRA0..DPRA3 Dirección de lectura
SPO Salida dada por A0..A3
DPO Salida dada por DPRA0..DPRA3

Figura 40 Interfase de memoria de puerto dual 16x1

La Figura 41 muestra un esquema de la interfase de memoria en bloque configurada


como memoria de puerto simple, de 1024 palabras por 4 bits. La Tabla 11 describe
brevemente las señales.

©2003 Guillermo Güichal 117


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 41 Interfase de memoria de bloque de 1024 x 4

Tabla 11 Puertos de interfase de la memoria RAMB4_S4


Señal Descripción
WE Habilitación de escritura (Write Enable)
EN Habilitación
RST Reset
CLK Reloj
DI3.. DI0 Datos de entrada
A3..A0 Dirección
DO3.. DO0 Datos de salida

Inferencia de Memorias
Ciertas estructuras en VHDL pueden modelar el comportamiento de memorias RAM o
ROM. Muchas herramientas detectan estas estructuras e infieren el uso de una memoria
interna de la FPGA (ya sea en bloque o distribuida). El tipo de estructura reconocida y las
memorias inferidas dependerán de las herramientas. Algunas herramientas infieren bien
ciertos tipos de memoria pero no otros (puerto simple vs. puerto dual) o no permiten
inicializar una memoria inferida. En lo siguientes cuadros y figuras se muestra código
VHDL con el cual se infieren distintos tipos de memoria y los resultados de la síntesis.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH. ALL;
use IEEE.STD_LOGIC_UNSIGNED. ALL;

entity infer_ram is
port (clk : in std_logic;
we : in std_logic;
a : in std_logic_vector(4 downto 0);
di : in std_logic_vector(3 downto 0);
do : out std_logic_vector(3 downto 0));
end infer_ram;

architecture Comportamiento of infer_ram is

©2003 Guillermo Güichal 118


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

type ram_type is array (31 downto 0) of std_logic_vector(3 downto 0);


signal RAM : ram_type;

-- Señal para registrar la dirección de lectura


signal read_a : std_logic_vector(4 downto 0);

begin
process (clk)
begin
if Rising_Edge(clk) then
-- La memoria se escribe con un WE sincronico
if (we = '1') then
RAM(conv_integer(a)) <= di;
end if;

-- La memoria BRAM necesita la dirección de lectura registrada


read_a <= a;
end if;
end process;

-- Datos de salida
do <= RAM(conv_integer(read_a));

end Comportamiento;

Cuadro 49 VHDL para inferir memoria en bloque BRAM en las herramientas de Xilinx

======================================================================
HDL Synthesis Report

Macro Statistics
# Block RAMs : 1
1024x4-bit single-port block RAM : 1

======================================================================
Device utilization summary:
---------------------------

Selected Device : 2s200epq208-7

Number of bonded IOBs: 19 out of 146 13%


Number of BRAMs: 1 out of 14 7%
Number of GCLKs: 1 out of 4 25%

Cuadro 50 Mensajes de resultado al inferir RAM en bloque en las herramientas de Xilinx

©2003 Guillermo Güichal 119


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 42- Resultados de la síntesis. BRAM inferida.


(Fuente: Captura de pantalla de herramienta Xilinx ECS)

En los siguientes cuadros se muestra el código VHDL y los resultados de síntesis al


inferir memoria RAM distribuida. Notar que hay solo una sutil diferencia en el VHDL
respecto al código que infiere RAM distribuida. Para inferir RAM distribuida la dirección
de lectura no está registrada. El resultado de utilización del dispositivo refleja la
diferencia entre usar RAM distribuida o en bloque.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH. ALL;
use IEEE.STD_LOGIC_UNSIGNED. ALL;

entity infer_ram is
port (clk : in std_logic;
we : in std_logic;
a : in std_logic_vector(4 downto 0);
di : in std_logic_vector(3 downto 0);
do : out std_logic_vector(3 downto 0));
end infer_ram;

architecture Comportamiento of infer_ram is

type ram_type is array (31 downto 0) of std_logic_vector(3 downto 0);


signal RAM : ram_type;

begin
process (clk)

©2003 Guillermo Güichal 120


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

begin
if Rising_Edge(clk) then
-- La memoria se escribe con un WE sincronico
if (we = '1') then
RAM(conv_integer(a)) <= di;
end if;
end if;
end process;

-- Datos de salida. Direccion de entrada asincrónica directamente


do <= RAM(conv_integer(a));

end Comportamiento;

Cuadro 51 VHDL para inferir memoria distribuida en las herramientas de Xilinx

======================================================================
HDL Synthesis Report

Macro Statistics
# LUT RAMs : 1
1024x4-bit single-port distributed RAM: 1

======================================================================
Device utilization summary:
---------------------------
Selected Device : 2s200epq208-7

Number of Slices: 341 out of 2352 14%


Number of 4 input LUTs: 413 out of 4704 8%
Number of bonded IOBs: 19 out of 146 13%
Number of GCLKs: 1 out of 4 25%

Cuadro 52 Mensajes de resultado al inferir RAM distribuida en las herramientas de Xilinx

En el siguiente ejemplo se infiere una memoria ROM. Notar en la figura que la memoria
ROM se implementa como una RAM con sus entradas de escritura deshabilitadas.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;

-- La interfaz de la ROM no tiene datos de lectura


entity ROM_infer is
port(clk : in std_logic;
we : in std_logic;
addr: in std_logic_vector(3 downto 0);
do : out std_logic_vector(7 downto 0));
end entity ROM_infer;
architecture Xilinx of ROM_infer is

©2003 Guillermo Güichal 121


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

begin

-- Este proceso solo lee datos


the_rom: process (clk)
begin
if rising_edge(clk) then
case addr is
when "0000" => do <= X"12";
when "0001" => do <= X"34";
when "0010" => do <= X"56";
when "0011" => do <= X"78";
when "0100" => do <= X"9A";
when "0101" => do <= X"BC";
when "0110" => do <= X"DE";
when "0111" => do <= X"F0";
when "1000" => do <= X"77";
when "1001" => do <= X"88";
when "1010" => do <= X"99";
when "1011" => do <= X"AA";
when "1100" => do <= X"BB";
when "1101" => do <= X"CC";
when "1110" => do <= X"DD";
when others => do <= X"EE";
end case;
end if;
end process the_rom;

end architecture Xilinx;

Cuadro 53 VHDL para inferir memoria ROM (usando BRAM) en las herramientas de Xilinx

======================================================================
HDL Synthesis Report

Macro Statistics
# Block RAMs : 1
16x8-bit single-port block RAM : 1

======================================================================
Device utilization summary:
---------------------------

Selected Device : 2s200epq208-7

Number of bonded IOBs: 12 out of 146 8%


Number of BRAMs: 1 out of 14 7%
Number of GCLKs: 1 out of 4 25%

Cuadro 54 Mensajes de resultado al inferir una ROM en las herramientas de Xilinx

©2003 Guillermo Güichal 122


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 43 Resultados de la síntesis. ROM implementada como RAM escritura deshabilitada.


(Fuente: Captura de pantalla de herramienta Xilinx ECS)

Altera recomienda estructuras similares para inferir memorias en sus dispositivos desde
los HDLs. en el siguiente cuadro se muestra un ejemplo de VHDL para inferir una
memoria RAM de puerto dual.

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY ram_dual IS

PORT (clock1: IN STD_LOGIC;


clock2: IN STD_LOGIC;
data: IN STD_LOGIC_VECTOR (3 DOWNTO 0);
write_address: IN INTEGER RANGE 0 to 31;
read_address: IN INTEGER RANGE 0 to 31;
we: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
);
END ram_dual;

ARCHITECTURE rtl OF ram_dual IS


TYPE MEM IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL ram_block: MEM;

©2003 Guillermo Güichal 123


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

SIGNAL read_address_reg : INTEGER RANGE 0 to 31;

BEGIN
PROCESS (clock1)
BEGIN
IF (clock1'event AND clock1 = '1') THEN
IF (we = '1') THEN
ram_block(write_address) <= data;
END IF;
END IF;
END PROCESS;

PROCESS (clock2)
BEGIN
IF (clock2'event AND clock2 = '1') THEN
q <= ram_block(read_address_reg);
read_address_reg <= read_address;
END IF;
END PROCESS;

END rtl;

Cuadro 55 VHDL recomendado para inferir memoria RAM de puerto dual en FPGAs de Altera

Para entender bien como inferir memorias u otras primitivas desde el código HDL para
una FPGA y herramienta dada, referirse a los manuales de las herramientas y notas de
aplicación de los fabricantes de FPGAs. Las herramientas provistas por los fabricantes de
FPGAs tienen ayudas y plantillas que permiten generar código HDL de manera rápida.

Instancia de Memorias
Hay muchos casos en los que se desea controlar en detalle el tipo de memoria (u otra
primitiva) a utilizar. En estos casos se debe colocar una instancia (instantiate) del
componente usando port map . Para esto hay que referirse a la documentación de los
fabricantes y entender las interfaces de las primitivas. Una vez definido el componente se
instancia como cualquier otra primitiva. En el siguiente ejemplos e muestra el uso de una
memoria del tipo ram_32x8_dp en una FPGA de Altera. Para modelar el
comportamiento de la memoria se debe incluir al proyecto el VHDL correspondiente al
componente ram_32x8_dp provisto por Altera. Mas adelante se muestra el uso de
memorias de Xilinx para crear una cola FIFO.


ARCHITECTURE rtl_text OF fifo_1clk_32x8 IS

-- Declaración del componente


COMPONENT ram_32x8_dp
PORT (
data : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
wren : IN STD_LOGIC := '1';
wraddress : IN STD_LOGIC_VECTOR (4 DOWNTO 0);
rdaddress : IN STD_LOGIC_VECTOR (4 DOWNTO 0);

©2003 Guillermo Güichal 124


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

clock : IN STD_LOGIC;
q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0));
END COMPONENT;
BEGIN
-------------------------------------
-- Altera RAM instantiation for FIFO.
-------------------------------------
RamFifo : ram_32x8_dp
PORT MAP (
data => Writedata_IN,
wren => WriteEnable_IN,
wraddress => WriteAddress_REG(4 DOWNTO 0),
rdaddress => ReadAddress_REG(4 DOWNTO 0),
clock => Clock_IN,
q => Readdata_OUT);
...
END ARCHITECTURE rtl_text;

8.5.4 Definición de Nuevos Componentes de Diseño


A partir de algunas primitivas de diseño pueden definirse componentes con parámetros
genéricos que pueden reutilizarse en distintas aplicaciones. En los siguientes ejemplos se
presenta una memoria de 16 por N y una cola FIFO de 16 x 16, ambas formadas a partir
de la primitiva RAM16x1D.

-- Componente de memoria RAM de 16 x N a partir de primitiva RAM16X1D

entity DRamDual16xN is
generic (
MSB_MEMORIA_RAM : positive := 15;
);
port (
Clock_IN : in std_logic;
WriteEnable_IN : in std_logic;
WriteAddress_IN : in std_logic_vector(3 downto 0);
WriteData_IN : in std_logic_vector(MSB_MEMORIA_RAM downto 0);
ReadAddress_IN : in std_logic_vector(3 downto 0);
ReadData_OUT : out std_logic_vector(MSB_MEMORIA_RAM downto 0)
);
end DRamDual16xN;

architecture Estructura of DRamDual16xN is

component RAM16X1D
port (
WCLK : in std_logic;
WE : in std_logic;
A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic;

©2003 Guillermo Güichal 125


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

D : in std_logic;
SPO : out std_logic;
DPRA0 : in std_logic;
DPRA1 : in std_logic;
DPRA2 : in std_logic;
DPRA3 : in std_logic;
DPO : out std_logic);
end component;

begin

--------------------------------------------
-- Instancia de RAM
--------------------------------------------
G1: for I in MSB_MEMORIA_RAM downto 0 generate
L: RAM16X1D port map (
WCLK => Clock_IN,
WE => WriteEnable_IN,
A0 => WriteAddress_IN(0),
A1 => WriteAddress_IN(1),
A2 => WriteAddress_IN(2),
A3 => WriteAddress_IN(3),
D => WriteData_IN(I),
SPO => open,
DPRA0 => ReadAddress_IN(0),
DPRA1 => ReadAddress_IN(1),
DPRA2 => ReadAddress_IN(2),
DPRA3 => ReadAddress_IN(3),
DPO => ReadData_OUT(I));
end generate G1;

end Estructura;

Cuadro 56 Memoria RAM de 16 x N

En el siguiente ejemplo se define una cola tipo FIFO de 16 palabras por 16 bits. Se utiliza
como bloque básico para guardar los datos la primitiva RAM16X1D. Este componente
tiene una entrada y una salida de datos y dos señales que indican si se desea leer el dato
de la cola o escribir el dato a la cola. LA salida de lectura siempre tiene el primer dato de
salida disponible, y al leerlo se incrementa un puntero y se pasa al siguiente. El dato de
escritura se escribe sobre la memoria en el lugar indicado por el puntero de escritura. Otra
salida indica el número de datos disponibles en la cola. El correcto funcionamiento
depende de que la lógica que se conecta a este componente no actúe de manera no
prevista. Es decir, solo se deberá leer un dato si hay datos disponibles y solo se deberá
escribir un dato si los datos disponibles no llenan la cola.

En la arquitectura de este componente se mezclan las descripciones estructurales y de


comportamiento. Aunque esto no es recomendable en general, en este componente todos
los procesos junto a la memoria como instancia forman un solo componente, y tiene más
sentido y hace más entendible el funcionamiento mantener todos los elementos juntos que
separarlos en dos componentes diferentes.
-- Componente FIFO 16 x 16 a partir de primitiva RAM16X1D

©2003 Guillermo Güichal 126


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

entity FifoDRam16x16 is
port (
Clock_IN : in std_logic;
Reset_IN : in std_logic;
WriteEnable_IN : in std_logic;
ReadEnable_IN : in std_logic;
WriteData_IN : in std_logic_vector(15 downto 0);
ReadData_OUT : out std_logic_vector(15 downto 0);
DatosDisponibles_OUT : out std_logic_vector(4 downto 0)
);
end FifoDRam16x16;

architecture Mixta of FifoDRam16x16 is

signal ReadAddress_REG : std_logic_vector(4 downto 0);


signal WriteAddress_REG : std_logic_vector(4 downto 0);
signal DatosDisponibles_REG : std_logic_vector(4 downto 0);

component RAM16X1D
port (
WCLK : in std_logic;
WE : in std_logic;
A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic;
D : in std_logic;
SPO : out std_logic;
DPRA0 : in std_logic;
DPRA1 : in std_logic;
DPRA2 : in std_logic;
DPRA3 : in std_logic;
DPO : out std_logic);
end component;

begin
--------------------------------------------
-- Instancia de RAM 16 x 16
--------------------------------------------
G1: for I in 15 downto 0 generate
L: RAM16X1D port map (
WCLK => Clock_IN,
WE => WriteEnable_IN,
A0 => WriteAddress_REG (0),
A1 => WriteAddress_REG (1),
A2 => WriteAddress_REG (2),
A3 => WriteAddress_REG (3),
D => WriteData_IN(I),
SPO => open,
DPRA0 => ReadAddress_REG (0),
DPRA1 => ReadAddress_REG (1),
DPRA2 => ReadAddress_REG (2),
DPRA3 => ReadAddress_REG (3),
DPO => ReadData_OUT(I));
end generate G1;

-- Control de dirección lectura

©2003 Guillermo Güichal 127


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

ControlDireccionLectura : process(Reset_IN, Clock_IN)


begin
if (Reset_IN =’1’) then
ReadAdrress_REG <= (others => ‘0’);
elsif Rising_Edge(Clock_IN) then
if (ReadEnable_IN = ‘1’) then
ReadAddress_REG <= ReadAddress_REG + 1;
end if;
end if;
end process ControlDireccionLectura;

-- Control de dirección escritura


ControlDireccionEscritura : process(Reset_IN, Clock_IN)
begin
if (Reset_IN =’1’) then
WriteAdrress_REG <= (others => ‘0’);
elsif Rising_Edge(Clock_IN) then
if (WriteEnable_IN = ‘1’) then
WriteAddress_REG <= ReadAddress_REG + 1;
end if;
end if;
end process ControlDireccionEscritura;

-- Calculo de numero de datos disponibles


CuentaDatosDisponibles : process(Reset_IN, Clock_IN)
begin
if (Reset_IN =’1’) then
DatosDisponibles_REG <= (others => ‘0’);
elsif Rising_Edge(Clock_IN) then
if (ReadEnable_IN='1') and (WriteEnable_IN='0') then
DatosDisponibles_REG <= DatosDisponibles_REG - 1;
end if;
if (ReadEnable_IN='0') and (WriteEnable_IN='1') then
DatosDisponibles_REG <= DatosDisponibles_REG + 1;
end if;
end if; -- Reset, Clock
end process CuentaDatosDisponibles;

DatosDisponibles_OUT <= DatosDisponibles_REG;

end Mixta;

Cuadro 57 Cola FIFO de 16 x 16

©2003 Guillermo Güichal 128


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

8.6 Máquinas de Estado


Si el estado de funcionamiento de un diseño, y por ende las salidas, están dadas por las
entradas al circuito solamente el diseño puede resolverse mediante lógica combinacional.
Un diseño en el que el estado de funcionamiento no está solo dado por las entradas sino
también por la historia de funcionamiento anterior no puede resolverse mediante lógica
combinacional. Se está presencia de un circuito secuencial que incluirá no solo lógica
combinacional sino también una máquina de estados. Si la cantidad de estados es limitada
a se la denomina máquina de estados finita8. Las maneras clásicas de modelar máquinas
de estados son las tablas de transición y los diagramas de estados de burbujas. En las
tablas de transición se describen los diferentes estados de funcionamiento en las filas y
las combinaciones de entradas en las columnas. Los datos de las tablas indican el
próximo estado. La Tabla 12 muestra un ejemplo de una tabla de transición para un
diseño secuencial genérico. El diseño tiene dos entradas de un bit y una salida. Las
entradas se agrupan en la primera fila como un vector de 2 bits.

Tabla 12 Tabla de transición de estados


Entrada1 | Entrada2 Salida
Estado “00” “01” “10” “11”
Inicial Inicial Inicial Estado1 Estado1 “001”
Estado1 Estado4 Estado4 Estado2 Estado3 “010”
Estado2 Estado3 Estado3 Estado3 Estado3 “011”
Estado3 Estado4 Estado3 Estado4 Estado3 “100”
Estado4 Inicial Inicial Inicial Inicial “111”

En los diagramas de burbujas se detallan los estados mediante burbujas y las transiciones
entre ellos con flechas que las unen. Sobre las flechas se especifican las condiciones
necesarias para esas transiciones. Existen muchas herramientas gráficas con las que se
pueden diseñar máquinas de estado. En general se grafican diagramas de burbujas y la
condiciones de transición y salidas. Estas representaciones gráficas son luego traducidas a
VHDL por las herramientas. La Figura 44 muestra esta máquina de estados como un
diagrama de burbujas.

8
Las máquinas de estado infinitas no tienen sentido práctico para las aplicaciones que se tratan en este
texto

©2003 Guillermo Güichal 129


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 44 Ejemplo de maquina de estado

Siguiendo las recomendaciones para diseños sintetizables sobre FPGAs, se recomienda


utilizar máquinas de estado sincrónicas, con un estado de reset asincrónico. En las
máquinas de estado sincrónicas solo hay cambios de estado y sobre las salidas con un
flanco de reloj. Si la velocidad del reloj es demasiado rápida y se desea hacer más lenta
una máquina de estados, se puede utilizar una señal de habilitación de reloj en el proceso

©2003 Guillermo Güichal 130


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

sincrónico como se describirá más adelante. La implementación básica de una máquina


de estados como la descripta será la mostrada en la Figura 45.

Figura 45 - Esquema lógico de la maquina de estados del ejemplo

Aunque es muy práctico diseñar una máquina de estados con una interfase gráfica como
la provista por StateCad de Xilinx, HDL Designer de Mentor Graphics, o cualquier otra
herramienta de ese estilo, también se puede desarrollar directamente en VHDL9. EL estilo
preferido para describir una máquina de estados en VHDL es mediante dos procesos.
Uno es combinacional y calcula el próximo estado a partir del estado actual y las
entradas. El otro es sincrónico y asigna el estado actual y define las salidas. El ejemplo
presentado es una manera de modelar máquinas de estado, pero existen una variedad de
combinaciones de procesos y lógica concurrente que pueden ser utilizadas.

El Cuadro 58 muestra el la máquina de estados de la figura anterior a modo de ejemplo.


La implementación será como la de la Figura 45, con la asignación del estado actual y las
salidas hecha a través de elementos sincrónicos (registros). La asignación de salidas en el
proceso sincrónico puede prestarse a confusión. Debe recordarse que, al haber un flanco
de reloj y ejecutarse la instrucción de asignación del próximo estado, este valor se
agenda, pero no se actualiza inmediatamente. Por eso, al evaluarse el case de asignación
de las salidas, se tomará el valor del estado actual y no el agendado. La consecuencia es
que las salidas estarán en realidad retrasadas un ciclo de reloj respecto al estado actual
(debido a los registros antes de las salidas). Si eso no es aceptable puede usarse lógica
combinacional para las salidas o replantearse la máquina de estados para obtener las
salidas necesarias.

9
Las herramientas traducen los diseños gráficos a VHDL o Verilog antes de sintetizarlos.

©2003 Guillermo Güichal 131


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- Declaración de la arquitectura de la máquina de estados


-- La entidad se declara como en cualquier otro caso para
-- describir las interfases (port)

architecture ComportamientoFSM of EjemploFSM is


-- Declaración de señales internas de ser necesarias
signal Salida_REG : std_logic_vector (2 downto 0);

-- Utilización de un tipo enumerado para describir los estados


type tdEstado is (
Inicial,
Estado1,
Estado2,
Estado3,
Estado4
);

signal EstadoActual : tdEstado ;


signal EstadoSiguiente : tdEstado ;

begin
-- -------------------------------------------------------- --
-- Asignaciones e instrucciones concurrentes
-- -------------------------------------------------------- --
Salida <= Salida_REG;

-- -------------------------------------------------------- --
-- Proceso sincrónico de asignación de estado actual y señales
-- -------------------------------------------------------- --
ProcesoSincronico : process(Clock_IN, Reset_IN)
begin
if (Reset_IN = '1') then
EstadoActual <= Inicial;
-- Valores de reset
Salida_REG <= “001”;
elsif (Rising_Edge(Clock_IN) then
-- Paso al próximo estado de manera sincrónica
EstadoActual <= EstadoSiguiente;
-- Acciones para la asignación de señales y salidas
case EstadoActual is
when Inicial =>
Salida_REG <= “001”;
when Estado1 =>
Salida_REG <= “010”;
when Estado2 =>
Salida_REG <= “011”;
when Estado3 =>
Salida_REG <= “100”;
when Estado4 =>
Salida_REG <= “111”;
when others =>
null; -- Mantiene las salidas actuales con un registro
end case;
end if;
end process ProcesoSincronico;

©2003 Guillermo Güichal 132


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- -------------------------------------------------------- --
-- Proceso combinacional de asignación de estados
-- -------------------------------------------------------- --
AsignacionProximoEstado : process (Entrada1,
Entrada2,
EstadoActual
)
begin
-- Acciones combinadas de asignación de estado siguiente
case EstadoActual is
when Inicial =>
if (Entrada1_IN = ‘1’) then
EstadoSiguiente <= Estado1;
else
EstadoSiguiente <= Inicial;
end if;
when Estado1 =>
if (Entrada1_IN = ‘0’) then –- Entrada1= ‘1’, Entrada2= ‘X”
EstadoSiguiente <= Estado4;
elsif (Entrada2_IN=‘0’) then –- Entrada1= ‘1’, Entrada2= ‘0’
EstadoSiguiente <= Estado2;
else -- Entrada1= ’1’, Entrada2= ‘1’
EstadoSiguiente <= Estado3;
end if;
when Estado2 =>
EstadoSiguiente <= Estado3;
when Estado3 =>
if (Entrada2_IN = ‘0’) then
EstadoSiguiente <= Estado4;
else
EstadoSiguiente <= Estado3;
end if;
when others => -- Estado4
EstadoSiguiente <= Inicial;
end case;

end process AsignacionProximoEstado;

end ComportamientoFSM;

Cuadro 58 Ejemplo de máquina de estados en VHDL

En el proceso combinacional todas las señales que producen cambios deben estar en la
lista de sensibilidad. Además, al evaluar las entradas para el próximo estado en las
instrucciones if.. else deben evaluarse todos los casos de combinaciones de entradas para
evitar que se infieran “latches”.

8.6.1 Codificación de Estados


En el ejemplo se utiliza un tipo enumerado para describir los estados y así hacer el código
más fácil de entender. Al sintetizar este código las herramientas usarán registros y
asignarán un valor a cada estado. Si se describe la máquina de estados en VHDL el
diseñador puede optar por utilizar un registro del tipo std_logic_vector directamente. Con

©2003 Guillermo Güichal 133


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

un registro de n bits pueden codificarse 2n estados, pero muchas veces es más eficiente
utilizar codificación “one-hot” o “one-cold”. En este tipo de codificación se usan tantos
bits como estados haya y un solo bit está en ‘1’ (one hot) o ‘0’ (one cold) en un momento
dado. Esto permite simplificar la lógica combinacional que determina en que estado se
encuentra la máquina para asignar las salidas y el próximo estado.

8.6.2 División de la Señal de Reloj (Clock Enable)


Al diseñar para síntesis lo ideal es utilizar una sola señal de reloj que se distribuye a todos
los bloques del diseño. En una FPGA esta señal se conecta y distribuye a los bloques
lógicos por una red de conexiones global dedicada a ese fin. Si se desea hacer funcionar
parte del diseño, como puede ser una máquina de estados finita, a una frecuencia
diferente de la del reloj principal no debe proveerse una señal de reloj más lenta. Lo que
se utiliza es una señal de habilitación de reloj. Esta es una señal con la que se habilita el
reloj por un ciclo solo cada N ciclos. Esto hace que un proceso sincrónico se ejecute
solamente cada N ciclos de reloj en vez de con cada flanco del reloj. En VHDL esto debe
describirse como se muestra en el Cuadro 59. En general este método puede sintetizarse
de manera eficiente utilizando las señales de habilitación de los flip-flops de salida en los
bloques lógicos de las FPGA, y no agrega lógica combinacional adicional. La señal de
habilitación se debe generar en un bloque aparte dividiendo el reloj principal.

-- Formato de un proceso con señal de habilitación de reloj

ProcesoConHabilitacionClock : process(Clock_IN, Reset_IN)


begin
if (Reset_IN = '1') then
-- Valores de reset
elsif Rising_Edge(Clock_IN) then
-- Solo ejecutar las instrucciones secuenciales si el reloj
-- está habilitado
if (HabilitacionDeReloj_IN = ‘1’) then
...
...-- Instrucciones secuenciales del proceso
...
end if; -- Habilitación de reloj
end if; -- Reset, Clock

end process ProcesoConHabilitacionClock;

Cuadro 59 Utilización de la señal de habilitación de reloj

Este método de habilitación de reloj es útil y recomendado para cualquier diseño


secuencial y no solo para máquinas de estado.

©2003 Guillermo Güichal 134


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

9 VHDL para Simulación y Verificación


9.1 Introducción
El lenguaje VHDL no solo puede usarse para sintetizar circuitos sino que también pueden
crearse modelos de simulación para verificar el diseño en sus distintas etapas mediante
simulaciones. Esto se hace creando lo que se denomina un "testbench", o banco de
pruebas.

Las próximas secciones describen VHDL que muchas veces no es sintetizable. La


realidad es que eso depende de las herramientas y del uso que se le da a ese VHDL. Los
lazos serán sintetizables si pueden resolverse para un instante dado y modelan lógica
combinacional. Los accesos a archivos no son sintetizables sobre la lógica de las FPGAs,
pero algunas herramientas (Ej.: Quartus II de Altera) permiten usar código de acceso a
archivos para inicializar valores de memoria o realizar tareas similares.

9.2 Bancos de Prueba


En el proceso de diseño de un circuito sintetizable se deben probar primero los
componentes o bloques y luego el diseño completo. Esto se hace mediante simulaciones
utilizando los llamados “bancos de prueba”. El término banco de prueba proviene de las
pruebas que se hacen a diseños mecánicos o eléctricos convencionales en que el
dispositivo que se quiere probar se coloca en un banco donde también están los
generadores de señales y los analizadores para medir las respuestas. En el ambiente de
VHDL todo esto se hace de manera virtual utilizando código VHDL para generar señales
de prueba y analizando las respuestas mediante simulaciones.

La utilización de bancos de prueba y simulaciones no elimina por completo la necesidad


de probar luego el circuito sintetizado y colocado sobre una placa, pero sí simplifica
muchísimo todo el proceso de depuración.

En general hay dos niveles de interfase que se desean probar. Por un lado se quiere ver si
las formas de onda de la interfase responden a lo esperado. A un nivel superior se desea
probar si los datos de entrada/salida cumplen con lo esperado. Es decir si el diseño hace
lo que debería con los datos de entrada y responde con los datos de salida adecuados. En
el primer caso una observación de las formas de onda en general alcanza para analizar la
interfase. Para el análisis de funcionamiento a nivel datos probablemente se requerirá una
metodología mas estructurada, con algún algoritmo de prueba más sofisticado y
posiblemente leer y guardar datos de y a un archivo para su posterior análisis.

La manera de probar un componente y la complejidad del banco de pruebas dependerá


por supuesto de la funcionalidad y complejidad que tenga el dispositivo a probar. Si el
componente solo genera una forma de onda fija quizás no sea necesario hacer un análisis
a nivel de datos, si el componente es muy complejo quizás puede llevar más esfuerzo el
diseño del banco de pruebas que el del componente en sí. Como en cualquier circuito
digital, es importante probar los casos límite. Esto es más fácil de hacer en VHDL que

©2003 Guillermo Güichal 135


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

con hardware “real” ya que podemos generar cualquier combinación de señales solo
cambiando un poco de código. Algunos de estos casos son que sucede cuando los
contadores llegan a sus valores finales, que sucede cuando se sobrepasan los límites
esperados para las entradas, que sucede con combinaciones de entradas no esperadas,
utilizar un número significativo de datos de entrada, usar números aleatorios para ver el
funcionamiento, etc.

9.2.1 Vectores de prueba


Se denominan vectores de prueba (test vectors) a una secuencia de señales utilizadas para
estimular y probar un diseño. Por ejemplo, si un diseño tiene la siguiente interfase.

port (
Reset_IN : IN std_logic;
Clock_IN : IN std_logic;
Enable_IN : IN std_logic;
Mode_IN : IN std_logic_vector(2 downto 0);
Dato_OUT : IN std_logic_vector(7 downto 0)
);
los vectores de prueba serian el conjunto de señales que prueban diferentes
combinaciones de las entradas Reset_IN, Clock_IN, Enable_IN, Mode_IN para que se
permita evaluar, mediante observaciones de la salida Dato_OUT si el diseño está
funcionando bien.

Estos vectores pueden generarse mediante VHDL secuencial que explícitamente genera
la secuencia de señales deseadas, usando ciclos y arreglos de valores o leyendo los datos
de un archivo. Este último método es recomendable porque es muy flexible y permite
redefinir fácilmente los vectores de prueba sin tocar el código VHDL.

9.2.2 Diseño de un Banco de Pruebas


Al diseñar un banco de pruebas no se deben seguir las reglas estrictas que se necesitan
para síntesis, pero es buen seguir buenas prácticas de programación y estructura del
banco de pruebas.

Algunas pautas y guías para hacer un buen banco de pruebas son las siguientes:

• Englobar todo el banco de pruebas en un modelo estructural de nivel superior.


Luego conectar este modelo al diseño que se desea probar. Es bueno dar siempre
el mismo nombre de DUT o UUT (de Device Under Test o Unit Under Test) al
diseño bajo prueba. La Figura 46 muestra el esquema sugerido para un banco de
pruebas. La estructura superior contiene el diseño bajo prueba (DUT) y el
componente que genera las pruebas y analiza los resultados.
• Se recomienda separar e independizar la generación de datos de la generación de
temporizados. Esto también se mostró en la figura en el interior del “Probador”
• Utilizar el prefijo “tb” para todos los componentes del banco de pruebas. Así es
fácil diferenciar que elementos pertenecen al diseño y cuales al banco de pruebas.
Algunas organizaciones requieren que todos los elementos del banco de pruebas
se separen en una librería completamente diferente a la de diseño.

©2003 Guillermo Güichal 136


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

• No se necesitan seguir las estructuras presentadas para síntesis: como los bancos
de prueba no serán sintetizados, sino que solo sirven para las simulaciones, no es
necesario seguir las estructuras presentadas para diseños sintetizables.
• Usar las mismas guías en el código, nombres, etc. Es bueno seguir las mismas
pautas de código y nombres ya que eso hace que el banco de pruebas sea mas fácil
de entender, modificar e incluso reutilizar.
• Los procesos de prueba deberán tener un valor de reposo ya que esto es lo que
indica que se terminó la simulación y facilita la tarea al simulador (ayuda a
ejecutar la simulación más rápido).

Figura 46 Esquema de banco de pruebas para DUT

9.2.3 Manejo de tiempo en simulaciones usando VHDL


En las simulaciones se debe controlar y medir la variable tiempo. De esta manera se
pueden crear las situaciones necesarias para probar el diseño y se puede evaluar la
respuesta temporal del mismo. El manejo del tiempo se hace a través de la instrucción
wait y la palabra after. Ambas se han presentado en secciones anteriores, y en esta
sección solo se darán ejemplos de su utilización.

9.2.3.1 Uso del WAIT y AFTER


La instrucción wait es la que permite esperar una cierta cantidad de tiempo o a que
suceda un evento. En el Cuadro 60 se muestran algunos de sus usos mediante un proceso
que prueba la lectura de un dato usando un protocolo.

P_PruebaReadEnable : process
variable Dato1_VAR, Dato2_VAR : std_logic_vector(7 downto 0);

©2003 Guillermo Güichal 137


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

begin
-- Comienzo de la simulación
ReadEnable_N_OUT <= ‘1’; -- Comienzo sin lectura
wait for 1 ms; -- Espero x transitorio

-- Comienzo del primer ciclo de lectura


ReadEnable_N_OUT <= ‘0’; -- Primer ciclo de lectura
wait until ReadAck_IN = ‘1’; -- Espero aviso
Dato1_VAR := Dato_IN; -- Leo el dato

-- Fin del primer ciclo de lectura


ReadEnable_N_OUT <= ‘1’ after 12 ns; -- Mantengo señal x Thold

wait for 400 ns; -- Espera para generar 2do


-- ciclo de lectura

-- Comienzo del segundo ciclo de lectura


ReadEnable_N_OUT <= ‘0’; -- Ciclo de lectura
wait until ReadAck_IN = ‘1’; -- Espero aviso
Dato2_VAR := Dato_IN; -- Leo el dato
ReadEnable_N_OUT <= ‘1’ after 12 ns; -- Mantengo señal x Thold

wait; -- Fin de la simulación

end process P_ReadEnable;


Cuadro 60 Ejemplo del uso de wait y alter en un proceso de prueba

9.2.3.2 Función NOW


La palabra NOW se utiliza para leer el tiempo actual de simulación. Esto es muy útil
cuando se quieren medir los tiempos de respuesta de un diseño. Puede esperarse un
evento, tal como el cambio de un dato de salida del DUT (componente que se está
probando) y usando la palabra NOW guardar el tiempo de respuesta a un archivo.

En el Cuadro 61 se muestra un ejemplo en el que se verifica que el tiempo entre cambios


de una señal no sea menor que 4 ns;

-- Ver si cambia el dato. Si lo hace calcular el tiempo de cambio


if (DatoAnterior_VAR /= DatoActual_VAR) then
-- Guardo el dato y el tiempo de cambio de dato anterior
-- Leo el tiempo de cambio actual
DatoAnterior_VAR := DatoActual_VAR;

TCambioAnterior := TCambioActual;
TCambioActual := now;
...
-- Verifico si hay suficiente tiempo entre cambios

©2003 Guillermo Güichal 138


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

if (TCambioActual - TCambioAnterior) < 4 ns then


-- Error! Hay un cambio antes de los 4 ns
...
end if;
...
end if;

Cuadro 61 Ejemplo del uso de NOW para leer el tiempo de un evento

9.3 VHDL (Generalmente) No Sintetizable


Hay muchas instrucciones y estructuras de VHDL que no se pueden sintetizarse. A
continuaciones presentan algunas instrucciones de VHDL que en muchos casos no
pueden sintetizarse pero que son muy útiles para modelar ciertos procesos de hardware y
para generar las pruebas de los diseños sintetizables como se verá más adelante en la
sección sobre bancos de prueba.

9.3.1 Instrucciones de lazo FOR, WHILE y LOOP, NEXT y EXIT


Las instrucciones de lazo son instrucciones secuenciales que permiten realizar una tarea
más de una vez, hasta que se cumpla alguna condición. En general, estas instrucciones
solo son sintetizables si el resultado final puede modelarse como lógica y no contienen
instrucciones de manejo de tiempo (WAIT) dentro de los lazos. La síntesis o no de estos
lazos depende de las herramientas.

En el Cuadro 62 se dan ejemplos de lazos for . El lazo for puede usar un índice que se
incrementa o reduce según se usa la palabra to o downto. Esto dependerá de la tarea que
deba llevar a cabo el lazo. El lazo se termina con end loop y en el cuerpo se describen las
tareas que se deben realizar usando instrucciones secuénciales.

-- Formato de la instrucción FOR


for Indice in Primero to/downto Ultimo loop
... -- Instrucción secuencial
... -- Tareas que se hacen con cada Índice
... -- Instrucción secuencial
end loop;

-- Ejemplo de la instrucción FOR para inicializar un arreglo


-- cero
for Indice in 31 downto 0 loop
ArregloBits(Indice) = ‘0’;
end loop;

-- Ejemplo de la instrucción FOR para verificar la diferencia


-- entre elementos de un arreglo con elementos de tipo time
...
-- Se guarda el tiempo de lectura e incrementa el índice
TiemposLectura(UltimoIndice) := now;
UltimoIndice := UltimoIndice + 1;

©2003 Guillermo Güichal 139


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

...

-- Se verifican los tiempos leídos para ver si cumplan la


-- condición especificada
for Idx in 2 to UltimoIndice loop
if (TiemposLectura(Idx) - TiemposLectura(Idx-1) > 5 ns) then
...
... -- Escribir a un archivo que hay error en los tiempos
...
end if; -- Si hubo un deltaT > Limite
end loop; -- Para todos los elementos del arreglo
...

Cuadro 62 Formato y ejemplo de lazo FOR

El Cuadro 63 muestra el uso de la instrucción while. En esta expresión se especifica una


condición buleana al comienzo. Mientras esa condición se evalúe como verdadera (true)
se seguirá ejecutando el cuerpo secuencial del lazo.

-- Formato de la instrucción WHILE


while Indice in Primero to/downto Ultimo loop
... -- Instrucción secuencial
... -- Tareas que se hacen con cada Indice
... -- Instrucción secuencial
end loop;

-- Ejemplo de la instrucción FOR para inicializar un arreglo


-- cero
for Indice in 31 downto 0 loop
ArregloBits(Indice) = ‘0’;
end loop;

-- Ejemplo de la instrucción FOR para verificar la diferencia


-- entre elementos de un arreglo con elementos de tipo time
...
-- Se guarda el tiempo de lectura e incrementa el índice
TiemposLectura(UltimoIndice) := now;
UltimoIndice := UltimoIndice + 1;
...
...
-- Se verifican los tiempos leídos para ver si cumplan la
-- condición especificada
for Idx in 2 to UltimoIndice loop
if (TiemposLectura(Idx) - TiemposLectura(Idx-1) > 5 ns) then
...
... -- Escribir a un archivo que hay error en los tiempos
...
end if; -- Si hubo un deltaT > Limite

©2003 Guillermo Güichal 140


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

end loop; -- Para todos los elementos del arreglo


...

Cuadro 63 Formato del lazo WHILE

En el Cuadro 64 se muestra el formato del lazo utilizando la instrucción loop. En este


lazo se usan las instrucciones next y exit para manejar los saltos a la próxima ejecución
del lazo o para salir. Hay varias maneras de usar las instrucciones next y exit. La más
simple es como instrucciones por su cuenta, generalmente utilizado después de una
comparación if.. para salir del lazo si l condición se cumple. También se puede usar la
palabra when para especificar la condición en la misma línea de instrucción

-- --------------------------------------------------------- --
-- Formato de la instrucción LOOP, NEXT y EXIT
loop
... -- Instrucciones secuenciales
next (when Condición); -- Reinicia el lazo
... -- Instrucciones secuenciales
exit (when Condición); -- Sale del lazo (salta después
-- del “end loop”)
... -- Instrucciones secuenciales
end loop;

-- --------------------------------------------------------- --
-- Ejemplo de lazo loop con condiciones de salida
--
Indice := 0; -- Inicialización del índice
loop -- Comienzo del lazo
Indice := Indice + 1; -- Incremento del índice
...
... -- Instrucciones secuenciales que se ejecutarán
... –- para todos los valores de Indice
...
next when Indice <= 5; -- Reinicia el lazo si Indice < 5
...
... -- Instrucciones secuenciales que se ejecutan solo si
... -- Indice es mayor que 5
...

exit when Indice = 10; -- Sale del lazo con Indice = 10


end loop;
...

Cuadro 64 Formato del lazo LOOP

Ejemplos de formatos de uso de next y exit en un lazo:


• exit;

©2003 Guillermo Güichal 141


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

• next;
• if (Condición buleana) then
exit;
end if;
• if (Condición buleana) then
next;
end if;
• exit when (Condición buleana);
• next when (Condición buleana);

9.3.2 Instrucciones ASSERT y REPORT


Estas instrucciones se utilizan durante simulación para dar mensajes sobre el estado de
funcionamiento de un modelo al usuario. Son instrucciones secuenciales que pueden
utilizarse en cualquier punto del cuerpo de un proceso. El formato para esta instrucción es

assert ExpresiónDeCondición report Mensaje severity NivelDeFalla;

ExpresiónDeCondición: expresión buleana que provocará una falla si se evalúa como


false

Mensaje: Cadena de caracteres que da un mensaje al usuario sobre la falla.

NivelDeFalla: Usado para informar el nivel de severidad de la falla. En general el


simulador detendrá la simulación si la falla es muy grave. El límite para
esto puede ser fijado por el usuario. A continuación se dan los posibles
niveles de falla y un comentario sobre el uso de cada uno
• note : Mensaje para informar al usuario
• warning : Hay algo mal en el modelo y pueden producirse resultaos
inesperados.
• error : Error en el modelo que no
• failure : Falla muy grave que no puede suceder nunca. Detendrá al
simulador.

Ejemplos de uso de assert, report:


-- Nota al usuario sobre el funcionamiento del modelo
assert MemoriaLibre >= MEM_LIMITE_MINIMO
report “Memoria baja, se sobrescribirán primeros valores”
severity note;

-- Mal funcionamiento dentro del modelo


assert NumeroBytes = 0
report “Se recibió paquete sin datos”
severity warning;

-- Error en una señal que no generará el efecto esperado

©2003 Guillermo Güichal 142


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

assert AnchoDePulso >= 2 ns


report “Pulso demasiado chico. No generará interrupción.”
severity error;

-- Error en el modelado de un componente


assert NumeroDeEntradas = NumeroDeSalidas
report “Error en el modelo. No se puede simular”
severity failure;

La instrucción report puede usarse por si sola para generar mensajes que ayuden en la
depuración del código. La expresión tiene la forma

Uso y ejemplos de report


report Mensaje; -- Formato de la instrucción report
report “Nuevo dato de entrada”;

9.3.3 Manejo de Archivos y Paquete TEXTIO


Además de los tipos predefinidos nombrados anteriormente, VHDL contiene el tipo file
para poder manejar archivos. Además provee varias instrucciones para el manejo de
archivos. Estas operaciones se muestran en la Tabla 13. Los archivos pueden abrirse en
tres modos: read_mode para lectura, write_mode para escritura a un archivo nuevo y
append_mode para agregar datos al final de un archivo existente. Los archivos en VHDL
pueden contener un solo tipo de datos, incluyendo escalares, arreglos de una dimensión o
datos de tipo record.

Tabla 13 Operaciones con archivos provistas por VHDL


Descripción
file_open Procedimiento utilizado para abrir de manera explícita un archivo
file_close Procedimiento utilizado para cerrar de manera explícita un archivo
read Procedimiento utilizado para leer un dato de un archivo
write Procedimiento utilizado para escribir un dato a un archivo
endfile Función que verifica si se ha llegado al final de un archivo y
devuelve true o false

Un archivo puede declararse en cualquier sección de declaración, ya sea de una


arquitectura, un proceso o un subprograma. Al hacer la declaración puede asociarse un
archivo físico, o esto puede hacerse más adelante utilizando la instrucción open.

Al escribir datos a un archivo estos se guardarán con un formato binarios que dependerá
del sistema sobre el que se está trabajando. En general estos no pueden ser analizados
directamente por el desarrollador. En muchos casos es importante que se puedan escribir
o leer los datos directamente de los archivos. De esta manera se hace fácil especificar los
datos de entrada a un modelo o verificar sus resultados. Para simplificar la escritura y
lectura de archivos en un formato entendible para el usuario, la librería std provee el

©2003 Guillermo Güichal 143


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

paquete textio. Este paquete permite acceder a archivos que contienen cadenas de
caracteres. Así, todos los datos serán cadenas de texto. Pueden usarse funciones de
conversión para guardar o escribir cualquier tipo de dato en estos archivos. En lo que
resta de esta sección se presentará el paquete textio y su utilización para leer y guardar
datos de simulación. El lector puede referirse a la bibliografía para estudiar el uso de
otros tipos de archivo.

Para utilizar archivos de texto en un banco de pruebas (el manejo de archivos no es


sintetizable), se deben agregar las siguientes líneas en el código

library std;
use std.textio.all;

Esto hace accesible el paquete textio que incluye los tipos y procedimientos mostrados en
la Tabla 14. También incluye los archivos que pueden utilizarse directamente "input" y
"output" asociados a los archivos físicos "std_input" y "std_output". Estos se proveen
para poder acceder a los dispositivos estándar de entrada / salida, que en general están
definidos como la pantalla y el teclado en casi todos los sistemas.

Tabla 14 Tipos y procedimientos en textio


Tipo Descripción
line Tipo declarado como cadena de caracteres "string"
text Tipo declarado como archivo de tipos line
side Tipo enumerado que toma los valores left o right (izquierda o
derecha)
width Tipo definido como natural (números de 0 al máximo entero)
Procedimiento
readline Procedimiento que permite copiar (leer) una línea de un archivo a
una variable del tipo "line" (cadena de caracteres)
writeline Procedimiento que permite copiar (escribir) una variable del tipo
"line" a un archivo
read Serie de procedimientos sobrecargados para diferentes tipos de
parámetro que permiten leer diferentes datos de una variable tipo line
write Serie de procedimientos sobrecargados para diferentes tipos de
parámetro que permiten escribir diferentes datos a una variable tipo
line

Las operaciones de entrada salida sobre los archivos utilizando textio se hacen línea a
línea. Esto permite que varios procesos accedan a un mismo archivo. Como la secuencia
de escritura a un archivo de varios procesos concurrentes es impredecible, al escribir
líneas completas no se entremezclarán los datos sino que a lo sumo se alternan líneas de
un proceso y otro. Si cada proceso marca de alguna manera las líneas que escribe es fácil
descifrar el funcionamiento del modelo en su conjunto al analizar el archivo.

©2003 Guillermo Güichal 144


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Para leer datos usando textio se debe declarar una variable del tipo line y abrir un
archivo de subtipo text. Mediante una instrucción secuencial readline se lee una línea del
archivo. Esa línea luego se procesa usado las diferentes variantes de read para extraer los
datos.

Para escribir una línea a un archivo primero se escriben los datos a una variable del tipo
line utilizando las diferentes variantes de write y luego se escribe la línea al archivo
usando writeline.

9.3.4 Palabra reservada ALIAS


Como se mencionó anteriormente, el lenguaje VHDL da mucha flexibilidad para la
definición de nuevos tipos y subtipos. Esto permite ordenar y organizar los modelos para
que sean fáciles de entender y se adecuen a los componentes que se quieren modelar.
Otra instrucción que es muy útil para poder hacer que los modelos sean más claros de
entender es la palabra reservada alias.

Esta palabra permite definir nuevos nombres para datos y otros objetos. En el caso más
simple un alias se refiere a un dato con otro nombre. El Cuadro 65 muestra algunos
ejemplos. La capacidad de sintetizar o no diseños que utilizan alias depende de las
herramientas, y se recomienda no utilizarlas para diseños que se sintetizarán para FPGAs.

-- Ejemplo de alias para nombrar los registros y bits


-- del conjunto de registros de una CPU
subtype tdCPURegistro is std_logic_vector(15 downto 0);

type tdCPUSetRegistros is record


ContadorPrograma : tdCPURegistro;
RegistroGeneral : tdCPURegistro;
RegistroControl : tdCPURegistro;
RegistroEstado : tdCPURegistro;
RegistroAuxiliar1 : tdCPURegistro;
RegistroAuxiliar2 : tdCPURegistro;
end record;

-- Se declara una señal con el nuevo tipo


signal CPURegisterSet_REG : tdCPUSetRegistros;

-- Se definen alias para los registros de la señal declarada


alias CpuPC_REG is CPURegisterSet_REG.ContadorPrograma;
alias CpuGPR_REG is CPURegisterSet_REG.RegistroGeneral;
alias CpuState_REG is CPURegisterSet_REG.RegistroEstado;
alias CpuControl_REG is CPURegisterSet_REG.RegistroControl;
alias CpuA1_REG is CPURegisterSet_REG.RegistroAuxiliar1;
alias CpuA2_REG is CPURegisterSet_REG.RegistroAuxiliar1;

-- Se definen alias para algunos bits de algunos registros


alias CpuPCHigh_REG is CpuPC_REG(15 downto 8);
alias CpuPCHigh_REG is CpuPC_REG(7 downto 0);

©2003 Guillermo Güichal 145


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

-- Estado de las interrupciones


-- Vector de interrupciones que incluye todos los bits
alias CpuInterrupcion_REG is CpuState_REG(4 downto 0);

-- Bits de interrupcion uno a uno


alias CpuInterrupcion1_REG is CpuState_REG(0);
alias CpuInterrupcion2_REG is CpuState_REG(1);
alias CpuInterrupcion3_REG is CpuState_REG(2);
alias CpuInterrupcion4_REG is CpuState_REG(3);

Cuadro 65 Ejemplos declaración de alias

9.3.5 Ejemplos de Componentes para Bancos de Prueba


A continuación se dan algunos ejemplos de componentes para pruebas que usan manejo
del tiempo y otras estructuras no sintetizables. Los primeros dos serán utilizados para
probar casi todos los diseños, ya que describen una generación de reloj y generación de
una señal de reset. El último ejemplo muestra como puede simularse un ciclo de bus de
CPU.

9.3.5.1 Generación de Señal de Reloj


En el Cuadro 66 se muestra un componente que genera una señal de reloj con el período
dado por una constante genérica.

library ieee;
use ieee.std_logic_1164.all;

entity tbGeneradorReloj is
generic (
PERIODO_NS : time := 20 ns
);
port (
SimmulacionActiva_IN : IN std_logic;
Reloj_OUT : OUT std_logic
);

end tbGeneradorReloj ;

architecture Comportamiento of tbGeneradorReloj is


begin

P_Reloj : process
begin
wait for 1 ns;
while (SimmulacionActiva_IN = '1') loop

©2003 Guillermo Güichal 146


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Reloj_OUT <= '0';


wait for PERIODO_NS / 2;
Reloj_OUT <= '1';
wait for PERIODO_NS / 2;
end loop; -- Simulación activa
Reloj_OUT <= '0';
wait; -- Proceso en espera permanente
end process P_Reloj;

end Comportamiento;

Cuadro 66 Generación de una señal de reloj para pruebas

9.3.5.2 Generación de una Señal de Reset


En el Cuadro 67 se muestra un componente que genera una señal de “Reset” con el
tiempo de reset activo dado por una constante genérica.

library ieee;
use ieee.std_logic_1164.all;

entity tbGeneradorReset is
generic (
TIEMPO_RESET : time := 250 ns
);
port (
Reset_OUT : OUT std_logic
);

end tbGeneradorReset ;

architecture Comportamiento of tbGeneradorReset is


begin

P_Reset : process
begin
Reset_OUT <= ‘1’; -- Reset activo
wait for TIEMPO_RESET; -- Se mantiene reset activo
Reset_OUT <= ‘0’; -- Reset baja. Comienza a funcionar
-- el circuito
wait; -- Proceso en espera permanente
end process P_Reset;

end Comportamiento;

Cuadro 67 Generación de una señal de reset para pruebas

©2003 Guillermo Güichal 147


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

9.3.5.3 Temporizado de la Interfase de un Bus de Microcontrolador


En este ejemplo la FPGA tendrá una interfase con un microcontrolador (uC) genérico
muy simple. Para probar el diseño se debe crear un banco de pruebas que simule la
interfase de ese uC. El banco de pruebas tendrá dos niveles. Por un lado se generarán y
leerán datos para verificar el funcionamiento del diseño a alto nivel. Por otro esos datos
se transferirán desde y hacia la FPGA simulando el temporizado del bus del uC (ya que
esa es la manera en la que los dos dispositivos irán conectados en el hardware final). En
la Figura 47 se muestra el temporizado de este bus sincrónico. La Tabla 15 y Tabla 16
dan los valores de tiempo correspondientes y el Cuadro 68 muestra el VHDL que simula
la interfase.

Ciclo de lectura Ciclo de escritura

Clock
tClock
tSWData tHWData
tSRData
tHRData

Data
tHAddress
tSAddress tHAddress tSAddress

Address
tSRead tHRead

ReadEnable tHWrite
tSWrite

WriteEnable

Figura 47 Temporizado de uC a simular en el banco de pruebas

Tabla 15 Tiempos para ciclo de lectura de uC


Parámetro Descripción Mínimo Máximo
tClock Período del reloj (48 - 52% duty cycle) 100 ns 1 us
tSAddress Tiempo de “setup” de direcciones antes del primer flanco 50 ns
positivo de reloj
tHAddress Tiempo de mantenimiento o “hold” de la dirección después 8 ns 14 ns
del flanco positivo de reloj
tSRead Tiempo de “setup” de señal ReadEnable en ‘0’ antes del 54 ns
flanco positivo de reloj
tHRead Tiempo de mantenimiento o “hold” de la señal ReadEnable 4 ns 8 ns
después del flanco positivo de reloj
tSRData Tiempo de “setup” del dato necesario antes del flanco 15 ns
positivo de reloj
tHRData Tiempo de mantenimiento o “hold” del dato necesario 1 ns
después del flanco positivo de reloj

©2003 Guillermo Güichal 148


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Tabla 16 Tiempos para ciclo de escritura de uC


Parámetro Descripción Mínimo Máximo
tClock Período del reloj (48 - 52% duty cycle) 100 ns 1 us
tSAddress Tiempo de “setup” de direcciones antes del primer flanco 50 ns
positivo de reloj
tHAddress Tiempo de mantenimiento o “hold” de la dirección después 8 ns 14 ns
del flanco positivo de reloj
tSWrite Tiempo de “setup” de señal WriteEnable en ‘0’ antes del 62 ns
flanco positivo de reloj
tHWrite Tiempo de mantenimiento o “hold” de la señal WriteEnable 4 ns 8 ns
después del flanco positivo de reloj
tSWData Tiempo de “setup” de datos antes del flanco positivo de 58 ns
reloj
tHWData Tiempo de mantenimiento o “hold” del dato después del 6 ns 15 ns
flanco positivo de reloj

-- ------------------------------------------------------- --
-- Ejemplo de ciclo de temporizado de un bus de uC
...
... -- Declaración de librerías y uso de paquetes.
...

-- Entidad para banco de pruebas que simula el micocontrolador


entity tbMicroControlador is
generic(
T_CLOCK : time := 200 ns
);
port(
Reset_IN : in std_logic;
Clock_IN : in std_logic;
ReadEnable_OUT : out std_logic;
WriteEnable_OUT : out std_logic;
Address_OUT : out std_logic_vector(19 downto 0) ;
Data_IO : inout std_logic_vector(15 downto 0)
);
end tbMicroControlador;

architecture Comportamiento of tbMicroControlador is

-- Constantes de parámetros de temporizado del bus


constant T_SETUP_ADDRESS : time := 50 ns;
constant T_HOLD_ADDRESS : time := 8 ns;
constant T_SETUP_READENABLE : time := 54 ns;
constant T_HOLD_READENABLE : time := 4 ns;
constant T_SETUP_R_DATA : time := 15 ns;
constant T_HOLD_R_DATA : time := 1 ns;
constant T_SETUP_WRITEENABLE : time := 62 ns;
constant T_HOLD_WRITEENABLE : time := 4 ns;
constant T_SETUP_W_DATA : time := 58 ns;
constant T_HOLD_W_DATA : time := 6 ns;
...
... -- Declaración de tipos, señales internas, etc.
...

©2003 Guillermo Güichal 149


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

begin

-- En el proceso de control se leen las operaciones y datos


-- de los ciclos del uC de un archivo de comandos.
-- Los ciclos del bus y los datos se guardan a un archivo
-- junto a una etiqueta de tiempo, mensajes de error, etc.
-- para ser revisados después y analizar el funcionamiento
-- del diseño
-- Cada vez que se debe acceder al bus se usan los
-- procedimientos de LeerDato, EscribirDato definidos
-- antes del begin del proceso

SimulacionDeMicro : process

variable FinDeSimulacion : boolean := false;


... –- Otras variables auxiliares para controlar simulación

variable DatoAEscribir_VAR : std_logic_vector(15 downto 0);


variable DatoEnTiempoSetup_VAR : std_logic_vector(15 downto 0);
variable DatoEnTiempoHold_VAR : std_logic_vector(15 downto 0);
variable DireccionWrite_VAR : std_logic_vector(19 downto 0);
variable DireccionRead_VAR : std_logic_vector(19 downto 0);

-- Procedimientos de acceso al bus que controlan los


-- temporizados y se usan en los procesos de simulación
-- de las operaciones a nivel dato para leer y escribir
-- el bus
procedure LeerDato is
begin

wait until Rising_Edge(Clock_IN);


ReadEnable_OUT <= ‘0’ after (T_CLOCK – T_SETUP_READENABLE);
Address_OUT <= DireccionRead_VAR after T_CLOCK –
T_SETUP_ADDRESS;
wait until Rising_Edge(Clock_IN);

wait for (T_CLOCK – T_SETUP_R_DATA);


DatoEnTiempoSetup_VAR := Data_IO;

wait until Rising_Edge(Clock_IN);


wait for T_HOLD_R_DATA;
DatoEnTiempoHold_VAR := Data_IO;

ReadEnable_OUT <= ‘1’ after (T_HOLD_READENABLE–T_HOLD_R_DATA);

Address_OUT <= (others => ‘0’) after (T_HOLD_ADDRESS –


T_HOLD_R_DATA);
end LeerDato;

procedure EscribirDato is
begin

wait until Rising_Edge(Clock_IN);


WriteEnable_OUT <= ‘0’ after (T_CLOCK –
T_SETUP_WRITEENABLE);

©2003 Guillermo Güichal 150


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Address_OUT <= DireccionWrite_VAR after (T_CLOCK –


T_SETUP_ADDRESS);
Data_IO <= DatoWrite_VAR after (T_CLOCK –
T_SETUP_W_DATA);
wait until Rising_Edge(Clock_IN);
wait until Rising_Edge(Clock_IN);

WriteEnable_OUT <= ‘1’ after T_HOLD_WRITEENABLE;


Address_OUT <= (others => ‘0’) after T_HOLD_ADDRESS;
Data_IO <= (others => ‘Z’) after T_HOLD_W_DATA;

end EscribirDato;

-- Comienzo del proceso de simulación del uC


begin

-- Valores iniciales
ReadEnable_OUT <= '1';
WriteEnable_OUT <= '1';
Address_OUT <= (others => '0');
Data_IO <= (others => 'Z');

-- Esperar a salir del estado de reset. NO es mala idea probar


-- a ver que pasa durante el re3set, pero aquí no se hace
wait until Reset_IN = '0';

-- Lazo de simulación de X operaciones, o hasta que se acabe


-- el archivo
while (FinDeSimulacion = false) loop
...
-- Leer operación y datos de un archivo
...
case OperacionDeCPU is
when OP_CPU_LECTURA =>
...
LeerDato;
...
-- Escribir resultados a un archivo
...
when OP_CPU_ESCRITURA =>
...
EscribirDato;
...
... -- Escribir resultados a un archivo
...
when ...
...
-- Otros comandos y procesamiento de los datos leídos, etc.
...
...
...

Cuadro 68 Simulación de la interfase de un microcontrolador

©2003 Guillermo Güichal 151


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

9.4 Que Falta sobre VHDL…


El objetivo de estas notas en cuanto a VHDL es presentarlo en el contexto de los diseños
sintetizables para FPGAs y dar una guía rápida y ejemplos para que el lector pueda
utilizarlo lo más rápido posible. Hay varias instrucciones, estructuras, e infinitas
posibilidades de uso de VHDL que no han sida descriptas. Algunas de estos temas no se
usan en circuitos sintetizables y otros no se incluyeron para no hacer estas notas
demasiado largas y pesadas. Para ahondar más en estos temas se recomiendan los textos
mencionados en la sección Bibliografía o utilizar Internet para buscar la información
deseada.

Algunos temas que no se han tratado son:


• Diferencias entre las diferentes versiones de VHDL
• Modo BUFFER para puertos de entidades (no se presentan ya que no son
recomendados para síntesis)
• Atributos de tipos escalares y señales (attributes)
• Arreglos multidimensionales
• Mecanismos de retardo inerciales y de transporte (inertial and transport
delay mechanisms)
• Subprogramas: Procedimientos y funciones no se explicaron de manera
exhaustiva
• Múltiples arquitecturas y uso de configuraciones (configure)
• Bloques y guardas (guards, blocks)
• Manejo de archivos de otro tipo que el definido en textio
• etc., etc., etc.

©2003 Guillermo Güichal 152


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

10 Buenas Prácticas de Diseño


10.1 Introducción
Al diseñar hardware utilizando VHDL no debe olvidarse que el producto es parte de un
sistema más grande y que interactuará con componentes y señales externas sobre las que
no hay control. En este sentido el diseñador debe estar al tanto de los requerimientos,
tolerancias, frecuencias etc. de estas señales y componentes para poder proveer una
interfase que se adecue a la funcionalidad prevista.

Por otro lado, las FPGAs permiten el desarrollo de sistemas muy complejos en un solo
componente. Estos diseños pueden llegar a ser bastante sofisticados y tener una jerarquía
que utilice componentes desarrollados por diferentes personas. Para poder manejar esto
de manera controlada es bueno tener pautas o guías de diseño que ayuden a la interacción
y reutilización de la propiedad intelectual. En esta sección se presentarán de manera
básica una serie de puntos y recomendaciones relacionadas con estos temas.

10.2 Documentación
Si se pretende tener un producto (re)utilizable, vendible, o que pueda entenderse después
de tenerlo archivado unos meses es imprescindible crear buena documentación.
COMPLETAR CON PAUTAS SOBRE DOCUMENTACIÓN.

10.3 Guía de estilo para el código HDL


Ya se ha planteado la importancia de crear diseños que puedan ser entendidos facilmente,
ya sea otros desarrolladores, clientes, auditores o el mismo desarrollador un tiempo más
tarde. Para facilitar esto, una organización debería tener una guía documentada que pueda
ser consultada por todos los desarrolladores. De esta manera se evitan las confusiones y
se acelera el aprendizaje de nuevos integrantes del equipo. En esta sección se presenta un
ejemplo de documento de este tipo. Este es solo un ejemplo, y no debe tomarse como el
único modelo que puede ser utilizado. Lo más importante es ser consistente a través del
tiempo y con el resto de la organización al escribir código (ya sea VHDL o en cualquier
otro lenguaje de programación).

• Lenguaje de programación en general


o En los lenguajes que no son sensibles a las mayúsculas ser consistente en el
uso de la capitalización para las palabras reservadas.
o En los lenguajes que son sensibles a las mayúsculas no se deben diferenciar
los nombres de funciones, entidades, procesos, etc. solo por las mayúsculas
o Colocar las instrucciones begin y end en su propia línea de programa
o En general, cada instrucción independiente del programa deberá estar en su
propia línea
o No usar constantes mágicas. Definir todas las constantes con palabras que las
identifiquen inequívocamente.
o Dar un nombre a todos los procesos para aclarar su funcionalidad.

©2003 Guillermo Güichal 153


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

o Usar un prefijo “td” para los tipos definidos en el programa


o Usar paréntesis aunque no sean necesarios si ayudan a entender la prioridad y
sentido de la lógica que se está describiendo.

• Programación en VHDL
o No mezclar estándares de programación. Usar sintaxis VHDL 87 o 93
exclusivamente)
o Usar un archivo por entidad (“entity”) que defina su interfase y arquitectura.
El nombre del archivo deberá ser igual al de la entidad.
o Usar tipos std_logic para todas los puertos de interfase externa
o Nunca asignar un valor desconocido ‘X’ o verificar un don’t care ‘-‘
(producen resultados inesperados en la síntesis y las simulaciones)
o No usar los valores por defecto para señales y variables. Asignarles un valor
inicial durante el estado de Reset.
o Tratar de usar el mismo nombre para las señales a través de toda la jerarquía
de diseño, quizás agregando prefijos o sufijos.
o Definir todas las constantes para un diseño en un solo “package”
o Usar constantes y parámetros genéricos para definir el tamaño de los buffers y
buses. (Ayuda a reutilizar el código)
o No utilizar puertos del tipo “BUFFER” para leer un valor de salida. En vez de
eso usar tipos “OUT” y agregar otra señal interna a la que se le asigna el
mismo valor.

• Nombres de las señales, variables y constantes


o Usar nombres que den una clara idea de los datos que contiene la señal o
constante. Usar palabras completas y no abreviaturas que son difíciles de
descifrar y recordar.
o Para los nombres de las señales usar mayúsculas solo para identificar las
palabras del nombre. (Ej.: NombreDelProceso)
o Usar todas mayúsculas separadas con “_” para definir constantes. Dar un
prefijo especifico a todas las constantes de acuerdo al proyecto. Usar una
secuencia jerárquica de palabras clave para especificar a que valor se está
refiriendo una constante (Ej.: UTN_ADC_MAXIMO, UTN_ADC_MINIMO).
o Usar nombres que den una idea clara de la función de los módulos, procesos o
procedimientos.
o Usar los siguientes sufijos para las señales en VHDL
sin sufijo : cable
_N : lógica negada (“active low”)
_REG : señal almacenada en un registro
_LATCH : señal almacenada en un match
_DLY : señal retrasada a través de un registro
_IN : puerto (port) de entrada a una de una entidad (entity)
_OUT : puerto (port) de salida de una de una entidad (entity)
_IO : puerto (port) de entrada/salida de una entidad (entity)

©2003 Guillermo Güichal 154


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

o Usar los siguientes prefijos para las señales en VHDL


sin prefijo : cable
int : representación interna de un puerto de una “entity”

• Nombres de módulos procesos, procedimientos


o Usar nombres que den una idea clara de la función de los módulos, procesos o
procedimientos.
o Ser sistemático en el formato de los nombres.
o Usar mayúsculas para dividir las palabras de un nombre. Dejar “_” para las
nombres de las variables.

• Indentación, espacios y líneas en blanco


o Hacer un consistente y buen uso de los espacios, indentación y líneas en
blanco para que el código sea mas entendible y claro.
o La indentación debe ser fija y consistente para todo proyecto. Dos espacios es
un valor razonable. Los TABs deberán estar definidos como 2 espacios.
o No escribir líneas de código de mas de 80 caracteres. Partir la línea larga entre
varias y alinearla para que se comprenda mejor.
o Usar líneas en blanco para separar las declaraciones de las funciones, los
bloques funcionales de código, etc.
o Indentar la primer línea de código después de la declaración de un proceso o
procedimiento. Todo el código que implementa el proceso quedará así
indentado debajo de la declaración.

• Comentarios
o Usar los comentarios para describir la lógica y el motivo del programa. No
comentar lo obvio.
o Usar líneas completas comentadas para dividir grandes bloques lógicos del
programa
o Usar comentarios para especificar que condición está cerrando un comando
END
o Siempre debe agregarse un comentario para describir lógica que no es obvia o
tiene particularidades que son difíciles de entender a simple vista.

Ejemplos:

• Comentarios, espacios y nombres


-- -----------------------------------------------------------------------------
-- LIMITES PARA LOS DATOS LEIDOS DEL ADC
-- -----------------------------------------------------------------------------
constant UTN_ADC_VALOR_MAXIMO : std_logic_vector(12 downto 0) := “0010000000000”;
constant UTN_ADC_VALOR_MINIMO : std_logic_vector(12 downto 0) := “1110000000000”;

-- -----------------------------------------------------------------------------
-- SEÑALES
-- -----------------------------------------------------------------------------
signal ADCdataBus : std_logic_vector(12 downto 0);
signal ADCReady : std_logic;
signal ADCRead : std_logic;

©2003 Guillermo Güichal 155


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

• Capitalización, comentarios nombres, espacios e indentación


Usar:
-- Proceso que suma las dos entradas leídas de los puertos serie
P_SumaDatosSerie : process (Clock_IN, Reset_IN)
begin
if (Reset_IN = ‘0’) then
...
elsif (Clock_IN’event and Clock_IN = ‘1’) then
...
end; -- if Reset, Clock
end process; -- Proceso Suma Datos Serie
y no
ProcesoX1 : process (Clock_IN, Reset_IN) -- No hay una descripción del proceso
BEGIN -- la indentación esta mal
if (Reset_IN = ‘0’) THEN -- Si el Reset es cero Obvio
elsif (Clock_IN’EVENT And Clock_IN = ‘1’) then -- si hay un flanco de reloj Obvio
-- suma los datos Esto debería estar describiendo el proceso, no aquí
...
end; end PROCESS; -- Cada end en su propia línea

• Usar:
signal DatoDeEntrada_N_REG : std_logic_vector(2 downto 0);
signal DatoDeSalida_REG : std_logic_vector(2 downto 0);
...
P_umaDeEntradas : PROCESS(Clock_IN, Reset_IN)…
P_RestaDeEntradas : PROCESS(Clock_IN, Reset_IN)…
y no:
signal datodeentrada_N_REG : std_logic_vector(2 downto 0); -- No hay un estándar
-- para los nombres
signal salida : std_logic_vector(2 downto 0); -- alinear los espacios
...
SumaDeEntradas : PROCESS(Clock_IN, Reset_IN)… -- no hay consistencia en
Proceso_Entradas_Resta : PROCESS(Clock_IN, Reset_IN)… -- el formato de los nombres

10.4 Programación para Diseños Sintetizables


Al hacer código VHDL para diseños sintetizables conviene utilizar las normas de código
para síntesis recomendadas. Según la herramienta que se use la implementación puede
depender más o menos del código que se escriba. Las recomendaciones de VHDL para
síntesis generales (estándar 1076.x) y de los fabricantes enseñan que esperan las
herramientas para indicar las características que se desean en un diseño.

10.4.1 Diferencias entre Síntesis y Simulación


Diferencias que pueden existir entre diseño simulado y sintetizado. Tiempos no exactos
en simulación. Hay que hacer síntesis y anotar con SDF. Puede haber diferencias,
especialmente con lógica combinacional y latches.

10.4.2 División de la Frecuencia Mediante Habilitación del Reloj


Al diseñar para síntesis lo ideal es utilizar una sola señal de reloj que se distribuye a todos
los bloques del diseño. En una FPGA esta señal se conecta y distribuye a los bloques
lógicos por una red de conexiones global dedicada a ese fin. Si se desea hacer funcionar
parte del diseño a una frecuencia diferente de la del reloj principal no debe proveerse una
señal de reloj más lenta. Esto es, para diseños con FPGAs no se recomienda dividir el
reloj y generar una señal de menor frecuencia y duty cycle del 50%, sino que se

©2003 Guillermo Güichal 156


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

recomienda generar una señal de habilitación de reloj. Esta es una señal con la que se
habilita el reloj por un ciclo solo cada N ciclos. Esto hace que un proceso sincrónico se
ejecute solamente a la frecuencia deseada (cada N flancos de reloj) en vez de con cada
flanco del reloj. La Figura 48 muestra el método de división de frecuencia recomendado
para diseños sobre FPGAs.

Figura 48 División de frecuencia recomendada para FPGAs usando habilitación de reloj (CE)

La Figura 49 muestra como NO debe implementarse una división de reloj en un diseño


con FPGAs. Aunque este método es muy utilizado en diseños digitales convencionales,
no aprovecha los recursos de la FPGA y puede causar problemas de temporizado y
sincronización en el circuito implementado. En general, solo se recomienda manejar las
señales de reloj de los flip-flops a partir de las redes de distribución global de reloj y
nunca desde lógica combinacional.

©2003 Guillermo Güichal 157


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Figura 49 División de frecuencia mediante divisor de reloj (No utilizar en FPGAs)

Usando VHDL, el método recomendado para implementar la división de frecuencia se


muestra en el Cuadro 69. Esta manera de dividir el reloj se sintetiza de manera muy
eficiente utilizando las señales de habilitación de los flip-flops en los bloques lógicos de
las FPGA. La señal de habilitación se debe generar en un bloque aparte dividiendo el
reloj principal.

-- Formato de un proceso con señal de habilitación de reloj


ProcesoConHabilitacionClock : process(Clock_IN, Reset_IN)
begin
if (Reset_IN = '1') then
-- Valores de reset
elsif (Rising_Edge(Clock_IN) then
-- Solo ejecutar las instrucciones secuenciales si el reloj
-- está habilitado
if (HabilitacionDeReloj_IN = ‘1’) then
...
...-- Instrucciones secuenciales del proceso
...
end if; -- Habilitación de reloj
end if; -- Reset, Clock
end process ProcesoConHabilitacionClock;

Cuadro 69 Utilización de la señal de habilitación de reloj

©2003 Guillermo Güichal 158


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

10.5 Guía de Estilo Para un Buen Diseño de Hardware


Así como una organización debería tener una guía para la estructura y formato del código
para que sea entendible y reutilizable, lo mismo es válido a nivel de componentes para
que estos puedan interconectarse sin mayores esfuerzos a otros bloques y reutilizarse en
otros proyectos. Es una buena idea que se tengan estas normas o guías para el desarrollo
de hardware centralizadas en un documento que puede ser consultado por los
desarrolladores. En este documento deberían volcarse las normas preferidas de interfase y
estructuras de desarrollo así como también la experiencia y aprendizajes de la
organización. De esta manera se ayuda a que luego la propiedad intelectual sea más fácil
de comprender y reutilizar por otros o incluso por la misma persona después de un
tiempo, se evita repetir errores y los nuevos desarrolladores pueden aprender de la
experiencia de otros.

Hay muchos errores comunes que pueden evitarse facilmente siguiendo este tipo de
pautas Por ejemplo, si algunos desarrolladores utilizan una señal de reset positiva y otros
negativa, o si algunos no proveen un estado de reset conocido o si algunos nombran los
buses del bit más significativo al menor y otros al revés, esto puede causar errores al
integrarlos en un diseño. A continuación se da como ejemplo una lista de algunas
recomendaciones para diseños utilizando VHDL tomado de guías de desarrollo de
organizaciones reales. Estos son las pautas que se ha tratado de utilizar a través de este
texto para todos los ejemplos.

• Señal de Reset
Proveer una señal de Reset porque hace que un diseño sea determinístico y evita
que se llegue a estados prohibidos
o Todos los Flip-Flop deberán tener un Reset de lógica positiva, asincrónico.
Este Reset deberá estar conectado a la pata de Reset global de la FPGA o
CPLD de ser posible.
o El Reset asincrónico se usará a nivel local en todos los módulos. Este se
sincronizará con el reloj al nivel lógico mas alto de la jerarquía de diseño.
(Evita des-sincronización por caminos de diferente longitud de la señal de
Reset).
o Durante el estado de Reset todos los puertos bidireccionales deberán colocarse
en el estado de entrada. (Esto es lo que espera el “boundary scan” y evita tener
valores )

• Reloj
o Todas las señales que cruzan dominios de reloj deberán muestrearse antes y
después de cruzar dominios (previene estados meta-estables).
o Se deberán usar la mínima cantidad de dominios de reloj posibles.
o No usar señales de reloj o Reset como Enable o dato. No usar un dato como
reloj o Reset. (los resultados durante simulaciones pueden diferir del circuito
sintetizado y causar problemas de temporizado)

©2003 Guillermo Güichal 159


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

o Las señales de reloj deberán estar conectadas a un "pad" global de reloj en la


FPGA o CPLD. (estos pines tienen canales de distribución especiales con baja
diferencia de retardo en la distribución, o bajo “skew”)

• Buses
o Comenzar los buses en el bit 0. (Algunas herramientas no aceptan buses que
no comienzan en 0)
o Usar (MSB downto LSB) para todos los buses. (para evitar interpretaciones
diferentes y provocar malos conexionados)

• Recomendaciones para Síntesis


o Usar solo diseños sincrónicos. (evita problemas durante la síntesis, de
temporizado y en las simulaciones)
o Tratar de no utilizar Flip-Flops con flanco de reloj descendente (dificulta la
verificación y puede crear problemas durante la síntesis)
o No usar latches. (crea problemas de síntesis y de verificación de tiempos)
o Usar procesos con lista de sensibilidad a las señales de Reset y Reloj
solamente con el siguiente formato

PROCESS (Clock, Reset)


BEGIN
IF (Reset = '1') THEN
...
ELSIF (Clock'event AND Clock = '1') THEN
...
END IF;
END IF;
END PROCESS;

o Para lógica sincrónica con “enable”, tratar de definirla en un proceso solo con
el siguiente formato

PROCESS (Clock, Reset)


BEGIN
IF (Reset = '1') THEN
intOutSignal <= '0';
ELSIF (Clock'event AND Clock = '1') THEN
IF (CE = '1') THEN -- Señal de enable
intOutSignal <= '1';
END IF;
END IF;
END PROCESS;

(así las herramientas de síntesis utilizarán así la señal de enable interna de los
bloques lógicos de la FPGA y no generarán lógica externa)
o No utilizar largas cadenas de if.. else sino que utilizar una instrucción
case. (esto evita que se genere lógica de prioridad grande, lenta e
innecesaria)

©2003 Guillermo Güichal 160


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

o En un proceso combinacional incluir todas las señales en la lista de


sensibilidad. (evita que se generen latches no deseados)
o En máquinas de estado, usar dos procesos separados. Uno para la asignación
sincrónica de los estados y uno asincrónico para las salidas. (Ayuda a entender
el código y predecir el tamaño de la lógica combinacional)

• Recomendaciones Generales de Diseño


o No usar buffers de tres estados internamente en los diseños.
o No usar elementos de retardo.
o Todas las señales de interfase externa deberán tener registros

• Bancos de Prueba (testbenches) y Depuración


o Tratar de crear el banco de pruebas en dos partes. Uno para generación y
verificación de datos y otro para la generación del temporizado de las señales.
(Esto facilita la verificación de los datos por un lado y el temporizado por
otro. Además facilita la modificación del protocolo de comunicación o
“handshaking” con el módulo a probar).
o Definir los tiempos para los ciclos de comunicación con el módulo a probar
como constantes que pueden ser modificadas fácilmente.

©2003 Guillermo Güichal 161


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

11 SoCs, Cores y Propiedad Intelectual


11.1 Introducción
Que es un SoC, SoPC. Que es un "core". Papel que juegan en el rápido desarrollo de un
SoC y "time to market" de un producto (tiempos hace unos años: 2 años, ahora 6-8 meses
para tener un chip). Cores para FPGAs, cada vez mas los proveen los fabricantes (no solo
chips). Modelo de negocios basado en proveer cores y servicios de integración de los
cores.

11.2 Presentación de un Core


TBD. Como se debe presentar un Core: Documentación, interfaces, modelos, bancos de
prueba, etc. Hay una nota interesante en EETimes o FPGAJournal que guardé sobre estos
temas. Buscar en carpeta Research

11.3 Diseño para Verificación (Design For Test)


Puntos intermedios para poder evaluar funcionamiento, etc.

11.4 Reutilización de Propiedad Intelectual


Diseñar bien los cores para hacerlos reutilizables.

©2003 Guillermo Güichal 162


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

12 Notas Sobre Síntesis con FPGAs


12.1 Introducción
Introducción al proceso de síntesis. RTL a . Alto nivel (comportamiento) a físico.
Physical Synthesis.

12.2 Diseño y Optimización Para Síntesis


De la nota de aplicación.: Aunque muchas herramientas pueden optimizar el código, la
implementación de un circuito en una FPGA muchas veces depende del estilo usado por
el diseñador en la descripción del hardware.

12.3 Formato Edif

12.4 Estructuras Recomendadas para Diseños Sintetizables


Los procesos YA ESTAN EN LA PRIMERA (3) SECCION¿? Nombrarlos, hacer
referencias y presentar cosas nuevas.

12.4.1 Estructuras de Decisión Jerárquicas y Concurrentes (IF vs. CASE)


Ver nota de aplicación

12.4.2 Procesos sincrónicos

12.4.3 etc.

12.4.4 etc.

12.4.5 etc.

12.5 Ejemplos de estructuras sintetizadas

• Multiplexores
-- with (Seleccion_IN & Datos3_IN(0)) select
with Seleccion_IN select
Salida1_OUT <= Datos1_IN when "00",
Datos2_IN when "01",
"010101" when others;
-- "XXXXXX" when others;

©2003 Guillermo Güichal 163


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

Ver diferencias cuando se asigna “0000” o “XXX”

• Las herramientas infieren decodificadores para with select, when else, process if, -
else if y case
• Que pasa con if (if else) elsif…
• Máquina de estados. Mostrar Flip-Flops, quizás con diferentes “encoding”

©2003 Guillermo Güichal 164


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

13 Notas sobre Verificación


13.1 Introducción
Qué es verificación, simulación. Filosofías de prueba. Herramientas para verificar. Etc.,
etc.

©2003 Guillermo Güichal 165


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

14 Uso de las Herramientas


14.1 Manejo Básico de Xilinx Project Manager

14.2 Manejo Básico de Altera Quartus II

14.3 Manejo Básico de Actel Libero (o la que sea gratuita)

©2003 Guillermo Güichal 166


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

14.4 Manejo Básico de ModelSim

Nota Importante de Instalación

Para poder instalar y ejecutar Xilinx Project Navigator y Modelsim la PC debe tener
instalados el sistema operativo Windows 2000 o Windows XP

Se recomienda seguir el proceso dado en el ISE QuickStart para entender el proceso de


diseño y simulación completo

En Xilinx Project Navigator

• Para poder invocar a ModelSim desde Project Navigator debe estar bien definido
el “path” al ejecutable. Para el ModelSim versión XE gratuito es
Edit/Preferences/Partner Tools/ C:\Modeltech_xe-starter\win32xoem
o el path adecuado incluyendo el directorio win32xoem

• Para crear un banco de pruebas


1. Project/New Source/Testbench Waveform (para diagramas de forma de
onda) o
Project/New Source/VHDL Testbench (para banco de prueba en VHDL)
2. Ponerle un nombre y presionar OK
3. Seleccionar el módulo al que se desea asociar (que módulo va a probar)
4. Editar el testbench o formas de onda como se desee y grabarlo.
5. Seleccionar el archivo del banco de pruebas (*.tbw o *.vhd)

• Para enviar un proyecto a ModelSim y simularlo


6. Seleccionar el testbench o archivo de forma de onda que se desea simular
7. En la ventana “Processes for Current Source” seleccionar ModelSim
Simulator
8. Hacer doble clock en la opción “Simulate Behavioral Testbench” para
abrir el proyecto y su banco de pruebas en ModelSim
9. Si el test es un archivo de forma de onda se ver el testbench en VHDL
usando “View Behavioral Testbench”

Menús de ModelSim

• Para ver las formas de onda ir al menú


View/Wave

• Para ver la estructura del diseño cargado en ModelSim


View/Structure

• Para agregar señales a la ventana ver las formas de onda ir al menú

©2003 Guillermo Güichal 167


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

1. View/Signals. Esto abrirá la ventana de señales


2. Seleccionar el componente deseado en la jerarquía de la ventana
principal o en la ventana “Structure”
3. De la ventana de señales, arrastrar la/las señal deseada/s a la ventana
“Wave” (forma de onda)

Comandos de línea

Tarea Comando Ejemplo/Comentario


Recomenzar simulación restart –all Apretar “Restart” en la ventana que
aparece al apretar Enter
Correr simulación run TIEMPO run 1000 ns
run 1 ms
Ayuda sobre comandos help commands Da una lista de los comandos
help run disponibles o ayuda sobre un
comando específico

Salir del programa quit Presionar YES cuando pregunta si


quiere salir

Menús de la ventana de forma de onda (waveform)

• Para ver solo los nombres de las señales (sin path) poner “1” en la casilla:
Tools/Windows Preferences/ Display Signal Path [] # of elements

Para guardar/abrir una configuración de formas de onda


(Los archivos tienen una extensión “.do”)
File/Load Format o Save Format

• Para insertar una línea divisoria entre grupos de señales


Botón derecho (o menú Insert) / Divider

• Para guardar/abrir una simulación


File/Save Dataset o Open Dataset

• Para hacer zoom en la ventana de señales


Lupa negra: muestra toda la simulación
Lupa + y –: hacen zoom
Cuadraditos con flecha hacia abajo y a la derecha: seleccionan un área

©2003 Guillermo Güichal 168


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

15 Referencias
15.1 Dispositivos Lógicos Programables
Bibliografía
• Spartan IIe Device Family, Hoja de datos de Xilinx DS077, www.xilinx.com, 2002.
• Virtex II Pro Data Sheet, Hoja de datos de Xilinx DS083, www.xilinx.com, 2002
• MAX 7000 Programmable Device Family, Hoja de datos de Altera DS-MAX7000-6.5,
www.altera.com.
• Stratix FPGA Family Data Sheet, Hoja de datos de Altera DS-STXFAMLY-3.0,
www.altera.com, 2002
• Excalibur Device Overview Data Sheet, Hoja de datos de Altera DS-EXCARM-2.0,
www.altera.com.
• GAL22V10 Data Sheet, Hoja de datos de Lattice Semiconductors, www.vantis.com,
Junio 2000
• Using Delay Locked Loops in Spartan II Devices, Nota de aplicación de Xilinx XAPP174,
www.xilinx.com, 2000
• Introduction to GAL Devices, Nota de aplicación de Lattice Semiconductors,
www.vantis.com, 2002
• CPLD Package and I/O Matriz, Guía de selección de Altera SA-CPLDMTRX-1.0,
www.altera.com, 2002
• FPGA and CPLD Architectures: A Tutorial, Stephen Brown & Jonathan Rose, IEEE
Design and Test of Computers, 1996.
• Diseño Digital Principios y Prácticas Tercera Edición, John F. Wakerly, Editorial Prentice
Hall, 2001.
• Síntesis y Descripción de Circuitos Digitales Utilizando VHDL, IEC Francisco Javier
Torres Valle, Universidad Autónoma de Guadalajara, 2001.
• Low-cost programmable logic: How low should you go?, Brian Dipert, EDN, 16/3/2001
• Programmable Logic Device Review. Lattice Introduces FPGA, Murray Disman,
www.chipcenter.com, 2002.
• The Effect of LUT and Cluster Size on Deep-Submicron FPGA Performance and Density,
Elias Ahmed a& Jonathan Rose, IEEE Transactions on VLSI Systems, March 2004
• FPGA Performance vs Cell Granularity, Jack Kouloheris & Abbas El Gamal, IEEE
Custom Integrated Circuits Conference, 1991

Links de Interés
• Sitio web de Altera: www.altera.com
• Sitio web de Xilinx: www.xilinx.com
• Sitio web de Actel: www.actel.com
• Sitio web de Cypress Semiconductor: www.cypress.com
• Sitio web de Quicklogic: www.quicklogic.com
• Sitio web de Atmel: www.atmel.com

©2003 Guillermo Güichal 169


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

15.2 Diseño Digital con PLDs


Bibliografía
• Artículo de Embedded Systems Programming: "The Universal Design Methodology", Bob
Zeidman, Nov 4, 2003
• Artículo de Embedded Systems Programming: "Tools are not Enough", Lindsey Vereen,
Enero 27, 2004
• "Algorithmic C Synthesis Optimizes ESL Design Flows", XCell Journal Fall 2004, Shawn
McCloud, Mentor Graphic Corporation

Links de Interés
• What is Behavioral Synthesis? http://www.forteds.com/pub/bd/whatisbd.asp

15.3 VHDL
Bibliografía

• The Designer’s Guide to VHDL 2nd Edition, Peter J. Ashenden, Editorial Morgan Kaufman,
2002
• Diseño Digital Principios y Prácticas Tercera Edición, John F. Wakerly, Editorial Prentice
Hall, 2001
• Synthesis and Simulation Design Guide, Xilinx
• Development System Reference Guide ISE 5 , Xilinx
• The VHDL Golden Reference Guide version 1.1, Doulos, 1995
• In Search of the Origins of VHDL’s Delta Delays, Sumit Gosh, Proceedings of the IEEE
International Symposium on Quality Electronic Design, 2002.
• Código VHDL de los paquetes.de lógica estándar IEEE: std_logic_1164.vhd,
std_logic_arith.vhd, std_logic_signed.vhd y std_logic_unsigned.vhd.
• Synthesis and Simulation Design Guide, Xilinx
• Libraries Guide, Xilinx
• Rapid Prototyping of Digital Systems, James O. Hamlen Michael D. Furman, Kluwer
Academic Publishers, 2000
• The VHDL Golden Reference Guide version 1.1, Doulos, 1995
• VHDL Style Guidelines for Performance, Model Technology, Oct 1999.

Links de Interés

• www.vol.webnexus.com Curso de introducción al lenguaje Verilog (en inglés)


• www.eda.ei.tum.de/forschung/vhdl/ Lista de recursos sobre VHDL
• Buscando en Google (www.google.com) las palabras clave “VHDL” o “VHDL
tutorial” se hallarán cientos de sitios de interés.
• Sitio de vhdl.org: www.vhdl.org
• Preguntas frecuentes (FAQ) sobre VHDL: vhdl.org/vi/comp.lang.vhdl
• Tutorial de VHDL de Jan Van der Spiegel en University of Pennsylvania
http://www.seas.upenn.edu/~ee201/vhdl/vhdl_primer.html

©2003 Guillermo Güichal 170


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

15.4 Buenas Prácticas de Diseño


Bibliografía

• Code Complete, Steve McConell, Microsoft Press, 2002.


• ESD Coding Standards Rev 1.0, Embedded Systems Design, Inc., 2001
• ESD VHDL Coding Guidelines Rev 1.0, Embedded Systems Design, Inc., 2001

15.5 Síntesis
Bibliografía
• Xilinx Synthesis Technology (XST) User Guide, Xilinx

Links de Interés (síntesis)


• http://www.vhdl.org/vi/vhdlsynth/vhdlsynth.html

©2003 Guillermo Güichal 171


Diseño digital utilizando FPGAs UTN, Facultad Regional Bahía Blanca

16 Ejemplos

Los ejemplos se describen en este apéndice pero el código está en un CD o archivos


adjuntos

16.1 Ejemplos de Lógica Combinacional


16.2
16.3 Ejemplos de Lógica Secuencial

16.4 Divisor Reloj

16.5 Control display 7 segmentos

16.6 ... otros ejemplos de laboratorios hechos en clase...

16.6.1 Interfase Mouse

16.6.2 Controlador VGA

16.7 Ejemplo Completo: UART

16.8 etc, etc

©2003 Guillermo Güichal 172

Vous aimerez peut-être aussi