Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
ndice general
1
Programacin en VHDL
1.1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Programacin en VHDL/Introduccin
2.1
Descripcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.2
Historia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3
Otras alternativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.1
ABEL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.2
AHDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.3
Verilog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.3.4
Otros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tipos de descripcin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4.1
Descripcin de comportamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4.2
2.4.3
Descripcin estructural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2.4
ndice de contenidos
3.1
Comentarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.2
Identicadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3
Nmeros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1
Bases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.1
Tipos escalares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.2
Tipos compuestos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.3
Subtipos de datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4.4
Conversin de tipos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.1
Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.2
Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.5.3
Seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3.4
3.5
ii
NDICE GENERAL
3.6
3.7
Atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
3.6.1
Denicin de atributos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
Programacin en VHDL/Entidad
12
4.1
Declaracin de entidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
4.1.1
13
Programacin en VHDL/Arquitectura
14
5.1
15
5.1.1
Sentencias Concurrentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
Descripcin de comportamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5.2.1
PROCESS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5.2.2
Variables y Seales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
5.2.3
Sentencias secuenciales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17
Descripcin estructural . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
5.3.1
Denicin de componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
5.3.2
Referencia de componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
5.2
5.3
20
Subprogramas
21
7.1
21
7.2
Llamadas a subprogramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
7.3
Sobrecarga de operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
Paquetes
24
8.1
24
Denicin de paquetes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Libreras
25
9.1
25
Librera ieee . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
10.2 Ficheros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
27
28
28
29
29
NDICE GENERAL
iii
30
11.3 Noticaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
30
30
31
31
31
12 Programacin en VHDL/Ejemplos
33
13 Programacin en VHDL/Ejemplos/ALU
34
14 Programacin en VHDL/Ejemplos/Biestable-Latch
35
15 Programacin en VHDL/Ejemplos/Contador
36
16 Programacin en VHDL/Ejemplos/Multiplexor
37
38
39
19 Programacin en VHDL/Ejemplos/Sumador
40
41
19.1.1 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
19.1.2 Images . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
41
Captulo 1
Programacin en VHDL
Programacin en VHDL
Puerta triestado
Multiplexor
Sumador
Contador
Biestable-Latch
Mquinas de estados
ALU
Apndices
1. Sntesis
2. Instalacin y uso de GHDL
Bibliografa
1
Captulo 2
Programacin en VHDL/Introduccin
2.1 Descripcin
VHDL signica VHSIC Hardware Description Language, y a su vez VHSIC signica Very High Speed Integrated Circuit.
Se trata de un lenguaje de descripcin de hardware, esto signica que mediante l se puede describir la forma de comportarse de un circuito electrnico. El comportamiento puede ser llevado a algn dispositivo que dispondr de sus propios
componentes con los que lograr ese comportamiento deseado. La forma de comportarse es independiente del hardware
donde se implementar.
El VHDL es un estndar llamado IEEE 1076-1993. Sus ventajas son:
Una disponibilidad pblica
Independencia de dispositivos y fabricantes
Reutilizacin
Diseo jerrquico
Un proyecto de VHDL puede contener muchos cheros. El cdigo VHDL usualmente se encuentra en los cheros con
extensin *.vhd. La estructura tpica de uno de estos cheros es:
Llamadas a libreras Entidad Arquitectura(s)
2.2 Historia
A mediados de los aos setenta se produce una fuerte evolucin en los procesos de fabricacin de los circuitos integrados,
y junto a las tecnologas bipolares, surge la tecnologa MOS (metal oxide semiconductor ), principalmente la NMOS, promoviendo el desarrollo de circuitos digitales hasta la primera mitad de los aos ochenta. En aquellas pocas, el esfuerzo
de diseo se concentraba en los niveles elctricos para establecer caractersticas e interconexiones entre los componentes
bsicos a nivel de transistor. El proceso de diseo era altamente manual y tan solo se empleaban herramientas como el
PSPICE para simular esquemas elctricos con modelos previamente personalizados a las distintas tecnologas. A medida
que pasaban los aos, los procesos tecnolgicos se hacan ms y ms complejos. Los problemas de integracin iban en
aumento y los diseos eran cada vez ms difciles de depurar y de dar mantenimiento. Inicialmente los circuitos MSI
(Medium Scale Integration ) y LSI (Low Scale Integration ) se disearon mediante la realizacin de prototipos basados
en mdulos ms sencillos. Cada uno de estos mdulos estaba formado por puertas ya probadas, este mtodo poco a poco,
iba quedndose obsoleto. En ese momento (nales de los aos setenta) se constata el enorme desfase que existe entre
tecnologa y diseo. La considerable complejidad de los chips que se pueden fabricar, implica unos riesgos y costes de
diseo desmesurados e imposibles de asumir por las empresas. Es entonces, cuando diversos grupos de investigadores
2
empiezan a crear y desarrollar los llamados lenguajes de descripcin de hardware cada uno con sus peculiaridades.
Empresas tales como IBM con su IDL, el TI - HDL de Texas Instruments, ZEUS de General Electric, etc., as como los
primeros prototipos empleados en las universidades, empezaron a desarrollarse buscando una solucin a los problemas
que presentaba el diseo de los sistemas complejos. Sin embargo, estos lenguajes nunca alcanzaron el nivel de difusin
y consolidacin necesarios por motivos distintos. Unos, los industriales, por ser propiedad de la empresa permanecieron
encerrados en ellas y no estuvieron disponibles par su estandarizacin y mayor difusin, los otros, los universitarios, perecieron por no disponer de soporte ni mantenimiento adecuado. Alrededor de 1981 el Departamento de Defensa de los
Estados Unidos desarrolla un proyecto llamado VHSIC (Very High Speed Integrated Circuit ) su objetivo era rentabilizar las inversiones en hardware haciendo ms sencillo su mantenimiento. Se pretenda con ello resolver el problema de
modicar el hardware diseado en un proyecto para utilizarlo en otro, lo que no era posible hasta entonces porque no
exista una herramienta adecuada que armonizase y normalizase dicha tarea, era el momento de los HDLs
VHDL
En 1983, IBM, Intermetrics y Texas Instruments empezaron a trabajar en el desarrollo de un lenguaje de diseo que
permitiera la estandarizacin, facilitando con ello, el mantenimiento de los diseos y la depuracin de los algoritmos, para
ello el IEEE propuso su estndar en 1984. Tras varias versiones llevadas a cabo con la colaboracin de la industria y de las
universidades, que constituyeron a posteriori etapas intermedias en el desarrollo del lenguaje, el IEEE public en diciembre
de 1987 el estndar IEEE std 1076-1987 que constituy el punto rme de partida de lo que despus de cinco aos sera
raticado como VHDL. Esta doble inuencia, tanto de la empresa como de la universidad, hizo que el estndar asumido
fuera un compromiso intermedio entre los lenguajes que ya haban desarrollado previamente los fabricantes, de manera
que ste qued como ensamblado y por consiguiente un tanto limitado en su facilidad de utilizacin haciendo dicultosa
su total comprensin. Este hecho se ha visto incluso ahondado en su revisin de 1993. Pero esta deciencia se ve altamente
recompensada por la disponibilidad pblica, y la seguridad que le otorga el verse revisada y sometida a mantenimiento
por el IEEE. La independencia en la metodologa de diseo, su capacidad descriptiva en mltiples dominios y niveles de
abstraccin, su versatilidad para la descripcin de sistemas complejos, su posibilidad de reutilizacin y en denitiva la
independencia de que goza con respecto de los fabricantes, han hecho que VHDL se convierta con el paso del tiempo en
el lenguaje de descripcin de hardware por excelencia...
ABEL
Abreviatura de Advanced Boolean Expression Language. ABEL permite describir diseos mediante tablas de verdad o
ecuaciones lgicas. Tambin permite la programacin secuencial con mquinas de estados.
2.3.2
AHDL
Abreviatura de Altera Hardware Description Language (Lenguaje de Descripcin de Hardware de Altera). Este lenguaje
hardware es propietario de Altera Corporation para la programacin de CPLDs y FPGAs. Destacar que este lenguaje
tiene una sintaxis similar a C, pero su funcionalidad es parecida a la del VHDL.
2.3.3
Verilog
Es la gran alternativa al VHDL. Tuvo gran aceptacin por parte de los ingenieros, puesto que la sintaxis de este lenguaje
es muy parecida a la del lenguaje de programacin C.
2.3.4
Otros
La ltima tendencia en los lenguajes de descripcin de hardware es parecerse cada vez ms a los lenguajes informticos ms habituales, como C o C++. El objetivo de estos lenguajes es que la descripcin de un algoritmo sea nica,
2.4.1
Descripcin de comportamiento
Una descripcin de comportamiento de un multiplexor de dos entradas, una salida y una seal de seleccin sera: la salida
ser igual a la primera entrada si la seal de control est desactivada y la salida ser la segunda entrada si la seal de
control est activada.
En VHDL la arquitectura de este multiplexor para la entidad llamada mux sera:
ARCHITECTURE mux_comportamiento OF mux IS BEGIN PROCESS(entrada1, entrada2, control) BEGIN IF(control
= '0') THEN salida <= entrada1; ELSE salida <= entrada2; END IF; END PROCESS; END mux_comportamiento;
2.4.2
En una descripcin de ujo de datos del mismo multiplexor la salida sera la ecuacin lgica: s=(entrada1 AND NOT
control) OR (entrada2 AND control)
En VHDL la arquitectura sera:
ARCHITECTURE mux_rtl OF mux IS SIGNAL int1, int2, int3 : BIT; BEGIN int1 <= NOT control; int2 <= entrada1
AND int1; int3 <= entrada2 AND control; salida <= int2 OR int3; END mux_rtl;
Esta descripcin hay varias instrucciones concurrentes, por lo que son ejecutadas cada vez que una seal interviene en
su asignacin. Realmente, se trata casi de una descripcin estructural, puesto que se estn describiendo seales y sus
componentes. Aunque tambin son asignaciones a seales y no una lista de componentes y sus conexiones. En el siguiente
ejemplo se muestra una descripcin de ujo de datos pura.
ARCHITECTURE mux_rtl OF mux IS BEGIN salida <= entrada1 WHEN control = '0' ELSE entrada2; END mux_rtl;
2.4.3
Descripcin estructural
Una descripcin estructural consistira en decir que el circuito tiene una puerta inversora U1, dos puertas AND de dos
entradas U2 y U3 y una puerta lgica OR de dos entradas U4, adems tambin describe las conexiones entre estas puertas,
un ejemplo sera: la entrada de U1 es la seal de control, la salida de U1 se conecta a la segunda entrada de U2, la primera
entrada de U2 es entrada1, etc.
El cdigo VHDL sera:
ARCHITECTURE mux_estructural OF mux IS SIGNALl int1, int2,int3:bit; BEGIN U1: inversor PORT MAP(control,
int1); U2: and_2_entradas PORT MAP(entrada1, int1, int2); U3: and_2_entradas PORT MAP(entrada2, control, int3);
U4: or_2_entradas PORT MAP(int2, int3, salida); END mux_estructural;
En el cdigo anterior se deberan haber denido previamente las puertas inversor, and_2_entradas y or_2_entradas.
Captulo 3
3.1 Comentarios
Los comentarios van precedidos de dos guiones. En una lnea se ignorar todo aquello que vaya despus de dos guiones
seguidos. Ejemplo:
-- Esto es un comentario
3.2 Identicadores
Son cualquier cadena de caracteres que sirven para identicar variables, seales, procesos, etc. Puede ser cualquier nombre
compuesto por letras (aux) o nmeros y letras (aux1, aux2, aux3, ...), incluyendo el smbolo de subrayado "_. Las
maysculas y minsculas son consideradas iguales, por lo tanto los identicadores TMP y tmp representan el mismo
elemento. No es posible crear un identicador que coincida con alguna palabra reservada del lenguaje.
3.3 Nmeros
Cualquier nmero se representa en base 10. Aunque es posible poner los nmeros en otras bases utilizando diferentes
smbolos, como se muestra en la siguiente seccin.
3.3.1
Bases
X"F hexadecimal
Para enteros y reales:
2#1100# binario
12 decimal
16#C# hexadecimal
l
3.4.1
Tipos escalares
Fsicos: Se trata de datos que corresponden con magnitudes fsicas, que tienen un valor y unas unidades.
TYPE longitud IS RANGE 0 TO 1.0e9 UNITS um; mm=1000 um; m=1000 mm; in=25.4 mm; END UNITS;
Reales o coma otante: Se denen igual que los enteros con la diferencia que los lmites son nmeros reales.
TYPE nivel IS RANGE 0.0 TO 5.0
Enumerados: Son datos que puede tomar siempre que se encuentre en una lista o conjunto nito. Es idntico a las
enumeraciones en C (enum).
TYPE color IS (ROJO, VERDE, AMARILLO);
3.4.2
Tipos compuestos
Son tipos de datos compuestos por los que se han visto anteriormente.
Matrices: Se trata de un conjunto de elementos del mismo tipo, accesibles mediante un ndice. Los hay de dos tipos:
monodimensionales o multidimensionales.
TYPE word IS ARRAY (31 DOWNTO 0) OF bit; TYPE tabla IS ARRAY (1 TO 4, 1 TO 4) OF real;
En este punto es necesario explicar la palabra reservada OTHERS, donde es posible asignar un determinado valor a todos
los elementos de la matriz.
word <= (OTHERS => '0'); -- Asigna '0' en todas las posiciones
Las palabras reservadas TO y DOWNTO sirven para indicar los ndices de una matriz. El primero indica un rango
ascendente (de x a y), mientras que el segundo es descendente (desde x hasta y).
-- word1 y word2 son elementos idnticos TYPE word1 IS ARRAY (31 DOWNTO 0) OF bit; TYPE word2 IS ARRAY
(0 TO 31) OF bit;
Dependiendo de la opcin elegida el bit ms signicativo corresponder al primer bit (0) o al ltimo (31). Tambin es
posible obtener un trozo de una matriz para poder realizar operaciones con ella.
TYPE word IS ARRAY (31 DOWNTO 0) OF bit; TYPE subword IS ARRAY (7 DOWNTO 0) OF bit; ... subword <=
word(31 DOWNTO 24);
Adems, es posible asignar a una matriz una lista separada por comas, de forma que el primer elemento de la lista
corresponde al primero de la matriz.
semaforo <= (apagado, apagado, encendido); luces <= (apagado, verde, azul, ..., amarillo);
3.4.3
Subtipos de datos
En VHDL se pueden denir subtipos, los cuales corresponden a tipos ya existentes. Se pueden diferenciar dos tipos
dependiendo de las restricciones que se apliquen.
Restricciones de un tipo escalar a un rango:
SUBTYPE indice IS integer RANGE 0 TO 7; SUBTYPE digitos IS character RANGE '0' TO '9';
3.4.4
Conversin de tipos
En ocasiones puede ser necesario convertir unos tipos a otros, esta operacin es conocida como casting. Algunas de las
conversiones son automticas, como puede ser el paso de entero a real, otras conversiones deben realizarse de forma
explcita, indicando el nombre del tipo al que se quiere pasar seguido del valor entre parntesis.
real(15); integer(3.5);
En muchos diseos es necesario realizar conversiones entre bits y enteros. A continuacin se muestran varias funciones
de conversin entre ambos tipos.
conv_integer(std_logic_vector); -- Conversin de vector a entero conv_std_logic_vector(integer, numero_bits); -- Conversin de entero a vector de numero_bits de tamao
3.5.1
Constantes
Es un elemento que se inicializa con un valor determinado, el cual no puede ser modicado, es decir siempre conserva el
mismo valor. Esto se realiza con la palabra reservada CONSTANT.
CONSTANT e : real := 2.71828; CONSTANT retraso : time := 10 ns;
Tambin es posible no asociar un valor a una constante, siempre que el valor sea declarado en otro sitio.
CONSTANT max : natural;
3.5.2
Variables
Es lo mismo que una constante, pero con la diferencia que puede ser modicada en cualquier instante, aunque tambin es
posible inicializarlas. La palabra reservada VARIABLE es la que permite declarar variables.
VARIABLE contador : natural := 0; VARIABLE aux : bit_vector(31 DOWNTO 0);
Es posible, dado un elemento cambiarle el nombre o ponerle nombre a una parte mediante la palabra reservada ALIAS.
VARIABLE instruccion : bit_vector(31 DOWNTO 0); ALIAS cod_op : bit_vector(7 DOWNTO 0) IS instruccion(31
DOWNTO 24);
3.5.3
Seales
Las seales se declaran con la palabra reservada SIGNAL, a diferencia con las anteriores este tipo de elementos pueden
ser de varios tipos: normal, register o bus. Es posible asignarles un valor inicial.
10
3.6 Atributos
Los elementos como seales y variables pueden tener atributos, stos se indican a continuacin del nombre, separados
con una comilla simple "'" y pueden incluir informacin adicional de algunos objetos desarrollados en VHDL, que servirn
a las herramientas de diseo para obtener informacin a la hora de realizar una sntesis.
Existen muchos atributos, como LEFT, RIGHT, LOW, HIGH, RANGE, LENGTH... Pero el atributo ms usado es
EVENT, que indica si una seal ha cambiado de valor. Por ejemplo la siguiente sentencia captura un anco de subida de
una seal (clk).
.... if clk'event and clk = '1' then ....
3.6.1
Denicin de atributos
Un atributo denido por el diseador siempre devolver un valor constante. En primer lugar se debe declarar el atributo,
mediante la palabra reservada ATTRIBUTE, indicando el tipo de elemento que se devuelve, seguidos el valor que se
retornar. La sintaxs para denir atributos sera la siguiente.
ATTRIBUTE nombre : tipo ATTRIBUTE nombre OF id_elemento : clase IS valor
Donde nombre es el identicador del atributo, id_elemento corresponde al identicador de un elemento del lenguaje denido previamente (seal, variable, etc.), la clase es el tipo de elemento al que se le va aadir dicho atributo, es decir si es
seal, constante, etc. y el valor ser lo que devuelva al preguntar por dicho atributo. Un ejemplo de todo esto puede ser
el siguiente.
SIGNAL control : std_logic; ATTRIBUTE min : integer; ATTRIBUTE min OF control : SIGNAL IS 4; .... IF control'min
> 20 THEN
3.7 Operadores
Los operadores que proporciona el lenguaje son:
Lgicos: Actan sobre los tipos bit, bit_vector y boolean. En el caso de utilizar este tipo de operadores en un vector,
la operacin se realizar bit a bit.
Operadores: AND, OR, NAND, NOR, XOR, XNOR y NOT.
Aritmticos:
+ (suma o signo positivo): Sirve para indicar una suma entre dos nmeros. Tambin puede actuar como
smbolo si se sita delante de una expresin.
- (resta o signo negativo): Sirve para indicar la resta entre dos nmeros. Si va delante de una expresin modica
el signo de la expresin.
* (multiplicacin): Multiplica dos nmeros de cualquier tipo.
/ (divisin): Divide dos nmeros de cualquier tipo.
3.7. OPERADORES
11
** (exponencial): Eleva un nmero a una potencia. El nmero de la izquierda puede ser entero y real, pero el
de la derecha slo puede ser entero. Ejemplo: 4**2 sera 4.
ABS() (valor absoluto): Devuelve el valor absoluto de su argumento.
MOD (mdulo): Calcula el mdulo de dos nmeros.
REM (resto): Calcula el resto de la divisin.
Relacionales: Siempre devuelven un valor booleano (true o false).
==, /= (igualdad): El primero devuelve verdadero si los operando son iguales y falso en caso contrario. El
segundo indica desigualdad, funcionando al revs que el anterior.
>, >=, <, <= (menor mayor): Poseen el signicado habitual (mayor que, mayor o igual que, menor que,
menor o igual que, respectivamente). La diferencia con los anteriores reside en su uso, en este caso los tipos
de datos que pueden manejar son siempre de tipo escalar o matrices.
Desplazamientos: (incluidas en la revisin de 1993)
SLL (Shift Left Logic) y SRL (Shift Right Logic), desplazamiento lgico a la izquierda y desplazamiento
lgico a la derecha, respectivamente, rellenando de ceros los huecos.
SLA (Shift Left Arithmetic) y SRA (Shift Right Arithmetic), desplazamiento aritmtico a la izquierda y
derecha respectivamente.
ROL (ROtate Left) y ROR (ROtate Right), rotacin a la izquierda y a la derecha respectivamente. En este
caso los huecos son ocupados por los bits que van quedando fuera.
A continuacin se muestran ejemplos sobre los operadores de desplazamiento:
-- Inicialmente a vale 1100 1101 a sll 4 -- El resultado es 1101 0000 a sla 4 -- El resultado es 1101 1111 (extensin del
ltimo bit) a srl 4 -- El resultado es 0000 1100 a sra 4 -- El resultado es 1111 1100 a rol 4 -- El resultado es 1101 1100
(los primeros 4 bits pasan a la ltima posicin) a ror 4 -- El resultado es 1101 1100
Otros:
& (concatenacin): Concatena vectores de manera que la dimensin de la matriz resultante es la suma de las
dimensiones de las matrices con las que se opera.
Hay que decir que no todos los operadores pueden funcionar sobre todos los tipos de datos. Tambin hay operadores que
en determinadas circunstancias no pueden ser utilizados, por ejemplo al hacer cdigo sintetizable no es recomendable usar
multiplicadores (excepto si uno de los operadores es potencia de dos, puesto que se tratara de un simple desplazamiento
de bits).
El orden de preferencia, de mayor a menor es:
1. **, ABS, NOT
2. *, /, MOD, REM
3. +, - (signo)
4. +, -, & (operaciones)
5. =, /=, <, <=, >, >=
6. AND, OR, NAND, NOR, XOR
Captulo 4
Programacin en VHDL/Entidad
Durante los captulos anteriores se ha insistido varias veces en que VHDL sirve para describir hardware. Un circuito
electrnico puede ser parte de otro ms grande, en este caso el primero sera un subcircuito del segundo. Por lo tanto,
un circuito puede estar compuesto por muchos subcircuitos y estos subcircuitos se interconectaran. As aparece una
jerarqua en el diseo. En la parte alta de la jerarqua apareceran los circuitos ms complejos, que estaran compuestos
por subcircuitos y, a su vez, cada uno de estos subcircuitos podra estar compuesto por subcircuitos ms sencillos.
Un ejemplo de jerarqua sera un microprocesador. El circuito ms complejo y el ms alto en la jerarqua sera el propio microprocesador. ste estara compuestos por subcircuitos, por ejemplo el de la unidad de control, el de la unidad
aritmtico-lgica, memorias, registros, etc. Estos subcircuitos estaran conectados por lneas elctricas, pueden ser simples
como un cable o complejas como un bus. Una unidad de control estara compuesta por ms subcircuitos, ms registros,
ms buses, etc.
Cuando se est diseando en un determinado nivel, seguramente se empleen elementos de niveles ms bajos. Para usar
estos elementos de nivel bajo en un nivel ms alto slo se necesita conocer su interfaz, es decir, sus entradas y salidas,
sobre ellas se conectaran los cables o buses que correspondieran.
13
la seal seguido de dos puntos y la direccin del puerto (se ver ms adelante), adems del tipo de seal del que se trata.
Al igual que antes, si existe ms de una seal se nalizar con un punto y coma, exceptuando la ltima seal de la lista.
nombre_seal : direccin tipo;
A continuacin se muestra un ejemplo de una entidad, con una serie de constantes y seales de entrada y salida.
ENTITY mux IS GENERIC( C_AWIDTH : integer := 32; C_DWIDTH : integer := 32 ); PORT( control : IN bit; entrada1 : IN bit; entrada2 : IN bit; salida : OUT bit ); END mux;
En este ejemplo la entidad de llama mux. Su interfaz se compone de las seales control, entrada1 y entrada2 como entradas
de tipo bit y de la seal llamada salida como salida, tambin de tipo bit. Adems, se incluyen dos constantes que servirn
a la parte declarativa para realizar alguna operacin.
En la introduccin se vio como asignar las seales de entradas y salidas mediante la palabra PORT MAP, para el caso
de los genricos se realiza con la palabra reservada GENERIC MAP, esta parte se estudiar con mayor detalle en los
siguientes captulos. Un ejemplo para utilizar el cdigo anterior como un componente sera el siguiente.
mux_1 : ENTITY work.mux GENERIC MAP( C_AWIDTH => C_AWIDTH, C_DWIDTH => C_DWIDTH ) PORT
MAP( control => control, entrada1 => entrada1, entrada2 => entrada2, salida => salida );
Obsrvese que en todo momento se habla de seales y no de variables, para el caso de los puertos.
4.1.1
Las seales representaran la funcin que haran los cables en un diseo hardware tradicional, es decir, sirven para transportar informacin y establecer conexiones. Dentro de una entidad los puertos son considerados como seales, en donde
se pueden diferenciar varios tipos.
IN: Son seales de entrada, las cuales slo se pueden leer, pero no se le pueden asignar ningn valor, es decir, no
se puede modicar el valor que poseen. Por lo tanto, su funcionalidad es similar a las constantes.
OUT: Corresponden a las seales de salida, en este caso su valor puede ser modicado, pero en este caso no pueden
leerse, es decir no pueden ser utilizadas como argumentos en la asignacin de cualquier elemento.
INOUT: Este tipo es una mezcla de los dos anteriores, pueden ser utilizados tanto como de lectura o de escritura.
BUFFER: Es idntico al anterior, con la diferencia de que slo una fuente puede modicar su valor.
Captulo 5
Programacin en VHDL/Arquitectura
Como se ha dicho en el captulo anterior, la arquitectura es lo que dene cmo se comporta un circuito. En el primer
captulo tambin se mostraron varias arquitecturas en las que se describa un multiplexor. La primera lnea de cada una
era
ARCHITECTURE mux_comportamiento OF mux IS ARCHITECTURE mux_rtl OF mux IS ARCHITECTURE mux_estructural
OF mux IS
Los nombres de cada arquitectura son mux_comportamiento, mux_rtl y mux_estructural respectivamente. Todas estn
asociadas a la entidad mux. El nombre de la arquitectura se usar para indicar qu arquitectura se debe usar en caso que
haya varias para una misma entidad.
Despus de esta lnea pueden aparecer varias instrucciones para indicar la declaracin de seales, componentes, funciones,
etc.. Estas seales son internas, es decir, a ellas no se puede acceder desde la entidad, por los que los circuitos de nivel
superior no podran acceder a ellas. En un smil con un microprocesador, estas seales podran ser las lneas que comunican
la unidad central con la ALU, a las que no se puede acceder directamente desde el exterior del microprocesador. Obsrvese
que en este caso no se indica si son entradas o salidas, puesto que al ser internas pueden ser ledas o escritas sin ningn
problema. En esta parte de la arquitectura tambin pueden aparecer otros elementos, como pueden ser las constantes. Lo
siguiente es la palabra clave BEGIN, que da paso a la descripcin del circuito, mediante una serie de sentencias. Por lo
tanto, la sintaxis de una arquitectura sera.
ARCHITECTURE nombre OF nombre_entidad IS [declaraciones] BEGIN [sentencias concurrentes] END [ARCHITECTURE] [nombre];
Un ejemplo de una arquitectura podra ser la siguiente.
ARCHITECTURE mux_rtl OF mux IS SIGNAL int1, int2, int3 : BIT; BEGIN int1 <= NOT control; int2 <= entrada1
AND int1; int3 <= entrada2 AND S; salida <= int2 OR int3; END mul_rtl;
La descripcin puede ser de tres tipos:
2. Descripcin de comportamiento
3. Descripcin estructural
14
15
5.1.1
Sentencias Concurrentes
La instruccin bsica de la ejecucin concurrente es la asignacin entre seales a travs del smbolo <=. Para facilitar la
asignacin de las seales VHDL incluye elementos de alto nivel como son instrucciones condicionales, de seleccin, etc,
que se vern a continuacin.
WHEN ... ELSE
Sentencia de seleccin mltiple. En hardware es necesario incluir todas las opciones posibles. En este caso es obligatorio
siempre acabar la expresin con un ELSE.
<seal> <= <asignacin1> WHEN <condicin1> ELSE <asignacin2> WHEN <condicin2> ELSE ... <asignacinN>
WHEN <condicinN> ELSE <asignacinM>;
Un posible ejemplo de este tipo de sentencias podra ser la siguiente.
s <= 00 WHEN a = b ELSE 01 WHEN a > b ELSE 11";
Siempre es obligatorio asignar algo, aunque es posible no realizar accin alguna, para ello se utiliza la palabra reservada
UNAFFECTED. De esta forma se asignar el mismo valor que tena la seal.
s1 <= d1 WHEN control = '1' ELSE UNAFFECTED; s2 <= d2 WHEN control = '1' ELSE s2;
Las dos sentencias anteriores parecen iguales, pero en la segunda se produce una transaccin, aspecto que en la primera
no sucede.
WITH ... SELECT ... WHEN
Es similar a las sentencias CASE o SWITCH de C. La asignacin se hace segn el contenido de un objeto o resultado
de cierta expresin.
WITH <seal1> SELECT <seal2> <= <asignacin1> WHEN <estado_seal1>, <asignacin2> WHEN <estado_seal2>,
... <asignacinN> WHEN OTHERS;
Un ejemplo de esta sentencia es la siguiente.
WITH estado SELECT semaforo <= rojo WHEN 01, verde WHEN 10, amarillo WHEN 11, roto WHEN
OTHERS;
La clusula WHEN OTHERS especica todos los dems valores que no han sido contemplados. Tambin es posible
utilizar la opcin que se contempl en el caso anterior (UNAFFECTED).
16
BLOCK
En ocasiones interesa agrupar un conjunto de sentencias en bloques. Estos bloques permiten dividir el sistema en mdulos,
estos mdulos pueden estar compuestos de otros mdulos. La estructura general es la siguiente.
block_id: BLOCK(expresin de guardia) declaraciones BEGIN sentencias concurrentes END BLOCK block_id;
El nombre del bloque es opcional (block_id), al igual que la expresin de guardia. Un ejemplo de esto podra ser el
siguiente.
latch: BLOCK(clk='1') BEGIN q <= GUARDED d; END BLOCK latch;
5.2.1
PROCESS
Un PROCESS, como se ha dicho antes, es una sentencia concurrente en el sentido de que todos los PROCESS y todas
las dems sentencias concurrentes se ejecutarn sin un orden establecido. No obstante las sentencias que hay dentro del
PROCESS se ejecutan de forma secuencial.
Por lo tanto se puede decir que una estructura secuencial va en el interior de un PROCESS.
La estructura genrica de esta sentencia es:
PROCESS [lista de sensibilidad] [declaracin de variables] BEGIN [sentencias secuenciales] END PROCESS;
La lista de sensibilidad es una serie de seales que, al cambiar de valor, hacen que se ejecute el PROCESS.
Un ejemplo sera:
PROCESS(seal1, seal2) ...
El PROCESS anterior slo se ejecutar cuando seal1 o seal2 cambien de valor.
5.2.2
Variables y Seales
Hay que distinguir las seales y las variables, las seales se declaran entre ARCHITECTURE y su correspondiente
BEGIN mientras que las variables se declaran entre PROCESS y su BEGIN. Dentro de un PROCESS pueden usarse
ambas, pero hay una diferencia importante entre ellas: las seales slo se actualizan al terminar el proceso en el que se
usan, mientras que las variables se actualizan instantneamente, es decir, su valor cambia en el momento de la asignacin.
Unos ejemplos son:
ENTITY ejemplo IS PORT (c: IN std_logic; d: OUT std_logic); END ENTITY; ARCHITECTURE ejemplo_arch OF
ejemplo IS SIGNAL a,b: std_logic; BEGIN PROCESS(c) VARIABLE z: std_logic; BEGIN a<= c and b; --asignacin
de seales: despus de ejecutarse esta lnea a seguir valiendo lo mismo, slo se actualiza al acabar el PROCESS z:= a or
c; --asignacin de variables: en el momento de ejecutarse esta lnea z valdr a or c (el valor que tena a cuando empez el
17
5.2.3
Sentencias secuenciales
CASE
Es parecido al anterior porque tambin ejecuta un bloque de cdigo condicionalmente, pero en esta ocasin se evala una
expresin en vez de una condicin. Se debe recordar que se deben tener en cuenta todos los casos, es decir, incluir como
ltima opcin la sentencia WHEN OTHERS.
CASE <expresin> IS WHEN <valor1> => [sentencias1] WHEN <valor2> => [sentencias2] WHEN <rango de valores>
=> [sentenciasN] WHEN OTHERS => [sentenciasM] END CASE;
Un ejemplo es:
CASE a IS WHEN 0 => B:=0; WHEN 1 to 50 => B:=1; WHEN 99 to 51 => B:=2; WHEN OTHERS => B:=3; END
CASE;
LOOP
LOOP es la forma de hacer bucles en VHDL. Sera el equivalente a un FOR o WHILE de un lenguaje convencional.
Su estructura es:
[etiqueta:] [WHILE <condicin> | FOR <condicin>] LOOP [sentencias] [exit;] [next;] END LOOP [etiqueta];
Un ejemplo de bucles anidados es:
bucle1: LOOP a:=A+1; b:=20; bucle2: LOOP IF b < (a*b) THEN EXIT bucle2; END IF; b:=b+a; END LOOP bucle2;
EXIT bucle1 WHEN a>10; END LOOP bucle1;
Otro ejemplo, este con FOR es:
bucle1: FOR a IN 1 TO 10 LOOP b:=20; bucle2: LOOP IF b<(a*a) THEN EXIT bucle2; END IF; b:=b-a; END LOOP
bucle2; END LOOP bucle1;
Otro ms con WHILE
cuenta := 10; bucle1: WHILE cuenta >= 0 LOOP cuenta := cuenta + 1; b:=20; bucle2: LOOP IF b<(a*a) THEN EXIT
bucle2; END IF; b := b-a; END LOOP bucle2; END LOOP bucle1;
18
NEXT y EXIT
NEXT permite detener la ejecucin actual y seguir con la siguiente.
[id_next:] NEXT [id_bucle] [WHEN condicin];
Como se puede suponer, la sentencia EXIT hace que se salga del bucle superior al que se ejecuta.
[id_exit:] EXIT [id_bucle] [WHEN condicin];
Se puede ver su uso en los ejemplos del apartado anterior.
ASSERT
Se usa para vericar una condicin y, en caso de que proceda, dar un aviso.
La sintxis es:
ASSERT <condicin> [REPORT <expresin>] [SEVERITY <expresin>];
Este comando se estudiar en el subcaptulo de noticaciones, en la seccin de bancos de prueba. Puesto que el uso de
este comando se realiza nicamente en la simulacin de circuitos.
WAIT
La ejecucin de un bloque PROCESS se realiza de forma continuada, como si de un bucle innito se tratara (se ejecutan
todas las sentencias y se vuelven a repetir). Esto no tiene mucho sentido, puesto que continuamente se ejecutara lo mismo
una y otra vez, sera interesante poder parar la ejecucin. Una forma de hacerlo es mediante las listas de sensibilidad, las
cuales se han visto anteriormente, aunque existe otra forma de hacerlo mediante la sentencia WAIT, pero es algo ms
complejo.
WAIT ON lista_sensible UNTIL condicion FOR timeout;
La lista_sensible es un conjunto de seales separadas por comas. La condicin es una sentencia que activar de nuevo la
ejecucin. El timeout es el tiempo durante el cual la ejecucion esta detenida.
No es necesario utilizar las tres opciones, en caso de hacerlo la primera condicin que se cumpla volver a activar la
ejecucin.
WAIT ON pulso; WAIT UNTIL counter = 5; WAIT FOR 10 ns; WAIT ON pulso, sensor UNTIL counter = 5; WAIT
ON pulso UNTIL counter = 5 FOR 10 ns;
Si se utiliza una lista de sensibilidad no es posible utilizar la sentencia WAIT, sin embargo si es posible utilizar varias
sentencias WAIT cuando esta acta como condicin de activacin. Este comando se estudiar en el subcaptulo de retrasos,
en la seccin de bancos de prueba.
5.3.1
19
Denicin de componentes
En VHDL es posible declarar componentes dentro de un diseo mediante la palabra COMPONENT. Un componente se
corresponde con una entidad que ha sido declarada en otro mdulo del diseo, o incluso en alguna biblioteca, la declaracin
de este elemento se realizar en la parte declarativa de la arquitectura del mdulo que se est desarrollando. La sintxis
para declarar un componente es muy parecida a la de una entidad.
COMPONENT nombre [IS] [GENERIC(lista_parametros);] [PORT(lista_de_puertos);] END COMPONENT nombre;
Si se dispone de un compilador de VHDL'93 no ser necesario incluir en los diseo la parte declarativa de los componentes,
es decir se pasara a referenciarlos de forma directa. Un ejemplo de un componente podra ser el siguiente.
COMPONENT mux IS GENERIC( C_AWIDTH : integer; C_DWIDTH : integer ); PORT( control : IN bit; entrada1 :
IN bit; entrada2 : IN bit; salida : OUT bit ); END COMPONENT mux;
5.3.2
Referencia de componentes
La referencia de componentes consiste en copiar en la arquitectura aquel componente que se quiera utilizar, tantas veces
como sea necesario para construir el diseo. Para ello, la sintaxis que presenta la instanciacin de un componente es la
siguiente.
ref_id: [COMPONENT] id_componente | ENTITY id_entidad [(id_arquitectura)] | CONFIGURATION id_conguracin
[GENERIC MAP (parametros)] [PORT MAP (puertos)];
Un ejemplo de referenciacin del componente anterior sera.
mux_1 : COMPONENT mux GENERIC MAP ( C_AWIDTH => C_AWIDTH, C_DWIDTH => C_DWIDTH ) PORT
MAP ( control => ctrl, entrada1 => e1, entrada2 => e2, salida => sal );
Las seales ctrl, e1, e2 y sal deben ser declaradas previamente en la seccin de declaraciones de la arquitectura, estas
seales sirven para poder conectar unos componentes con otros. Tambin deben declararse las variables que se utilizan
en la seccin GENERIC.
Captulo 6
20
Captulo 7
Subprogramas
Como en otros lenguajes de programacin, en VHDL es posible estructurar el cdigo mediante el uso de subprogramas.
Realmente, un subprograma es una funcin o procedimiento que realiza una determinada tarea, aunque existen ciertas
diferencias entre ambas.
Una funcin devuelve un valor y un procedimiento devuelve los valores a travs de los parmetros que le han sido
pasados como argumentos. Por ello, las primeras debern contener la palabra reservada RETURN, mientras que las
segundas no tienen necesidad de disponer dicha sentencia, en caso de tener una sentencia de ese tipo interrumpir
la ejecucin del procedimiento.
A consecuencia de la anterior, en una funcin todos sus parmetros son de entrada, por lo que slo pueden ser
leidos dentro de la misma, por el contrario en un procedimiento los parmetros pueden ser de entrada, de salida o
de entrada y salida (unidireccionales o bidireccionales).
Las funciones se usan en expresiones, sin embargo, los procedimientos se llaman como una sentencia secuencial o
concurrente.
Los procedimientos pueden tener efectos colaterales al poder cambiar seales externas que han sido pasadas como
parmetros, por otro lado las funciones no poseen estos efectos.
Las funciones nunca pueden tener una sentencia WAIT, pero los procedimientos s.
22
CAPTULO 7. SUBPROGRAMAS
IN, OUT e INOUT. Adems, en las funciones el parmetro puede ser CONSTANT o SIGNAL, por defecto es CONSTANT. Por otro lado, en los procedimientos los parmetros de tipo IN son CONSTANT por defecto y VARIABLE
para el resto, aunque tambin es posible utilizar SIGNAL siempre que se declare explcitamente. No se aconseja utilizar
seales como parmetros, por los efectos que pueden tener en la ejecucin de un programa.
Las funciones PURE o puras devuelven el mismo valor para unos parmetros de entrada determinados. Mientras que
una funcin es IMPURE o impura si para los mismos valores de entrada se devuelve distinto valor. Estas ltimas pueden
depender de una variable o seal global. Realmente, estas palabras reservadas hacen de comentario, puesto que una funcin
no se hace impura o pura por indicarlo.
Un ejemplo de una funcin sera el siguiente.
FUNCTION es_uno(din : std_logic_vector(31 downto 0)) RETURN std_logic IS VARIABLE val : std_logic; BEGIN IF
din = X"00000001 THEN val := '1'; ELSE val := '0'; END IF; RETURN val; END es_uno;
Por otro lado, un ejemplo de un procedimiento podra pertenecer a las siguientes lneas.
PROCEDURE es_uno(din : std_logic_vector(31 downto 0) dout : std_logic) IS BEGIN IF din = X"00000001 THEN
dout := '1'; ELSE dout := '0'; END IF; END es_uno;
En la asignacin a la seal de salida se realiza con el operador :=, puesto que no es una seal, es decir que se trata de un
tipo VARIABLE. Si se tratara de una seal se hara con el operador de asignacin <=.
Asociacin explcita: Los parmetros se colocan en cualquier orden. Un ejemplo de la llamada al procedimiento
anterior podra ser la siguiente.
limite(min=>valmin, max=>valmax, conj=>cjt(31 DOWNTO 28));
Parmetros libres: En VHDL es posible dejar parmetros por especicar, de forma que tengan unos valores por
defecto, y en el caso de pasar un valor a dichos argumentos puedan tomar el valor especicado. Un ejemplo de este
tipo de llamadas sera el siguiente.
PROCEDURE lee(longuitud : IN integer := 200) IS BEGIN .... END PROCEDURE; -- Posibles llamadas lee; lee(350);
Como ya se indic al inicio de este captulo, los subprogramas pueden ser llamados desde un entorno secuencial o concurrente. En caso de ser llamado en un entorno concurrente el procedimiento se ejecutar de forma similar a un bloque
PROCESS, por lo que hay que tener alguna sentencia que permita suspender la ejecucin, porque podra ejecutarse de
forma continua. Este tipo de sentencias podra ser una lista sensible o una sentencia WAIT, como ya se explic en los
bloques PROCESS, como se indic, no es posible utilizar la lista de sensibilidad junto con una sentencia WAIT. Este
tipo de sentencias es posible que detengan un procedimiento para siempre si son utilizadas en entornos secuenciales.
23
Captulo 8
Paquetes
Como se coment al principio, un paquete consta de un conjunto de subprogramas, constantes, declaraciones, etc., con
la intencin de implementar algn servicio. As se pueden hacer visibles las interfaces de los subprogramas y ocultar su
descripcin.
24
Captulo 9
Libreras
Hasta ahora se han visto varios elementos del lenguaje, como pueden ser las entidades, las arquitecturas, los paquetes,
etc. Cuando se realiza una descripcin en VHDL se utilizan estas unidades, en uno o ms cheros, stos se denominan
cheros de diseo. Posteriormente, estos cheros sern compilados para obtener una librera o biblioteca de diseo, de
forma que esta biblioteca contiene los elementos que componen el circuito. La biblioteca donde se guardan los resultados
de la compilacin se denomina work.
Una librera se compone de dos partes bien diferenciadas, dependiendo de las unidades que la formen. Por un lado, estn
las unidades primarias, que correspondern a entidades, paquetes y archivos de conguracin. Mientras que las unidades
secundarias sern arquitecturas y cuerpos de paquetes. Por lo tanto, se puede sacar la conclusin de que cada unidad
secundaria deber estar asociada con una unidad primaria.
Al realizar una compilacin se analizarn las unidades que vayan apareciendo en el texto. Por consiguiente, es importante
establecer un orden lgico de las distintas unidades, para que de esta forma se puedan cumplir las dependencias existentes
entre las mismas. La forma que toma la librera una vez compilada es muy diversa; dependiendo de la herramienta
de compilacin utilizada as ser el resultado obtenido, esto se debe a que en VHDL no existe un estndar para crear
bibliotecas.
Para incluir una librera a un diseo basta con utilizar la palabra reservada LIBRARY seguida del nombre de la biblioteca
a utilizar. Adems, tambin es posible hacer visibles elementos internos de estas bibliotecas con el uso de la sentencia
USE, como se explic en el apartado anterior. En el caso de querer hacer visible todos los elementos de un paquete se
puede utilizar la palabra reservada ALL.
LIBRARY mis_componentes; USE mis_componentes.logic.ALL;
En VHDL hay dos libreras que no hacen falta importarlas. Por un lado est la librera work, que contiene las unidades
que se estn compilando, y por otro lado, la librera std que contiene los paquetes standard y textio, las cuales contienen
deniciones de tipos y funciones para el acceso a cheros de texto.
26
GE <>) OF std_logic;
CAPTULO 9. LIBRERAS
Captulo 10
10.2 Ficheros
En algunas ocasiones es interesante utilizar cheros para leer informacin o incluso almacenarla. El uso de cheros nicamente es vlido en la simulacin, mientras que en la sntesis no es posible su uso. Estos cheros no pueden almacenar
matrices multidimensionales, punteros o cheros.
10.2.1
En primer lugar se debe declarar el tipo de datos que contendr dicho archivo. Mediante las palabras reservadas TYPE
y FILE se genera la siguiente estructura.
27
28
TYPE chero_tipo IS FILE OF tipo; FILE nombre : chero_tipo IS [modo] chero": -- VHDL'87 [chero_tipo [OPEN
modo] IS chero"] -- VHDL'93
Cuando se tratan con cheros en VHDL, la estructura anterior depende del compilador que se utilice (VHDL'87 y
VHDL'93). La primeras lneas son iguales en ambos casos, pero a la hora de indicar el acceso al chero la sintxis
diere de uno a otro compilador. En VHDL'87 el modo puede ser IN (por defecto) si se va a leer y OUT para escribir.
Por otro lado, en VHDL'93 el modo es denido mediante un tipo enumerado declarado en la librera correspondiente
(le_open_kind), donde se encuentra write_mode, read_mode (por defecto) o append_mode, que indica escritura, lectura
y concatenacin respectivamente. A diferencia que en el anterior, en este caso no es necesario abrirlo obligatoriamente
en el momento en que se declara. Para posteriormente abrirlo se podra utilizar el siguiente subprograma.
PROCEDURE le_open(status: OUT le_open_status; FILE f: le_type; external_name: IN string; open_kind: IN le_open_kind:=read_mode);
Al realizar la apertura despus de la declaracin conlleva una exibilidad mayor, como puede ser la peticin del nombre
del chero. Tambin es posible obtener el estado en el cual se qued el chero: open_ok, status_error, name_error y
mode_error, aunque este parmetro es opcional.
Adems de este subprograma existe otro para poder cerrar el chero abierto.
PROCEDURE le_close(FILE f: le_type);
A continuacin se muestra un ejemplo de declaracin, apertura y cierre de cheros.
TYPE arch_integer IS FILE OF integer; -- Declaracin y apertura a la vez FILE datos: arch_integer OPEN read_mode
IS input.txt"; -- Declaracin y apertura posterior FILE datos: arch_integer; ..... le_open(datos, input.txt,read_mode);
-- Cerrar le_close(datos);
10.2.2
Una vez que se ha declarado un chero es posible realizar diferentes operaciones como son la lectura, la escritura o la
propia comprobacin de n de archivo. Estas operaciones pueden ser realizadas a travs de unos subprogramas que se
detallan a continuacin.
PROCEDURE read(FILE f: tipo_archivo; value: OUT tipo); PROCEDURE write(FILE f: tipo_archivo; value: IN tipo);
PROCEDURE endle(FILE f: tipo_archivo) RETURN boolean;
El siguiente cdigo muestra un ejemplo de como utilizar estos procedimientos.
TYPE type_arch IS FILE OF integer; FILE arch : type_arch OPEN read_mode IS arch.txt"; VARIABLE n : integer;
..... WHILE NOT endle(arch) LOOP read(arch, n); .... END LOOP;
10.2.3
Ficheros de texto
Trabajar con cheros es til, pero hay que recordar que VHDL codican los datos de forma binaria, lo que implica que es
muy poco legible. Por lo tanto, debe haber una manera de traducir los datos de forma que el lenguaje pueda entenderlos,
y para el usuario sea fcil de escribir dichos archivos. El paquete textio permite la conversin de tipos.
Captulo 11
11.1 Retrasos
El retraso es uno de los elementos ms importantes de la simulacin, puesto que el comportamiento de un circuito puede
cambiar dependiendo del cambio de las diferentes seales. Cuando se realiza una asignacin se produce de forma inmediata, puesto que no se ha especicado ningn retraso. Este comportamiento puede ser alterado mediante la opcin
AFTER cuando se asigna un valor a una seal. Su sintaxis corresponde a la siguiente lnea.
seal <= valor AFTER tiempo;
Donde tiempo es un valor de tiempo indicado en us, ns, ms, ... Un ejemplo puede ser el siguiente.
rst <= '0' AFTER 15 ns;
Pero esta sentencia es mucho ms compleja, por ejemplo se puede asignar inicialmente un valor y modicarlo posteriormente o incluso que sea modicado cada cierto tiempo.
signal clk : std_logic := '0'; .... rst <= '1', '0' AFTER 15 ns; -- Inicialmente rst=1, despues de 15 ns rst=0 clk <= not clk
AFTER 5 ns; -- Cada 5 ns clk cambia de valor
Tambin es posible introducir una espera entre dos sentencias mediante la palabra reservada WAIT. La sintxis de esta
operacin e ms compleja que la anterior.
WAIT [ON lista | UNTIL condicion | FOR tiempo];
Lista corresponde a una lista de sensibilidad de seales, es decir, se permanecer en espera hasta que se produzca un
cambio en alguna de las seales de la lista. Condicin se trata de una espera indeterminada hasta que la condicin sea
verdadera. Por ltimo, el tiempo es un valor denido en una unidad de tiempo. A continuacin se muestra un ejemplo de
las tres esperas posibles.
-- WAIT ON stop <= '1'; WAIT ON semaforo; -- Hasta que semaforo no cambie se permanecer en el WAIT stop
<= '0'; .... -- WAIT UNTIL ack <= '1'; WAIT UNTIL clk'event and clk = '1'; -- Hasta que no exista un evento de clk y
sea uno se permanece en WAIT ack <= '0'; .... -- WAIT FOR start <= '0'; WAIT FOR 50 ns; -- Se espera 50 ns start <= '1';
29
30
11.3 Noticaciones
En la simulacin de circuitos es interesante el uso de las noticaciones, gracias a ellas se pueden advertir que seales han
sido activadas o incluso comprobar si una seal ha tomado un valor determinado. El uso de noticaciones se realiza mediante ASSERT, seguida de una condicin como elemento de activacin. La sentencia puede utilizarse tanto en entornos
concurrentes como en serie.
ASSERT <condicin> [REPORT <expresin>] [SEVERITY <expresin>];
Si la condicin no se cumple aparecer en la pantalla del simulador el mensaje que se ha especicado y el nivel de gravedad,
ambos son opcionales y en el caso de no indicar ningn mensaje aparecer Assertion Violation. Los diferentes niveles de
gravedad pueden ser (de menor a mayor): note, warning, error (por defecto) y failure. Dependiendo del nivel de gravedad
la simulacin puede detenerse.
A continuacin se muestran una serie de ejemplos de esta sentencia.
ASSERT adrr = X"00001111"; .... ASSERT addr = X"10101010 REPORT Direccion Erronea"; .... ASSERT addr >
X"00001000 and addr < X"00002000 REPORT Direccion correcta SEVERITY note; .... ASSERT addr < X"00001000
and addr > X"00002000 REPORT Direccion incorrecta SEVERITY warning;
31
11.4.1
Mtodo tabular
Para vericar la funcionalidad de un diseo se debe elaborar una tabla con las entradas y las respuestas que se esperan a
dichas entradas. Todo ello se deber relacionar mediante cdigo VHDL. Las siguientes lneas muestran un ejemplo con
el diseo que se expuso anteriormente.
USE work.round; ENTITY test_round IS END test_round; ARCHITECTURE test OF test_round IS SIGNAL clk, rst,
met : std_logic; SIGNAL e, s : std_logic_vector(3 DOWNTO 0); TYPE type_test IS RECORD clk, rst, met : std_logic; e,
s : std_logic_vector(3 DOWNTO 0); END RECORD; TYPE lista_test IS ARRAY (0 TO 6) OF type_test; CONSTANT
tabla_test : lista_test :=( (clk=>'0', rst =>'1', met=>'0', e=>"0000, s=>"0000), (clk=>'1', rst =>'0', met=>'0', e=>"0000,
s=>"0000), (clk=>'1', rst =>'0', met=>'0', e=>"0001, s=>"0010), (clk=>'1', rst =>'0', met=>'0', e=>"1010, s=>"0101),
(clk=>'1', rst =>'0', met=>'1', e=>"0000, s=>"0000), (clk=>'1', rst =>'0', met=>'1', e=>"0001, s=>"1000), (clk=>'1',
rst =>'0', met=>'1', e=>"1001, s=>"1100)); BEGIN r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met
=> met, e => e, s => s); PROCESS VARIABLE vector : type_test; VARIABLE errores : boolean := false; BEGIN FOR
i IN 0 TO 6 LOOP vector := tabla_test(i); clk<=vector.clk; rst<=vector.rst; met<=vector.met; e<=vector.e; WAIT FOR
20 ns; IF s /= vector.s THEN ASSERT false REPORT Salida incorrecta SEVERITY error; errores:=true; END IF;
END LOOP; ASSERT errores REPORT Test OK SEVERITY note; WAIT; END PROCESS; END test;
11.4.2
En el caso anterior los casos de prueba y el cdigo de simulacin permanecan juntos, pero es posible separarlos de
forma que, por un lado se encuentren las pruebas y por otro el cdigo. Esto es posible ya que VHDL dispone de paquetes
de entradas/salida para la lectura/escritura en cheros de texto, como ya se comento el paquete textio dispone de los
subprogramas necesarios para el acceso a dichos cheros.
Supnganse los casos de prueba desarrollados en el caso anterior, en el siguiente chero de texto se han escrito los vectores
de prueba:
clk rst met e s 0 1 0 0000 0000 1 0 0 0001 0010 1 0 0 1010 0101 1 0 1 0000 0000 1 0 1 0001 1000 1 0 1 1001 1100
A continuacin se muestra el cdigo relacionado con la simulacin, en l se incluye el acceso al chero anterior que
contiene los diferentes vectores de test.
USE std.textio.ALL; -- No es necesario porque se incluye por defecto USE work.round; ENTITY test_round IS END
test_round; ARCHITECTURE test OF test_round IS SIGNAL clk, rst, met : std_logic; SIGNAL e, s : std_logic_vector(3
DOWNTO 0); BEGIN r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met => met, e => e, s => s); PROCESS
FILE vector_test : text OPEN read_mode IS test.txt"; VARIABLE errores : boolean := false; VARIABLE vector : line;
VARIABLE clk_tmp, rst_tmp, met_tmp : std_logic; VARIABLE e_tmp, s_tmp : std_logic_vector(3 DOWNTO 0); BEGIN readline(vector_test,vector); -- Lee los nombres (la primera linea) WHILE NOT endle(vector_test) LOOP readline(vector_test,vector); read(vector,clk_tmp); read(vector,rst_tmp); read(vector,met_tmp); read(vector,e_tmp); read(vector,s_tmp);
clk <= clk_tmp; rst <= rst_tmp; met <= met_tmp; e <= e_tmp; WAIT FOR 20 ns; IF s_tmp /= s THEN ASSERT false
REPORT Salida incorrecta SEVERITY error; errores:=true; END IF; END LOOP; le_close(vector_test); ASSERT
errores REPORT Test OK SEVERITY note; WAIT; END PROCESS; END test;
11.4.3
Metodologa algortmica
Existe otro tipo de test, los cuales se basan en realizar algoritmos para cubrir el mayor nmero de casos posibles. A
continuacin se muestra un ejemplo, el cual aplica esta metodologa.
USE work.round; ENTITY test_round IS END test_round; ARCHITECTURE test OF test_round IS SIGNAL clk :
32
std_logic := '0'; SIGNAL rst, met : std_logic; SIGNAL e, s : std_logic_vector(3 DOWNTO 0); BEGIN clk <= NOT
clk after 10 ns; r : ENTITY work.round PORT MAP(clk => clk, rst => rst, met => met, e => e, s => s); PROCESS
BEGIN rst <= '1'; met <= '0'; e <= 0000"; WAIT FOR 20 ns; ASSERT (s="0000) REPORT Error en reset SEVERITY error; rst <= '0'; e <= 0000"; WAIT FOR 20 ns; ASSERT (s="0000) REPORT Error desplazamiento izquierda
SEVERITY error; e <= 0001"; WAIT FOR 20 ns; ASSERT (s="0010) REPORT Error desplazamiento izquierda
SEVERITY error; e <= 1010"; WAIT FOR 20 ns; ASSERT (s="0101) REPORT Error desplazamiento izquierda
SEVERITY error; met <= '1'; e <= 0000"; WAIT FOR 20 ns; ASSERT (s="0000) REPORT Error desplazamiento derecha SEVERITY error; e <= 0001"; WAIT FOR 20 ns; ASSERT (s="1000) REPORT Error desplazamiento
derecha SEVERITY error; e <= 1001"; WAIT FOR 20 ns; ASSERT (s="1100) REPORT Error desplazamiento derecha SEVERITY error; ASSERT false REPORT Test Finalizado SEVERITY note; WAIT; END PROCESS; END test;
Captulo 12
Programacin en VHDL/Ejemplos
En este captulo se mostrarn ejemplos de diseos lo ms completos posible, van desde la descripcin del problema hasta
su simulacin, se deja al lector si dispone del hardware apropiado su sntesis y vericacin real, as como su simulacin
mediante el software apropiado.
1. Puerta triestado
2. Multiplexor
3. Sumador
4. Contador
5. Biestable-Latch
6. Mquinas de estados
7. ALU
33
Captulo 13
Programacin en VHDL/Ejemplos/ALU
El objetivo es crear un dispositivo capaz de realizar cualquier operacin dependiendo del valor de una seal de entrada,
adems se dispondr de dos entradas de datos.
Entradas:
a: Entrada de datos 1.
b: Entrada de datos 2.
proceso: Entrada de la operacin.
Salidas:
c: Salida de datos.
LIBRARY ieee; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all ENTITY alu IS PORT(op1 : IN
std_logic_vector(7 DOWNTO 0);--entrada 1 op2 : IN std_logic_vector(7 DOWNTO 0);--entrada 2 proceso : IN std_logic_vector(3
DOWNTO 0);--que hara la alu res : OUT std_logic_vector(15 DOWNTO 0)); END alu; ARCHITECTURE synth OF alu
IS SIGNAL a,b:UNSIGNED(op1'range); SIGNAL c:UNSIGNED(resrange); BEGIN PROCESS (a, b, proceso) BEGIN
CASE proceso IS WHEN 0000 => c <= RESIZE((a + b),c'length); WHEN 0001 => c <= RESIZE((a - b),c'length);
WHEN 0010 => ........ WHEN OTHERS => null; END CASE; END PROCESS; a <= UNSIGNED(op1); b <= UNSIGNED(op2); res <= std_logic_vector(c); END synth;
34
Captulo 14
Programacin en
VHDL/Ejemplos/Biestable-Latch
El objetivo es crear un dispositivo capaz de reproducir en cada tic de reloj la entrada en la salida. Para ello ser necesario
diponer del reloj y reset del sistema.
Entradas:
rst: Reset del sistema.
clk: Reloj del sistema.
a: Entrada de datos.
Salidas:
b: Salida de datos.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY biestable IS PORT (clk : IN std_logic; rst : IN std_logic;
a : IN std_logic_vector(31 DOWNTO 0); b: OUT std_logic_vector(31 DOWNTO 0)); END biestable; ARCHITECTURE synth OF biestable IS BEGIN pSeq : PROCESS (clk, rst) IS BEGIN IF rst = '1' THEN b <= (others => '0'); ELSIF
clk='1' AND clk'event THEN b <= a; END IF; END PROCESS; END synth;
Tambin es posible realizar esta operacin a travs de una seal de activacion (enable), pero a este tipo de diseos se les
denomina latch. En este caso no har falta la seal de reloj, pero s el reset.
Entradas:
rst: Reset del sistema.
en: Enable de almacenamiento.
a: Entrada de datos.
Salidas:
b: Salida de datos.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; ENTITY latch IS PORT (en : IN std_logic; rst : IN std_logic; a : IN
std_logic_vector(31 DOWNTO 0); b: OUT std_logic_vector(31 DOWNTO 0)); END latch; ARCHITECTURE synth
OF latch IS BEGIN pSeq : PROCESS (en, rst) IS BEGIN IF rst = '1' THEN b <= (others => '0'); ELSIF en = '1' THEN
b <= a; END IF; END PROCESS; END synth;
35
Captulo 15
Programacin en
VHDL/Ejemplos/Contador
El objetivo es crear un contador con reset asncrono, seal de habilitacin y salida con un nmero de bits congurable,
con la siguiente denicin de interfaz:
Entradas:
reset: Reset del sistema.
clk: Reloj del sistema.
enable: Activacin-Desactivacin del contador.
Salidas:
count: Salida del contador.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.all; USE IEEE.NUMERIC_STD.all; ENTITY count IS GENERIC
(width:POSITIVE:=8); PORT (clk : IN std_logic; reset : IN std_logic; enable: IN std_logic; count : OUT std_logic_vector(width1 DOWNTO 0) ); END count; ARCHITECTURE arch1 OF count IS SIGNAL cnt : UNSIGNED(width-1 DOWNTO
0); BEGIN pSeq : PROCESS (clk, reset) IS BEGIN IF reset = '1' THEN cnt <= (others => '0'); ELSIF clk'event AND
clk='1' THEN IF enable='1' THEN cnt <= cnt + 1; END IF; END IF; END PROCESS; count <= std_logic_vector(cnt);
END arch1;
36
Captulo 16
Programacin en
VHDL/Ejemplos/Multiplexor
El objetivo es crear un sistema que devuelva un valor dependiente de otra seal de entrada, la cual ser la encargada de
seleccionar la salida. Adems se denirn varias entradas de datos que actuarn como salidas. Cuando la seal de seleccin
este a cero no se producir ninguna salida, es decir el valor ser cero.
Entradas:
a, b, c: entradas de datos.
sel: seal que indica la seal que va a ser devuelta.
Salidas:
salida: salida de datos.
library IEEE; use IEEE.STD_LOGIC_1164.all; ENTITY mux IS PORT(a : IN std_logic_vector(3 DOWNTO 0); b : IN
std_logic_vector(3 DOWNTO 0); c : IN std_logic_vector(3 DOWNTO 0); sel : IN std_logic_vector(1 DOWNTO 0);
salida : OUT std_logic_vector(3 DOWNTO 0)); END mux; ARCHITECTURE synth OF mux IS BEGIN PROCESS
(sel, a, b, c) IS BEGIN CASE sel IS WHEN 00 => salida <= (others => '0'); WHEN 01 => salida <= a; WHEN
10 => salida <= b; WHEN 11 => salida <= c; WHEN OTHERS => salida <= (others => '0'); END CASE; END
PROCESS; END synth;
37
Captulo 17
Programacin en
VHDL/Ejemplos/Mquinas de estados
El objetivo es crear un sistema que genere unas salidas determinadas, dependiendo de los estados por donde va uyendo
la ruta de datos. Por consiguiente, har falta el reset y reloj del sistema como entradas del sistema. Tambin se aade una
seal para sacar el estado al exterior.
Entradas:
rst: Reset del sistema.
clk: Reloj del sistema.
Salidas:
a: Salida de datos.
b: Salida de datos.
estado: Salida del estado.
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY maquina_estados IS PORT (clk : IN std_logic; rst : IN
std_logic; a : OUT std_logic; b : OUT std_logic; estado : OUT std_logic_vector(3 downto 0)); END maquina_estados;
ARCHITECTURE synth OF maquina_estados IS SIGNAL pstate, n_state : std_logic_vector(3 downto 0); BEGIN -maquina de estados PROCESS (clk, rst) BEGIN IF rst = '1' THEN pstate <= 0000"; ELSIF clk = '1' AND clk'event
THEN pstate <= n_state; END IF; END PROCESS; estado <= pstate; n_state <= 0001 WHEN (pstate = 0000) ELSE 0010 WHEN (pstate = 0001) ELSE 0011 WHEN (pstate = 0010) ELSE 0100 WHEN (pstate = 0011)
ELSE 0101 WHEN (pstate = 0100) ELSE 0011 WHEN (pstate = 0101) ELSE 0111 WHEN (pstate = 0011)
ELSE 1000 WHEN (pstate = 0111) ELSE 1001 WHEN (pstate = 1000) ELSE 0000"; a <= '1' WHEN pstate
= 0000 ELSE -0 '0' WHEN pstate = 0001 ELSE -1 '0' WHEN pstate = 0010 ELSE -2 '1' WHEN pstate
= 0011 ELSE -3 '1' WHEN pstate = 0100 ELSE -4 '1' WHEN pstate = 0101 ELSE -5 '1' WHEN pstate
= 0110 ELSE -6 '1' WHEN pstate = 0111 ELSE -7 '1' WHEN pstate = 1000 ELSE -8 '1' WHEN pstate =
1001 ELSE -9 '0'; b <= '1' WHEN pstate = 0000 ELSE -0 '1' WHEN pstate = 0001 ELSE -1 '1' WHEN
pstate = 0010 ELSE -2 '1' WHEN pstate = 0011 ELSE -3 '1' WHEN pstate = 0100 ELSE -4 '0' WHEN
pstate = 0101 ELSE -5 '0' WHEN pstate = 0110 ELSE -6 '1' WHEN pstate = 0111 ELSE -7 '1' WHEN
pstate = 1000 ELSE -8 '1' WHEN pstate = 1001 ELSE -9 '0'; END synth;
38
Captulo 18
Programacin en VHDL/Ejemplos/Puerta
triestado
El objetivo es crear una puerta que tenga una seal de operacin la cual, a estado alto, habilite la salida, por lo tanto el
valor de la entrada pasar a la salida. Cuando la seal de operacin est a nivel bajo la puerta no sacar una seal, es decir,
estar en alta impedancia.
Entradas:
entrada: entrada de datos.
op: seal que indica el modo de funcionar de la puerta.
Salidas:
salida: salida de datos.
LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; ENTITY triestado IS PORT(op, entrada: IN std_logic; salida: OUT
std_logic); END triestado; ARCHITECTURE synth OF triestado IS BEGIN PROCESS(entrada,op) BEGIN IF op='1'
THEN salida <= entrada; ELSE salida <= 'Z'; END IF; END PROCESS; END ARCHITECTURE synth;
39
Captulo 19
Programacin en VHDL/Ejemplos/Sumador
El objetivo es crear un sumador que dadas dos entradas de datos devuelva la suma de estos.
Entradas:
a: operando 1.
b: operando 2.
Salidas:
salida: suma de las entradas.
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.NUMERIC_STD.all; ENTITY sum IS PORT (a : IN std_logic_vector(3
DOWNTO 0); b : IN std_logic_vector(3 DOWNTO 0); salida : OUT std_logic_vector(4 DOWNTO 0)); END sum; ARCHITECTURE synth OF sum IS BEGIN PROCESS (a, b) IS BEGIN salida <= std_logic_vector(UNSIGNED(a) +
UNSIGNED(b)); END PROCESS; END synth;
40
41
Text
19.1.2
Images
19.1.3
Content license