Está en la página 1de 28

VHDL- I. Microelectrnica.

Curso 01/02

LENGUAJE VHDL

1. Introduccin. ................................................................................................................................................. 2

2. Elementos sintcticos en VHDL................................................................................................................... 3

3. Formas de descripcin en VHDL. ............................................................................................................... 7


3.1. Descripcin mediante flujos de datos. ..................................................................................................... 8
3.2. Descripcin comportamental algortmica. ............................................................................................. 10
3.3. Descripcin estructural. ......................................................................................................................... 15

4. Poniendo orden: subprogramas, paquetes y bibliotecas.......................................................................... 19


4.1. Funciones y procedimientos................................................................................................................... 19
4.2. Bibliotecas, paquetes y unidades. .......................................................................................................... 21

5. Ejemplos de VHDL. .................................................................................................................................... 23


5.1. Flip-flop D sncrono............................................................................................................................... 24
5.2. F-F tipo D con puesta a cero y a uno asncronas.................................................................................... 24
5.3. Contadores. ............................................................................................................................................ 25
5.4. Mquinas de estado................................................................................................................................ 26
5.5. Salidas triestado. .................................................................................................................................... 27
5.6. Puertos bidireccionales. ......................................................................................................................... 27

Bibliografa...................................................................................................................................................... 28

Carlos Medrano, E.U. Politcnica de Teruel -1-


VHDL- I. Microelectrnica. Curso 01/02

1. Introduccin.

Con la creciente complejidad de los diseos digitales ha aparecido una necesidad de describir un
circuito de la forma ms eficiente y prctica posible. Un lenguaje de programacin ofrece la
posibilidad de un alto nivel de abstraccin y es la solucin adecuada para dicha tarea. Entre los
lenguajes para la descripcin de circuitos digitales, el VHDL es el que est alcanzando mayor
popularidad, por ser un estndar y por su amplio campo de aplicacin, desde el modelado para la
simulacin de circuitos, hasta la sntesis automtica de circuitos.
El significado de las siglas VHDL es Very high speed integrated circuit (VHSIC) Hardware
Description Language. VHDL es una forma en que los humanos y las mquinas puedan leer y
entender la funcionalidad y la organizacin de sistemas hardware digitales. Las ventajas del VHDL
son:

-Permite disear y modelar un sistema en varios niveles de abstraccin: flujo de datos,


estructural, algortmico.
-Una descripcin en VHDL es independiente de la implementacin hardware final del proyecto.
Puede ser sintetizado sobre una PLD o un ASIC. Incluso puede servir para simulacin
exclusivamente.
-Permite el diseo Top-Down y modular, es decir, dividir un sistema complicado en subsistemas
ms sencillos, tantas veces como sea necesario hasta poder resolver cada mdulo (subsistema) por
separado. Ello facilita la prueba de cada mdulo independientemente y da ms seguridad al correcto
funcionamiento del sistema final. VHDL ofrece sus propias maneras de definir "subprogramas".
-Es un estndar (IEEE Std 1076-1987, IEEE Std 1076-1993). No obstante, hay que decir que
cada fabricante ofrece sus propias libreras con funciones tiles no definidas en el estndar. Por ello,
el paso de un entorno de programacin a otro no es trivial. Nosotros suponemos que trabajamos con
el estndar del ao 93.

Inicialmente, VHDL fue diseado para el modelado de circuitos digitales. Su utilizacin en


sntesis (implementacin hardware) no es inmediata, aunque la sofisticacin de las actuales
herramientas es tal que permite implementar diseos en un alto nivel de abstraccin.

En este curso, se explicarn los fundamentos del VHDL pensando en su utilizacin para
programar dispositivos de tipo PLD o FPGA. No conviene olvidar que el VHDL en s mismo no
est asociado a dispositivos programables, sino que es una descripcin de un circuito en alto nivel.
De cualquier modo, una descripcin que sea sintetizable es casi siempre vlida tambin para
simulacin, mientras que una descripcin para simulacin puede tener ms problemas a la hora de
compilarla sobre un dispositivo hardware.

En este captulo se introducen mediante ejemplos, la sintaxis del lenguaje, de forma que se
cubran los bloques ms habituales en diseo digital, intentando que rpidamente sea posible escribir
programas tiles, por comparacin con los ejemplos dados en los apuntes. No pretende ser una gua
extensa del VHDL. Para ello, y para resolver problemas concretos, es necesario acudir a la
bibliografa o a los manuales que cada fabricante ofrece.

La herramienta que usaremos se denomina MaxPlusII, de la marca Altera. Es un programa que


admite entradas en VHDL, sntesis en PLD de dicha marca, as como simulacin de los ficheros
fuente para programar las PLD (ficheros jedec, .jed o .pof). Es una herramienta muy potente, que
tiene adems entrada con captura esquemtica, analizador de tiempos y posibilidad de interface con

Carlos Medrano, E.U. Politcnica de Teruel -2-


VHDL- I. Microelectrnica. Curso 01/02

herramientas de otras marcas. Se puede conseguir una versin gratis (de estudiante) en
www.altera.com, que aunque obviamente no tiene todas las posibilidades de la herramienta
completa, permite el contacto con un entorno profesional.

2. Elementos sintcticos en VHDL.

Daremos unas breves definiciones de los elementos que se usan en VHDL

Comentarios: empiezan por dos guiones "--" seguidos, hasta el final de lnea.

Smbolos especiales: de un slo carcter + - / * ( ) . , : ; & ' " < > | = #


de dos caracteres ** => := /= >= <= <> --

Identificadores: Se usan para dar nombre a los diferentes objetos del lenguaje. Pueden ser
cualquier nombre compuesto por letras y nmeros, incluyendo el smbolo de subrayado "_". Nunca
puede contener uno de los smbolos especiales, no puede empezar por un nmero ni contener dos
subrayados seguidos. Las maysculas y minsculas se consideran iguales. Tampoco puede coincidir
con una de las palabras reservadas del lenguaje (que tienen un significado predefinido).

Nmeros: Se considera que estn en base 10. Se admite la notacin cientfica para nmeros en
coma flotante. Es posible escribir nmeros en otras bases utilizando el smbolo #. As,
2#11000100# es un nmero en base 2, 16#c4# en hexadecimal. No obstante, los nmeros son
mucho menos utilizados en VHDL que en otros lenguajes de programacin, puesto que es un
lenguaje orientado a diseos digitales, donde los valores que se manejan son bits o cadenas de bits.

Caracteres: Cualquier letra o nmero entre comillas simples: '2', 't'.

Cadenas: Conjunto de caracteres en comillas dobles: "hola"

Cadenas de bits: los bits son en realidad caracteres, y es posible formar con ellos cadenas y
representar nmeros. "1110100", O"126", X"FE"; el primero es binario, el segundo octal, indicado
por la O delante de la cadena, el ltimo es hexadecimal, indicado por la X delante de la cadena.

Palabras reservadas. Son aquellas que tienen un significado especial en VHDL

Operadores.

& concatenacin. Concatena cadenas: as "110" & "001" representa "110001".

** exponencial 4**2 representa 4 al cuadrado


<= := de asignacin, el primero para seales, el segundo para constantes y variables.
ABS() valor absoluto
* multiplicacin
/ divisin
MOD (mdulo)
REM (resto)

SLL, SRL Desplaza un vector de bits un nmero de bits a la izquierda o a la derecha, rellenando
con ceros los huecos libres

Carlos Medrano, E.U. Politcnica de Teruel -3-


VHDL- I. Microelectrnica. Curso 01/02

SLA, SRA Como el anterior pero el desplazamiento conserva el signo, el valor del bit ms
significativo.
ROL, ROR rotacin a izquierda o a derecha. Como un desplazamiento, pero los huecos que se
forman son ocupados por los bits que van saliendo.

=, /= igualdad o desigualdad
<, <=, >, >= menor, menor o igual, mayor, mayor o igual
Not, and, nand, or, nor, xor, xnor.

Tipos de datos.

La sintaxis de VHDL es estricta con respecto a los tipos. Cualquier objeto que se defina debe
tener un tipo. En VHDL no existen tipos propios del lenguaje, pero existen los mecanismos para
poder definir cualquier tipo. Las libreras que se declaran al principio del programa incluyen los
tipos ms habituales.

Tipos escalares: Son tipos simples. Tienen un orden que permite usar operadores
relacionales con ellos. Pueden ser enumerados, enteros, flotantes y fsicos.

Enteros: Se definen incluyendo el rango.

type index is range 7 downto 1;


type integer is range 2147483648 to 2147483647; -- tipo predefinido

Reales (coma flotante): Se deben definir tambin en un rango, pero con lmites reales.
Fsicos: Datos que trabajan con magnitudes fsicas, es decir, con valor y unidades. Hay un tipo
predefinido en VHDL que es el tiempo, time.

Enumerados: Pueden tomar cualquier valor en una lista.

type bit is ('0','1'); --Predefinido


type boolean is (FALSE, TRUE); -- Predefinido

El estandar IEEE 1164 define un tipo enumerado adicional, std_ulogic, y varios subtipos. El tipo
std_ulogic se define con una lista de 9 posibilidades:
type std_ulogic is ('U', -- Sin inicializar
'X', -- Fuerza a desconocido
'0', -- fuerza a 0
'1', -- fuerza a 1
'Z', -- Alta impedancia
'W', -- Desconocido dbil
'L', -- 0 dbil
'H', -- 1 dbil
'-', -- no importa
);
El subtipo std_logic proviene del std_ulogic y la lista de valores es la misma, pero este subtipo
tiene una funcin de resolucin (concepto en el que no entraremos). En la prctica, nosotros
usaremos muy a menudo el tipo std_logic para sntesis. Es ms amplio que el tipo bit, al incluir los
estados de alta impedancia y de no importa. Para usar el subtipo std_logic hay que incluir el paquete
std_logic_1164 de la librera ieee.

Carlos Medrano, E.U. Politcnica de Teruel -4-


VHDL- I. Microelectrnica. Curso 01/02

Tipos compuestos. Estn compuestos por tipos escalares.

Matrices: Coleccin de elementos a los que se accede mediante un ndice.

type word is array(31 downto 0) of bit;


signal b: word;

A los elementos de una matriz se accede mediante los ndices. Si dato es una seal de tipo word,
dato(3) es el elemento 3 de dato, dato(29 downto 25) es una parte del array.

Existen algunos tipos predefinidos.

type bit_vector is array (natural range <>) of bit;


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

que nos permiten definir seales como:

signal a: std_logic_vector(3 downto 0);

Son tambin de gran importancia los tipos unsigned y signed. Representan vectores de std_logic
pero considerndolos con signo. El tipo unsigned representa valores numricos positivos o cero. El
tipo signed representa valores tanto negativos como positivos en complemento a 2. Esto tiene una
implicacin a la hora de hacer comparaciones y otras operaciones.

signal a: unsigned(3 downto 0);

Registros: Equivalente al tipo record de otros lenguajes.

Subtipos.

Es posible la definicin de subtipos como subconjuntos de tipos existentes.

subtype raro is integer range 4 to 7;


subtype id is string(1 to 20);

Atributos.

Los elementos en VHDL pueden tener informacin adicional basada en atributos. Estos atributos
estn asociados a ciertos elementos del lenguaje y se manejan mediante la comilla simple '.

Por ejemplo, si t es una seal de un tipo enumerado, entero, flotante o fsico, se tienen los
siguientes atributos:
t'left lmite izquierdo del tipo left
t'right
t'low menor de los valores en t
t'high
t'length da el nmero de elementos de t.

Carlos Medrano, E.U. Politcnica de Teruel -5-


VHDL- I. Microelectrnica. Curso 01/02

Un atributo importante es 'event. Da un valor booleano verdadero si acaba de ocurrir un cambio


en la seal. Se usa especialmente con seales que sean de reloj:
clk'event

Otro atributo que aparece con frecuencia es 'range. Da el rango de un objeto limitado. Por
ejemplo, si definimos
signal word: std_logic_vector(15 downto 0);

entonces word'range es 15 downto 0

En ciertos programas informticos, hay tambin atributos que permiten agregar informacin
adicional a los objetos que se estn definiendo en VHDL. Estas informaciones adicionales sirven
para pasar informacin a las herramientas de diseo que se estn utilizando en VHDL, por ejemplo
si queremos que ciertas seales estn en determinados pines de una PLD. En MaxPlusII se realiza
de forma grfica.

Seales, constantes y variables.

Constantes.
Una constante es un elemento que se inicializa a un determinado valor que no puede ser
cambiado:

constant indice: integer:=5;


constant max_size: integer;

En el segundo caso max_size no tiene ningn valor asociado. Esto se permite siempre y cuando
el valor sea declarado en algn otro sitio.

Variables.
Su valor puede ser alterado en cualquier instante. Es posible asignarle un valor inicial:

variable contador: natural:=0;


variable aux: bit_vector(31 downto 0);

Las variables slo tiene sentido en bloques donde la ejecucin es en serie: subprogramas y
procesos (process).

Seales.
La seal no es un objeto del lenguaje que guarda un valor, sino que lo que hace es guardar un
valor y hacerlo visible en el momento adecuado. Esto es, se puede decir que la seal tiene dos
partes, una donde ese escribe y que almacena el valor, y otra que se lee y que no tiene por qu
coincidir con lo que se acaba de escribir.

Desde un punto de vista ms cercano al mundo de los circuitos digitales, una seal se entendera
como un nodo en el circuito (nodo en el mismo sentido que en SPICE). Las entradas y salidas de un
bloque digital deben ser definidas como seales. Asimismo, cualquier posible conexin real en el
circuito debe ser definida como seal.
Las asignaciones de seales se realizan con el operador "<=", mientras que las de constantes y
variables utilizan el operador ":=".

Entidades y arquitecturas.

Carlos Medrano, E.U. Politcnica de Teruel -6-


VHDL- I. Microelectrnica. Curso 01/02

La descripcin de un circuito en VHDL consta al menos de dos elementos: la entidad y la


arquitectura. En la entidad se definen las seales de entrada y salida. En la arquitectura, se define lo
que hace el circuito. Previamente a la definicin de ambas, se pueden incluir las libreras y los
paquetes necesarios en el programa. Veamos un ejemplo.

library ieee;
use ieee.std_logic_1164.all;

entity MUX2to1_a is port(


A, B: in std_logic;
Sel: in std_logic;
Y: out std_logic);
end MUX2to1_a;

architecture behavior of MUX2to1_a is


begin
Y<= ( B and Sel ) or
( A and not(Sel) );
end behavior;

Las dos primeras lneas del programa contienen las libreras (ieee) y los paquetes
(std_logic_1164.all) que sern utilizados en el programa. Los tipos ms habituales estn declarados
en esta librera, por lo que su uso es casi imprescindible. Como en el programa se usa el tipo
std_logic, es necesario incluir este paquete.

En la entidad llamada MUX2to1_a, definimos las salidas (Y) y las entradas del sistema (A,B y
Sel). Estas seales son puertos (port). Todas ellas estn definidas como de tipo std_logic. En este
caso, se trata de un multiplexor de dos canales. En la arquitectura, se define lo que realiza la
entidad. En este caso, la descripcin son unas simples ecuaciones booleanas.

Los puertos de las entidades se definen con un modo. Los modos pueden ser de 4 clases: in, out,
buffer, inout:
- in. Entrada a la entidad.
- out. Salidas de la entidad. Este tipo de puertos no se considera legible dentro de la entidad (por
ejemplo, no puede aparecer a la derecha en una asignacin)
- buffer. Es como el modo out, pero es legible dentro de la entidad. Dicho de otro modo,
permite la realimentacin de la seal en la arquitectura.
- inout. Para seales bidireccionales, se tiene que declarar el puerto como inout, que permite que
se pueda escribir o leer desde el exterior.

3. Formas de descripcin en VHDL.

En VHDL existen dos aproximaciones a la descripcin comportamental de un circuito. Por un


lado, se pueden especificar las ecuaciones de transferencia entre diferentes objetos en VHDL. Esta
posibilidad de descripcin de un circuito se llama descripcin de flujo de datos, o RTL (register
transfer level). La otra forma de describir circuitos en un nivel de abstraccin todava ms elevado
se conoce como descripcin comportamental o algortmica. Esta segunda posibilidad incluye a la
primera y permite al diseador de circuitos describir la funcionalidad en un nivel alto de
abstraccin.

Carlos Medrano, E.U. Politcnica de Teruel -7-


VHDL- I. Microelectrnica. Curso 01/02

La diferencia ms importante entre un estilo de descripcin y el otro es que la ejecucin o


interpretacin de sentencias en flujos de datos es concurrente, es decir, las sentencias indican
conexiones o leyes que se cumplen, por tanto es como si se ejecutaran continuamente. Esta es una
diferencia clara con otros lenguajes como el C, Pascal, Fortran etc., donde la ejecucin de las
sentencias es en serie. Esto ltimo significa que las sentencias son ejecutadas una tras otra por el
ordenador.

Lenguajes como VHDL, pensado para describir circuitos, deben ser ante todo concurrentes. Un
circuito no se ejecuta en serie, sino que las conexiones entre componentes siempre actan. No
obstante, el lenguaje VHDL tambin permite descripciones con ejecucin en serie, que hacen ms
fcil la programacin en abstracto.

3.1. Descripcin mediante flujos de datos.

when ... else

Se trata de una estructura concurrente. Veamos el ejemplo de un decodificador BCD a 10 lneas:

library ieee;
use ieee.std_logic_1164.all;

entity BCD_9 is port(


A: in std_logic_vector(3 downto 0);
Y: out std_logic_vector(9 downto 0));
end BCD_9;

architecture archBCD_9 of BCD_9 is


begin

Y<="0000000001" when A="0000" else


"0000000010" when A="0001" else
"0000000100" when A="0010" else
"0000001000" when A="0011" else
"0000010000" when A="0100" else
"0000100000" when A="0101" else
"0001000000" when A="0110" else
"0010000000" when A="0111" else
"0100000000" when A="1000" else
"1000000000" when A="1001" else
"0000000000";

end archBCD_9;

En este caso, usamos varios when ... else anidados. Cuando la entrada A toma un nmero en
BCD, la lnea correspondiente se activa.

Qu significa en este caso que la estructura es concurrente? Por ejemplo, es imposible asignar
otros valores a la salida Y en el mismo programa. As, este otro cdigo dara un error de
compilacin:

-- Incorrecto
library ieee;
use ieee.std_logic_1164.all;

Carlos Medrano, E.U. Politcnica de Teruel -8-


VHDL- I. Microelectrnica. Curso 01/02

entity BCD_9 is port(


A: in std_logic_vector(3 downto 0);
Y: out std_logic_vector(9 downto 0));
end BCD_9;

architecture archBCD_9 of BCD_9 is


begin
Y<="0000000001" when A="0000" else
"0000000010" when A="0001" else
"0000000100" when A="0010" else
"0000001000" when A="0011" else
"0000010000" when A="0100" else
"0000100000" when A="0101" else
"0001000000" when A="0110" else
"0010000000" when A="0111" else
"0100000000" when A="1000" else
"1000000000" when A="1001" else
"0000000000";

Y<="1111111110" when A="0000" else


"1111111101" when A="0001" else
"1111111011" when A="0010" else
"1111110111" when A="0011" else
"1111101111" when A="0100" else
"1111011111" when A="0101" else
"1110111111" when A="0110" else
"1101111111" when A="0111" else
"1011111111" when A="1000" else
"0111111111" when A="1001" else
"1111111111";
end archBCD_9;

Aqu hemos escrito dos decodificadores distintos, uno escrito despus del otro. Es un error
pensar que, puesto que el segundo bloque est despus del primero, es la activacin en baja de las
lneas la que se va a ejecutar. Este programa no puede compilarse. En Pascal por ejemplo, no hay
ningn problema en dar dos valores distintos a las variables, quedndose con el ltimo. En realidad,
lo que estoy haciendo es, pensando en un circuito, conectar las salidas de dos decodificadores
distintos al mismo punto (Y(9), Y(8) etc.). Por tanto, qu ocurre cuando los dos decodificadores
manden seales distintas a las salidas? Esta incompatibilidad es la impide la compilacin. (Siendo
estrictos, el VHDL permite este tipo de situaciones si se incluye un mecanismo de resolucin de las
seales, que indica qu ocurre en caso de incompatibilidad; ste es un concepto de VHDL
avanzado, que no veremos). Esto es vlido para cualquier estructura concurrente.

Conviene tambin fijarse es la definicin de un vector de tipo std_logic. Por ejemplo, A se


define como un std_logic_vector(3 downto 0). Hay que tener en cuenta que en este caso, el bit ms
a la izquierda corresponde al de ndice 3, mientras que si se hubiese definido como
std_logic_vector(0 to 3), sera el de ndice 0. Esto es importante, puesto que en operaciones
aritmticas con cadenas de bits, el bit ms a la izquierda es el ms significativo.

with ... select ... when

Es tambin una estructura concurrente. El codificador BCD a 10 lneas queda:


library ieee;
use ieee.std_logic_1164.all;

Carlos Medrano, E.U. Politcnica de Teruel -9-


VHDL- I. Microelectrnica. Curso 01/02

entity BCD_9 is port(


A: in std_logic_vector(3 downto 0);
Y: out std_logic_vector(9 downto 0));
end BCD_9;

architecture archBCD_9 of BCD_9 is


begin

with A select
Y<="0000000001" when "0000",
"0000000010" when "0001",
"0000000100" when "0010",
"0000001000" when "0011",
"0000010000" when "0100",
"0000100000" when "0101",
"0001000000" when "0110",
"0010000000" when "0111",
"0100000000" when "1000",
"1000000000" when "1001",
"0000000000" when others;
end archBCD_9;

Segn el valor de la seal A, se produce una asignacin u otra. Es importante la ltima lnea,
when others. Si no hemos agotado todas las posibilidades de la entrada A, es necesaria esta ltima
lnea para indicar qu debe hacerse en los casos que no se pongan de forma explcita anteriormente.
En la prctica, es casi obligatorio ponerlo. No conviene olvidar que al definir A como un tipo
std_logic_vector(3 downto 0), no slo hay 16 posibilidades para A, sino que el resto de valores
posibles para A tambin cuentan, por ejemplo "ZZZZ", o "----". Por ello, incluso un decodificador
de 4 a 16 lneas necesitara when others al final, puesto que se ha definido la entrada A como de
tipo std_logic_vector.

3.2. Descripcin comportamental algortmica.

Se trata de partes del programa con una ejecucin en serie, definidos dentro de unidades que
comienzan con la palabra clave process. En un mismo programa puede haber mltiples bloques
process. Cada uno de ellos equivale a una instruccin concurrente. Es decir, aunque internamente el
proceso describe el comportamiento de un circuito mediante una ejecucin de instrucciones en
serie, el compilador para sntesis deduce un circuito a partir de un proceso, y por tanto es
concurrente con el resto de las instrucciones (no puedo asignar un valor a una seal dentro y fuera
de un proceso).

process: if ... then

library ieee;
use ieee.std_logic_1164.all;

entity and3 is port(


a,b,c: in std_logic;
y: out std_logic);
end and3;

architecture archand3 of and3 is


begin

Carlos Medrano, E.U. Politcnica de Teruel - 10 -


VHDL- I. Microelectrnica. Curso 01/02

p1: process (a,b,c)


begin
if (a='1' and b='1' and c='1') then y<='1';
else y<='0';
end if;
end process;
end archand3;

El proceso contiene un identificador, p1 (el nombre que queramos). Posee adems una
"sensitivity list" o lista sensible, (a,b,c), que indica que el proceso se ejecutar cuando haya un
cambio en una de estas variables. Como en cualquier ejecucin en serie, hay que tener cuidado al
anidar los if-then, de forma que el resultado sea el esperado. La utilizacin de else es opcional, pero
si no se agotan todas las opciones, puede dar lugar a latches. Cuando se utilizan varios if then
anidados, puede usarse una contraccin de else if, elsif. En caso de usar la primera forma, es
necesario cerrar el nuevo if que se crea. En caso de usar la forma contrada, no hay que cerrar
ningn if adicional. Si la condicin que se ha de cumplir se refiere a la deteccin de un flanco de
reloj y va precedida de otro if previo, es necesario usar elsif en la deteccin del flanco de reloj, por
ejemplo, en un contador con reset asncrono, la condicin de deteccin del reset va antes de la
deteccin de flanco de reloj.

Es conveniente dejar claro en el cdigo qu es lo que tiene que asignarse a las seales de salida
en el proceso para todas las posibilidades de las seales en la lista sensible. En caso de que haya
casos no especificados al anidar los if, el compilador guarda el valor anterior de la seal en
cuestin, es decir se trata de un latch.

La forma en que un proceso se evala puede ser entendida del siguiente modo. Cuando una seal
que se encuentra en la "sensitivity list" del proceso cambia, este es ejecutado de forma secuencial.
Una vez que se ha llegado a la ltima instruccin, el proceso se detiene y las seales se actualizan.
Es decir, se puede imaginar como los valores antes y despus de un paso de simulacin.

Desde el punto de vista de la sntesis, en el proceso se determinar el valor de una o varias


seales, en funcin de otras que deben estar todas en la lista sensible. El compilador deducir el
circuito lgico que d el mismo comportamiento que el conjunto de las sentencias secuenciales del
proceso (con la distincin entre variables y seales que veremos luego). Una vez obtenido el
circuito lgico, ste es concurrente con respecto al resto de construcciones dentro de la arquitectura.
El siguiente programa por ejemplo, es un error.

library ieee;
use ieee.std_logic_1164.all;

entity and3 is port(


a,b,c: in std_logic;
y: out std_logic);
end and3;

architecture archand3 of and3 is


begin

p1: process (a,b,c)


begin
if (a='1' and b='1' and c='1') then y<='1';
else y<='0';
end if;
end process;

Carlos Medrano, E.U. Politcnica de Teruel - 11 -


VHDL- I. Microelectrnica. Curso 01/02

y<= a or b or c;
end archand3;

Diferencias entre variables y seales.

Es muy importante distinguir entre variables y seales dentro de un proceso. Las seales no
cambian su valor hasta que no acaba el proceso. Las variables slo se definen dentro del proceso, (
o dentro de bloques de ejecucin en serie, como funciones y procedimientos) y cambian su valor en
el momento en el que tienen una asignacin.
Por ejemplo, consideremos estos dos procesos:

architecture ejemp1 of entidad is architecture ejemp1 of entidad is


signal a,b,c,x,y: integer; signal a,b,x,y: integer;
begin begin
p1: process(a,b,c) p1: process (a,b)
begin variable c: integer;
c<=a; -- se ignora begin
x<=c+2; c:=a; -- Inmediata
c<=b; x<=c+2;
y<=c+2; c:=b; -- Inmediata
end process p1; y<=c+2;
end ejemp1; end process p1;
end ejemp1;

En el cdigo de la izquierda slo se usan seales y la ejecucin tiene lugar de la siguiente


manera: En primer lugar se hace la fuente de "c" igual a "a", lo cual slo indica que tomar ese
valor en el prximo paso de simulacin (al salir del proceso), pero no en el presente. A continuacin
se hace lo mismo con "x", asignndole a su fuente el valor de "c+2", es decir el valor que contuviera
"c" antes de empezar la ejecucin, porque el valor que se le asign en el paso anterior todava no
est presente. Luego, se hace "c<=b", es decir que se est sustituyendo el valor de la fuente de "c",
que era "a", por la seal "b". Esto quiere decir que el futuro valor de "c" ya no ser "a", sino "b". A
continuacin se hace "y<=c+2", de manera que a "y" se le asigna el valor "c+2", pero tomando
como "c" el valor de la seal antes de empezar el proceso.

En definitiva, supongamos que antes de iniciarse la ejecucin se tiene "c=2", "a=4", y "b=6".
Entonces al final de la ejecucin de este proceso se tendr "c=b=6", "x=4", "y=4". De todas formas,
puesto que la seal "c" ha cambiado y, como se encuentra en la lista sensible, el proceso se vuelve a
ejecutar, quedando finalmente "c=b=6", "x=y=8".

Se ha visto que la primera instruccin "c<=a" es ignorada completamente en la prctica. Esto es


debido a que las seales no se asignan inmediatamente y a que existe una sentencia posterior
"c<=b" que escribe sobre "c".

En el programa de la derecha "c" es una variable. La definicin de esta variable se hace dentro
del proceso, puesto que slo tiene sentido dentro de la ejecucin serie. Tambin "c" desaparece de
la lista sensible puesto que las variables son internas a los procesos (o a los subprogramas) y nunca
pueden formar parte de las listas sensibles.

Carlos Medrano, E.U. Politcnica de Teruel - 12 -


VHDL- I. Microelectrnica. Curso 01/02

La ejecucin es muy simple. Primero "c" toma el valor de "a", "c:=a". Hay que hacer notar el
smbolo de asignacin ":=" para variables. Como "c" es una variable, "c" toma el valor 4 justo en
este momento. A continuacin se hace la fuente de "x" igual a "c+2", es decir "x" tomar el valor 6
el prximo paso de simulacin. A continuacin se hace "c:=b", de manera que ahora "c" vale 6.
Despus viene "y<=c+2", por lo que "y" valdr 8 cuando se acabe la ejecucin. Al finalizar el
process se tiene que "x=6" e "y=8", y no se volver a ejecutar puesto que ni "a" ni "b" han
cambiado.

Esta discusin sobre variables y seales es vlida en cualquier proceso "process".

En la prctica, las variables pueden ser tiles para hacer algunas construcciones, y son
inevitables en los ndices que recorren los vectores, pero se puede prescindir de su uso en la
mayora de las ocasiones. Un proceso con variables y seales puede ser bastante complicado de
comprender. Hay que evitar el uso de

Conviene recordar tambin que las seales slo se actualizan al final del proceso. No hay que
poner sentencias en el proceso que dependan de una asignacin previa a una seal.

process: case .. when

Se trata de una estructura de ejecucin en serie. Es parecido al with ... select, pero ms general,
puesto que en cada caso no slo se puede hacer una asignacin, sino que despus de cada "=>"
puede escribirse una sentencia o un conjunto de ellas.

library ieee;
use ieee.std_logic_1164.all;

entity mux4to1 is port(


a: in std_logic_vector(3 downto 0);
sel: in std_logic_vector(1 downto 0);
y: out std_logic);
end mux4to1;

architecture archmux4to1 of mux4to1 is


begin
p1: process (a,sel)
begin
case sel is
when "00" => y<=a(0);
when "01" => y<=a(1);
when "10" => y<=a(2);
when "11" => y<=a(3);
when others => y<=a(0);
end case;

end process;

end archmux4to1;

Como en el caso del with ... select es necesario completar con when others, cuando no se han
revisado todos los casos posibles.

Carlos Medrano, E.U. Politcnica de Teruel - 13 -


VHDL- I. Microelectrnica. Curso 01/02

bucles: process: for y while loop

Permiten realizar bucles dentro de procesos. Tambin se ejecutan en serie.

-- cuatro multiplexores 2 a 1 controlados por la misma entrada


-- de seleccion

library ieee;
use ieee.std_logic_1164.all;

entity cuatromux2to1 is
port(
a: in std_logic_vector(7 downto 0);
sel: in std_logic;
y: out std_logic_vector(1 to 4));
end cuatromux2to1;

architecture archcuatromux2to1 of cuatromux2to1 is

type lineas is array (1 to 4) of std_logic_vector(1 downto 0);


signal dum: lineas;

begin

p1: process (dum,sel)


variable i: integer range 1 to 4;-- Al ser un indice de un loop
-- esta definicion es optativa
begin
for i in dum'range loop
y(i)<= (sel and dum(i)(1)) or (not(sel) and dum(i)(0));
end loop;
end process;

dum(1)<=a(1 downto 0);


dum(2)<=a(3 downto 2);
dum(3)<=a(5 downto 4);
dum(4)<=a(7 downto 6);

end archcuatromux2to1;

Este programa es poco prctico, slo se escribe para mostrar, adems de los bucles, el uso de los
arrays. Hemos definido un array de vectores de std_logic. Es en definitiva una matriz:

type lineas is array (1 to 4) of std_logic_vector(1 downto 0);

Hay que hacer notar tambin el uso del for loop, as como del atributo 'range. Este atributo da el
rango de un objeto. En nuestro caso es de 1 a 4, puesto que hemos definido el tipo lineas como un
array (1 to 4).

La seal dum est definida como de tipo lineas. Entonces dum(1) es el primer elemento del
array. Como cada elemento es un std_logic_vector, dum(1) es un std_logic_vector, y dum(1)(1) es
su primer elemento. Una definicin alternativa de un array con el mismo nmero de elementos es:

type lineas is array (1 to 4, 1 downto 0) of std_logic;

Carlos Medrano, E.U. Politcnica de Teruel - 14 -


VHDL- I. Microelectrnica. Curso 01/02

En este caso, si dum fuese de tipo lineas, un elemento de dum necesita dos ndices, dum(1,0) por
ejemplo, y cada elemento es un std_logic.

Es interesante tambin la manera de referirse a una parte de una cadena, en la forma a(7 downto
6), que selecciona dos elementos de la cadena total "a", definida como un std_logic_vector(7
downto 0). Hacemos hincapi asmismo la definicin de seales y de tipos dentro de la
arquitectura:

type lineas is array (1 to 4) of std_logic_vector(1 downto 0);


signal dum: lineas;

La seal dum no es de salida ni de entrada. Se podra entender como un nodo interno al circuito.

De forma anloga al for ... loop se define el while ... loop. Existe tambin la posibilidad de salir
de los bucles con next y exit. (*) Nota: exit no est soportado por MaxPlusII

3.3. Descripcin estructural.

Este tipo de descripcin es cercano a una net-list de otras herramientas CAD. La descripcin
estructural es especialmente interesante para la incorporacin de elementos de biblioteca al diseo y
la realizacin de diseos jerrquicos a partir de componentes. Consideremos dos entidades,
and_de_3 y or_de_n:
library ieee;
use ieee.std_logic_1164.all;
entity and_de_3 is port(
a,b,c: in std_logic;
y: out std_logic);
end and_de_3;
architecture archand_de_3 of and_de_3 is
begin
y<='1' when a='1' and b='1' and c='1' else
'0';
end archand_de_3;

-----------------------------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
entity or_de_n is
generic(n: integer:=2);
port(
a: in std_logic_vector(n-1 downto 0);
y: out std_logic);
end or_de_n;
architecture archor_de_n of or_de_n is
begin
p1: process(a)
variable i: integer range 0 to n-1;
variable res_parcial: std_logic;
begin
res_parcial:='0';
bucle:for i in 0 to n-1 loop
res_parcial:=res_parcial or a(i);
end loop bucle;

Carlos Medrano, E.U. Politcnica de Teruel - 15 -


VHDL- I. Microelectrnica. Curso 01/02

y<=res_parcial;
end process;
end archor_de_n;

Obsrvese que en el segundo caso existe una definicin de una entidad con un parmetro
variable, por ello se usa entity ... generic. De esta forma se puede definir una puerta or de n
entradas, siendo por defecto de dos entradas.

Cada una de estas entidades se compilara por separado.

Estas entidades se pueden definir en una librera, con el paquete (package)correspondiente. Esto
permite a un programa principal llamar a esos componentes (es decir, otras entidades definidas en
libreras), asocindoles los puertos correspondientes. Veremos como definir libreras en MaxPlusII.
Suponiendo que la librera se llama "milibrera" y que el paquete se llama "puertas", el programa
principal quedara:

-- Programa principal
library ieee;
library milibreria;
use ieee.std_logic_1164.all;
use milibreria.puertas.all;

entity variaspuertas is port(


r,s,t,p: in std_logic;
y: out std_logic);
end variaspuertas;

architecture archvariaspuertas of variaspuertas is

signal x,w,z: std_logic;


signal dum1:std_logic_vector(1 downto 0);
signal dum2: std_logic_vector(2 downto 0);
begin
u1: and_de_3 port map(r,s,t,x);
dum1<=r & p;
u2: or_de_n port map(a=>dum1,y=>z);
dum2<=r&s&p;
u3: or_de_n generic map(3) port map (dum2,w);
y<=x or z or w;
end;

La entidad and_de_3 es una puerta and de tres entradas y la segunda or_de_n una puerta or de n
entradas, donde n es un parmetro que por defecto es 2. Es interesante el uso de generic antes de
port, para permitir que la entidad tenga uno o varios parmetros variables.

En la arquitectura del programa principal se hace una asignacin de los "nudos" de cada
componente. La orden bsica es port map:

u1: and_de_3 port map (r,s,t,x);

u1 es un identificador de la sentencia, puede ser cualquier nombre. and_de_3 es el nombre del


componente. Como en l hemos definido los tres primeros puertos como una entrada, y el ltimo
puerto como una salida, el hecho de poner el orden (r,s,t,x) implica que x ser el resultado de una
operacin AND de r, s y t. Conviene hacer notar que los identificadores r,s,t y x no tienen por qu
coincidir con los de la definicin del componente (a,b,c,y). La orden port map no admite constantes.

Carlos Medrano, E.U. Politcnica de Teruel - 16 -


VHDL- I. Microelectrnica. Curso 01/02

La siguiente orden:

u2: or_de_n port map(a=>dum1,y=>z);

es otra asignacin usando el operador "=>", en este caso a una componente or_de_n. Como no
hacemos referencia al tamao (parmetro n), se toma por defecto el definido en la entidad or_de_n,
es decir, 2. En el parntesis, podemos ver otra forma de realizar una asignacin, en lugar de por
posicin como en el ejemplo anterior, mediante el operador =>. Asignamos la seal "dum1" al
puerto llamado "a" de or_de_n, y la seal "z" al puerto "y". "a" e "y" son los nombres de los puertos
en el componente, mientras que "dum1" y "z" son los nombres de las seales en el programa
principal. La seal "dum1" es una seal intermedia, que no es ms que la concatenacin de "r" y
"p". As obtengo un std_logic_vector, que es compatible con la definicin del puerto "a" en la
componente "or_de_n". Si utilizo esta forma de asignacin, no necesito dar las seales en el mismo
orden que en la definicin del componente.

La siguiente orden:

u3: or_de_n generic map(3) port map (dum2,w);

es una puerta or de 3 entradas. Generic map (3) sirve para pasar el parmetro al componente, en
este caso se le dice que el tamao del vector de entrada es 3.

Finalmente, la salida final, "y", no se define mediante componentes sino mediante operadores
booleanos:

y<=x or z or w;

Se puede, por tanto, mezclar tipos de descripciones dentro de un mismo programa, siempre que
una misma seal no sea escrita en distintos puntos del programa.

Las seales dum1 y dum2 slo sirven para tener una compatibilidad con los tipos definidos en
las componentes. As, or_de_n admite como entrada un std_logic_vector. Por tanto, debo pasarle un
objeto del mismo tipo.

En resumen, lo que hemos construido es un circuito como este:


U?
r 2 x
s 3 1
4
t
AND3

U? U?
2 z 2
1 3 1
3 4
p
y
OR2 OR3

U?
2 w
3 1
4

OR3

Carlos Medrano, E.U. Politcnica de Teruel - 17 -


VHDL- I. Microelectrnica. Curso 01/02

Es posible definir tambin las componentes and_de_3 y or_de_n en un nico programa, en lugar
de en una librera. En el listado, se comenzara por las entidades y arquitecturas de cada uno de
ellos, repitiendo cada vez las libreras que se usen en cada entidad-arquitectura. En la arquitectura
principal, se definen las componentes que se van a utilizar, mediante las sentencia component.

component and_de_3 port(


a,b,c: in std_logic;
y: out std_logic);
end component;

Los nombres y los modos de los puertos en estos componentes deben coincidir con los de la
entidad definida para cada componente, y deben tambin colocarse en el mismo orden.

Podemos ver un ejemplo de componente definido en el mismo programa en el siguiente cdigo


que representa un sumador en serie. Adems nos sirve para ilustrar el comando for ... generate
usado para hacer varias asignaciones estructurales en un bucle que dependa de un ndice:

library ieee;
use ieee.std_logic_1164.all;

entity celdasumadora is port(


a,b,cin:in std_logic;
s, cout: out std_logic);
end celdasumadora;

architecture archcelda of celdasumadora is


begin
s<=(a xor b) xor cin;
cout<= (a and b) or ((a or b) and cin);
end archcelda;

-- Programa principal

library ieee;
use ieee.std_logic_1164.all;

entity sumador2 is port(


a: in std_logic_vector(7 downto 0);
b: in std_logic_vector(7 downto 0);
cin: in std_logic;
sum: out std_logic_vector(7 downto 0);
cout: out std_logic);
end entity;

architecture archsumador2 of sumador2 is


signal c: std_logic_vector(7 downto 0);-- acarreos intermedios

component celdasumadora port(


a,b,cin: in std_logic;
s, cout: out std_logic);
end component;

begin
u1: celdasumadora port map(a(0),b(0),cin,sum(0),c(0));
bucle:for i in 1 to 7 generate
begin
u2: celdasumadora port map(a(i),b(i),c(i-1),sum(i),c(i));

Carlos Medrano, E.U. Politcnica de Teruel - 18 -


VHDL- I. Microelectrnica. Curso 01/02

end generate;
cout<=c(7);
end archsumador2;

Conviene insistir en que esto es un ejemplo para demostrar el funcionamiento de la instruccin


component. En este caso, sera mucho ms sencillo hacer el programa principal directamente sin
necesidad de definir componentes. La ventaja de component es la capacidad que proporciona al
programador para hacer un diseo modular, probando cada bloque por separado.

Es posible tambin definir varias arquitecturas para un mismo componente, y asignar a cada
sentencia la arquitectura adecuada en cada caso (sentencia configuration).
ATENCIN: En MaxPlusII, existen bastantes problemas a la hora de la compatibilidad de los
modos (in, out, buffer, inout) tal y como se han definido en un componente y el modo de la seal
que se coloca en el programa principal. Especialmente problemtico resulta el modo buffer. La
forma ms elegante de evitar estos problemas es definir seales de apoyo en la arquitectura. Al estar
definidas en la arquitectura, no tienen modo y pueden escribirse sin problemas en los port map. Las
verdaderas variables pueden ser obtenidas a partir de las de apoyo por simples asignaciones.
MS ATENCIN: MaxPlusII no permite el uso de constantes como puertos de componentes en
el comando port map. Es necesario usar siempre seales. Esto no es en la prctica un
inconveniente. Una seal llamada uno a la que se le asigna un '1' (uno<='1') fuera de un proceso o
funcin es en la prctica una constante puesto que al ser un lenguaje concurrente no le puedo
asignar un valor en ningn otro lugar del programa.

4. Poniendo orden: subprogramas, paquetes y bibliotecas.

Como otros lenguajes de programacin, VDHL permite el uso de subprogramas, que contienen
una porcin de cdigo y a los cuales se les puede llamar. La instruccin component es, de algn
modo, un subprograma. Veremos a continuacin otras dos estructuras que permite el VHDL:
funciones y procedimientos.

4.1. Funciones y procedimientos.

Son similares a las estructuras de otros lenguajes. Son subprogramas a los que se les pasan unos
parmetros. Las diferencias entre funciones y procedimientos son:

-Una funcin siempre devuelve un valor, mientras que un procedimiento slo puede devolver
valores a travs de los parmetros que se le pasen.
-Los argumentos de una funcin son siempre de entrada (in), por lo que dentro de la funcin slo
se pueden leer. No es necesario especificar el modo. En el procedimiento pueden ser de entrada, de
salida o de entrada y salida, por lo que pueden sufrir modificaciones. Por defecto es in, pero out,
buffer, e inout tambin son vlidos.
-Una funcin no tiene efectos colaterales, pero un procedimiento s, es decir, puede provocar
cambios en objetos externos a l debido a que pueden cambiar las seales aunque no se hubiera
especificado en el argumento. Es decir, en los procedimientos se permite realizar asignaciones sobre
seales declaradas en la arquitectura y, por tanto, externas al procedimiento.
-Las funciones, como devuelven un valor, se usan en expresiones, mientras que los
procedimientos se llaman como una sentencia secuencial o recurrente.
-La funcin debe contener la palabra clave return seguida de una expresin puesto que siempre
devuelve un valor, mientras que en el procedimiento no es necesario.

Carlos Medrano, E.U. Politcnica de Teruel - 19 -


VHDL- I. Microelectrnica. Curso 01/02

-Una funcin jams puede tener la instruccin wait, mientras que un procedimiento s.
-En las funciones es necesario especificar qu tipo de objeto se devuelve. Como las funciones
siempre devuelven algo, esto implica que debe existir una instruccin return en el interior del
cuerpo de la funcin, seguida de una expresin, que es precisamente lo que se devuelve. El uso de
return en procedimientos es posible, pero no lleva una expresin puesto que los procedimientos no
devuelven nada. Simplemente, interrumpe la ejecucin del procedimiento.
-Las funciones pueden definirse en la parte de declaraciones de una arquitectura, en cuyo caso la
definicin de la funcin sirve como declaracin de la funcin. Este es el ejemplo que se muestra
ms abajo. Otra manera de definirlas es declararlas en un paquete "package", incluyendo la
definicin de la funcin en el cuerpo del paquete "package body". De esta forma, la definicin de
la funcin ser visible a cualquier programa que utilice la orden use con el nombre del package
correspondiente. Lo mismo se aplica para los procedimientos.

Ejemplos:

El primer ejemplo es una clula sumadora de un bit construida con ayuda de una funcin,
llamada majority. Esta funcin necesita tres parmetros, y da como resultado un bit.

entity full_add is port(


a,b,carry_in: in bit;
sum, carry_out: out bit);
end entity;

architecture archfull_add of full_add is


function majority (a,b,c: bit) return bit is
begin
return ((a and b) or (b and c) or (c and a));
end majority;

begin
sum<=a xor b xor carry_in;
carry_out<= majority(a,b,carry_in);
end architecture;

El segundo ejemplo es una puerta or por procedimiento. Un procedimiento define una puerta or.
Despus, se llama a este procedimiento para realizar la puerta or en el programa principal.

entity or_con_procedimiento is port(


a,b: in bit;
z: out bit);
end entity;

architecture arch of or_con_procedimiento is


procedure dff (variable x1,x2:in bit;
variable y: out bit) is
begin
y:=x1 or x2;
end procedure;

begin

p: process(a,b)
variable va,vb,vz: bit;
begin
va:=a;vb:=b;
dff (va,vb,vz);

Carlos Medrano, E.U. Politcnica de Teruel - 20 -


VHDL- I. Microelectrnica. Curso 01/02

z<=vz;
end process;

end architecture;

En MaxPlusII los procedimientos deben ser llamados con variables, por lo que tambin deben
tener como parmetros variables. Por ello, el clculo de la puerta or se realiza a travs de variables.
En otros entornos informticos esto no es necesariamente as. Los procedimientos en VHDL no son
algo tan usado como en otros lenguajes como el Pascal. La forma "natural" de hacer subprogramas
en VHDL es mediante el uso de componentes.

4.2. Bibliotecas, paquetes y unidades.

Para organizar ciertos diseos conviene definir ciertos elementos en una biblioteca, que luego se
usar en el programa principal. En la biblioteca se pueden incluir los ficheros de algunos elementos,
que incluyan las entidades y arquitecturas. Se incluyen tambin los paquetes ("packages"). Los
paquetes permiten introducir componentes (cuya definicin de entidad y arquitectura puede estar en
otro fichero), tipos, funciones y procedimientos. Tienen una parte declarativa y otra descriptiva. Por
ejemplo, las sentencias que estn casi siempre a principio de todo programa son:

library ieee;
use ieee.std_logic_1164.all;

Esto indica el uso de la librera "ieee"; dentro de ella se usa el paquete "std_logic_1164"
(sentencia use); y dentro del paquete se usan todos los elementos (".all"). Si se necesitase slo uno,
bastara poner el nombre del elemento.
La forma concreta de organizar los directorios y ficheros depende de la herramienta informtica
concreta que usemos.

Por ejemplo, en MaxPlus II, supongamos que queremos construir realmente el ejemplo descrito
en el apartado 3.3 sobre la descripcin estructural de programas. All se definieron dos componentes
and3 y orn. Cada uno puede estar en su fichero .vhd, "and3.vhd" y "orn.vhd". Colocamos ambos
ficheros en un directorio, por ejemplo, en el directorio "c:\ejemplo". Compilamos cada uno de ellos
por separado, como cualquier otro programa. Basta hacer una compilacin funcional (con el
compilador activado, Processing/Functional SNF extractor), sin especificar una PLD concreta.
Despus habra que hacer el paquete correspondiente:
library ieee;
use ieee.std_logic_1164.all;

package puertas is

component or_de_n generic(n: integer:=2);


port(
a: in std_logic_vector(n-1 downto 0);
y: out std_logic);
end component;

component and_de_3 port(


a,b,c: in std_logic;
y: out std_logic);
end component;
end package;

Carlos Medrano, E.U. Politcnica de Teruel - 21 -


VHDL- I. Microelectrnica. Curso 01/02

El texto del package se guardara en un fichero puerta.vhd, y se compilara (el compilador


reconoce que es un paquete y acta en consecuencia).

Si ahora queremos compilar un programa principal usando and3 y orn, una vez que est escrito
deberamos hacer lo siguiente antes de compilarlo:

a) En el editor de texto, en options- user libraries, se debe dar el "path" al directorio donde estn
los bloques y el package. En nuestro caso sera "c:\ejemplo"
b) Con el compilador activo, en interfaces-VHDL Netlist reader settings se le da el nombre a la
librera y otra vez el "path" al directorio donde se encuentre. El nombre de la librera debe coincidir
con el encabezamiento asociado a library en el programa principal. En el ejemplo del apartado 3.3.
sera milibrera. Es independiente del nombre del directorio donde hayamos compilado el paquete.
c) Ya podemos compilar el programa principal, que deber reconocer la nueva librera.

Las libreras existentes en MaxPlus II son las siguientes, segn la ayuda on-line del propio
programa:

File Package Library Contents


maxplus2.vhd maxplus2 altera MAX+PLUS II primitives, macrofunctions, and selected
megafunctions supported by VHDL.

megacore.vhd megacore altera Pre-tested megafunctions consisting of several different


design files.
std1164.vhd std_logic_1164 ieee Standard for describing interconnection data types for VHDL
std1164b.vhd modeling, and the STD_LOGIC and
STD_LOGIC_VECTOR types.
lpm_pack.vhd lpm_components lpm LPM megafunctions supported by VHDL
arith.vhd std_logic_arith ieee SIGNED and UNSIGNED types, arithmetic and comparison
arithb.vhd functions for use with SIGNED and UNSIGNED types, and
the conversion functions CONV_INTEGER,
CONV_SIGNED, and CONV_UNSIGNED.
signed.vhd std_logic_signed ieee Functions that allow MAX+PLUS II to use
signedb.vhd STD_LOGIC_VECTOR types as if they are SIGNED types.
unsigned.vhd std_logic_unsigned ieee Functions that allow MAX+PLUS II to use
unsignedb.vhd STD_LOGIC_VECTOR types as if they are UNSIGNED
types.

Algunas de estas libreras ofrecen funciones tiles. Destacamos por su especial inters:

a) operadores sobrecargados. Se llama as a la ampliacin de una funcin u operador, para


admitir otros tipos de entrada. Por ejemplo, el operador "+" slo est definido para operar con
enteros. Si queremos sumar una cadena de bits y un entero, podemos incluir la librera que incluye
la definicin de la funcin "+" ampliada. En MaxPlusII, el paquete std_logic_arith de la librera ieee
incluye la definicin del tipo unsigned (cadena de bits entendida como un nmero positivo o cero),
as como la funcin "+" suma de un unsigned y un entero. Tambin se pueden sumar
std_logic_vector y enteros, si se incluyen tanto el paquete mencionado arriba como el paquete
std_logic_unsigned, que permite en ocasiones tratar al std_logic_vector como un unsigned.
Es interesante tambin la posibilidad de cambio de tipo: paso a entero, a unsigned, a signed o a
std_logic. Para ms informacin, leer la ayuda on line acerca de "conversion functions".

Carlos Medrano, E.U. Politcnica de Teruel - 22 -


VHDL- I. Microelectrnica. Curso 01/02

b) Mdulos parametrizados, LPM ("library of parametrized modules). Se trata de componentes


"ya hechos" que se pueden llamar mediante la orden port map. La ventaja que presentan es la gran
optimizacin a la que dan lugar durante la compilacin y sntesis en una PLD.

MAX+PLUS II offers a variety of megafunctions, including LPM functions and other


parameterized functions. Megafunctions are listed here by function. Functions indicated by an
asterisk (*) are provided for backward compatibility only.

Gates

lpm_and lpm_inv
lpm_bustri lpm_mux
lpm_clshift lpm_or
lpm_constant lpm_xor
lpm_decode mux
busmux

Arithmetic Components

divide* lpm_compare
lpm_abs lpm_counter
lpm_add_sub lpm_divide
lpm_mult

Storage Components

altdpram* lpm_latch
csfifo lpm_shiftreg
dcfifo* lpm_ram_dp
scfifo* lpm_ram_dq
csdpram lpm_ram_io
lpm_ff lpm_rom
lpm_fifo lpm_dff*
lpm_fifo_dc lpm_tff*

Other Functions

clklock pll ntsc

Altera also offers a variety of MegaCore/OpenCore functions. These functions are available from
Altera's world-wide web site at http://www.altera.com.

5. Ejemplos de VHDL.

Daremos a continuacin unos ejemplos de VHDL que cubran aspectos no tratados


anteriormente, pero que se encuentran a menudo en la sntesis de circuitos.

Carlos Medrano, E.U. Politcnica de Teruel - 23 -


VHDL- I. Microelectrnica. Curso 01/02

5.1. Flip-flop D sncrono.

library ieee;
use ieee.std_logic_1164.all;

entity biestD is port(


clk,d: in std_logic;
q: out std_logic);
end entity;

architecture archbiestD of biestD is


begin
p: process(clk,d)
begin
if clk'event and clk='1' then
q<=d;
end if;
end process;
end;

Es importante darse cuenta de la deteccin del flanco de reloj, caracterstica de todos los
sistemas sncronos. Dentro de un proceso, un if con clk'event (detecta cambios en clk) y clk='1'
(despus del cambio vale uno) detecta un flanco de subida del reloj. Un flanco de bajada sera if
clk'event and clk='0'.

Todo lo que venga despus de la deteccin del flanco de reloj corresponde a salidas que pasan a
travs de biestables.

5.2. F-F tipo D con puesta a cero y a uno asncronas.

library ieee;
use ieee.std_logic_1164.all;

entity biestD is port(


clk,d: in std_logic;
set,reset: in std_logic;
q: out std_logic);
end entity;

architecture archbiestD of biestD is


begin

p: process(clk,d,set,reset)
begin
if reset='1' then q<='0';
elsif set='1' then q<='1';
elsif clk'event and clk='1' then
q<=d;
end if;
end process;
end;

Hay que hacer notar que las condiciones del reset y del set van antes que la deteccin de la seal
de reloj. Por ello, son asncronas. Puedes intentar hacer un biestable con preset y puesta a uno

Carlos Medrano, E.U. Politcnica de Teruel - 24 -


VHDL- I. Microelectrnica. Curso 01/02

sncronas. Tambin puedes verificar qu es lo que ocurre si set='1' y reset='1' El biestable se pone a
cero o a uno?

5.3. Contadores.

Contador ascendente-descendente con carga paralelo sncrona y reset asncrono:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity contador is port(


clk,load,up,reset: in std_logic;
d: in std_logic_vector(7 downto 0);
q: buffer std_logic_vector(7 downto 0));
end entity;

architecture archcontador of contador is


begin

p: process(clk,d,q,load,up,reset)
begin
if reset='1' then q<=x"00";
elsif clk'event and clk='1' then
if load='1' then q<=d;
elsif up='1' then q<=q+1;
else q<=q-1;
end if;
end if;
end process;

end architecture;

Es interesante la forma de definir un contador. Al incluir el paquete std_logic_arith defino el tipo


unsigned y la operacin suma "+" de unsigned con enteros; con el paquete std_logic_unsigned se
puede tratar en ciertas situaciones un std_logic_vector como un unsigned (y sumarlo a un entero por
ejemplo). En este caso se podra haber definido directamente los vectores de entrada y salida como
unsigned y usar slo el paquete std_logic_arith.

Tambin es interesante la definicin del modo de q, como buffer. Ello es debido a que en la
ecuacin q<=q+1, q aparece a la derecha, y una seal definida como modo out no podra ser leda.
Otra manera de evitar esto, sera la creacin de una seal auxiliar en la arquitectura que
utilizaramos dentro del proceso. Una vez fuera del proceso, podemos hacer que la salida sea igual a
esa seal. De este modo, la salida nunca aparece a la derecha en una asignacin.

Recordamos tambin que si un vector es definido como (3 downto 0), el bit 0 es el menos
significativo.

Finalmente, hacemos notar tambin el uso de vectores en hexadecimal indicado por una x
delante del vector: x"00" es equivalente a 8 ceros binarios.

Un contador es tambin una mquina de estados, por lo que se puede definir como haremos en el
apartado siguiente. No obstante, esta definicin es mucho ms pesada.

Carlos Medrano, E.U. Politcnica de Teruel - 25 -


VHDL- I. Microelectrnica. Curso 01/02

5.4. Mquinas de estado.

La mquina de estado tiene una parte donde se describe la tabla de evolucin de estados, y otra
parte donde se describe las salidas. Consideremos un ejemplo: dos sensores en la va del tren
indican cuando pasa el tren por la va (la va es bidireccional). Los sensores se encuentran a ambos
lados de un cruce con una carretera. Un semforo debe ponerse en rojo cuando se detecte el paso
del tren.
library ieee;
use ieee.std_logic_1164.all;

entity semaforo is port(


rs, a,b,clk: in std_logic;
sem: out std_logic);
end;

architecture archsemaforo of semaforo is


constant size: integer:=2;
signal estado: std_logic_vector(0 to size-1);
constant e1: std_logic_vector(0 to size-1):="00";
constant e2: std_logic_vector(0 to size-1):="10";
constant e3: std_logic_vector(0 to size-1):="01";
constant e4: std_logic_vector(0 to size-1):="11";
begin
p1: process (clk,rs,estado,a,b)
begin
if rs='1' then estado<=e1;
elsif rising_edge(clk) then
case estado is
when e1 =>
if a='1' then estado<=e3;
elsif b='1' then estado<=e2;
else estado<=e1;
end if;
when e3 =>
if b='1' then estado<=e4;
else estado<=e3;
end if;
when e2 =>
if a='1' then estado<=e4;
else estado<=e2;
end if;
when e4 =>
if (a='0' and b='0') then estado<=e1;
else estado<=e4;
end if;
when others => estado<=(others=>'-');
end case;
end if;
end process;
-- decodificacion de las salidas;
with estado select
sem<='0' when e1,
'1' when others;
end archsemaforo;

Carlos Medrano, E.U. Politcnica de Teruel - 26 -


VHDL- I. Microelectrnica. Curso 01/02

Se ha definido el estado como un vector de std_logic. De esta forma, el programador elige


totalmente la codificacin del estado. La inclusin de las constantes es simplemente por motivos de
claridad, pero se podra prescindir de ellas y usar las cadenas de bits.

La funcin rising_edge() tambin detecta el flanco de subida mientras que falling_edge() detecta
el de bajada. Se aplica al tipo std_logic, pero no es aplicable al tipo bit.

Otra descripcin alternativa podra ser definir un tipo con nombres de estado, ms prximos al
lenguaje humano. Esto se hara en la arquitectura, antes del inicio (begin):

type tipoestado is (reposo, entra_por_a, entra_por_b, alejandose);


signal estado: tipoestado;

De esta forma, he creado un nuevo tipo que puede ser uno de los estados (de igual modo que el
tipo bit puede ser 1 o 0). Defino mi seal con ese nuevo tipo, y luego puedo usar esos nombres en el
programa, en lugar de cadenas de bits o nombres de constantes. La codificacin de los estados la
elegir el compilador.

5.5. Salidas triestado.

Consideremos ahora el caso de una salida triestado.


library ieee;
use ieee.std_logic_1164.all;

entity triestado is port(


enable,sel: in std_logic;
linea: in std_logic_vector(1 downto 0);
y : out std_logic);
end entity;

architecture archtriestado of triestado is


begin

y<='Z' when enable='0' else


linea(1) when sel='1' else
linea(0) when sel='0';
end architecture;

La salida en alta impedancia se indica con 'Z' (ojo, es Z, mayscula).

Una salida de un biestable no se puede definir directamente como 'Z'. Para hacer que una salida
de un registro est en alta impedancia, se puede definir una seal en la arquitectura, que sea como la
salida del registro, o que est en alta impedancia cuando se cumplan las condiciones adecuadas.

5.6. Puertos bidireccionales.

Carlos Medrano, E.U. Politcnica de Teruel - 27 -


VHDL- I. Microelectrnica. Curso 01/02

Consideremos el caso de un contador con las salidas en alta impedancia y con capacidad de
carga por los mismos pines de salida del contador.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity ldcnt is port (


clk, ld, oe: in std_logic;
count_out: inout unsigned(7 downto 0));
end ldcnt;

architecture archldcnt of ldcnt is


signal count: unsigned(7 downto 0);
begin
counter: process (clk,ld,oe,count_out,count)
begin
if (ld='1' and oe='0') then
count <= count_out;
elsif clk'event and clk='1' then
count <= count + 1;
end if;
end process counter;
count_out <= count when (oe = '1') else "ZZZZZZZZ";
end archldcnt;

Este contador se puede cargar por los mismos pines de salida (pines bidireccionales). Tales tipos
de puertos son necesariamente de tipo inout. El sistema que controla las entradas ld y oe debe hacer
que cuando se cargue un valor (ld='1'), a la vez no se habilite la salida (oe='0').

Bibliografa
K. Skahill, "VHDL for Programmable Logic", Ed. Addison-Wesley, 1996. Incluye en un CD-ROM el
programa Warp2.
F. Pardo, J.A. Boluda. "VHDL: Lenguaje para sntesis y diseo de circuitos digitales". Ed. Rama, 1999.
Incluye un CD-ROM con un simulador (Veribest) de VHDL (mximo 2000 lneas de cdigo), y una
herramienta de Altera, MaxII-Plus, aunque la versin ya est desfasada.
S. Olloz, E. Villar, Y. Torroja, L. Teres: "VHDL, lenguaje estndar de diseo electrnico", Ed. McGraw-Hill.
www.altera.com Distribuye gratis un software (Max-Plus II) que admite entrada en VHDL y en AHDL,
captura esquemtica, simulacin funcional y temporal. Cada cierto tiempo actualiza las versiones libres. Es
una herramienta mucho ms completa que Warp2.
Otras pginas Web:
http://tech-www.informatik.uni-hamburg.de/vhdl/
www.cypress.com
www.xilinx.com
www.actel.com
www.synopsis.com

Carlos Medrano, E.U. Politcnica de Teruel - 28 -

También podría gustarte