Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
El lenguaje de programación VHDL (Very High Speed Integrated Circuit Hardware Description
Languaje) es una nueva metodología de diseño de circuitos digitales. Es un lenguaje que
describe el comportamiento del circuito, es decir describe el hardware VHDL como un
lenguaje para el modelado y simulación lógica el cual posee una sintaxis amplia y flexible y
permite el modelado preciso, en distintos estilos, del comportamiento de un sistema digital
conocido, y el desarrollo de modelos de simulación.
El lenguaje VHDL es utilizado para la programación de dispositivos de lógica programable como los
FPGA y CPLD. Aunque VHDL es un lenguaje de programación como cualquier otro en cuanto a que
tiene las estructuras básicas de programación, también es importante mencionar que la ejecución
de los códigos en VHDL no es igual a la ejecución de los códigos en microprocesadores y
microcontroladores.
Una entidad es la abstracción de un circuito, ya sea desde un complejo sistema electrónico o una
simple puerta lógica. La entidad únicamente describe la forma externa del circuito, en ella se
enumeran las entradas y las salidas del diseño. Una entidad es análoga a un símbolo esquemático
en los diagramas electrónicos, el cual describe las conexiones del dispositivo hacia el resto del
diseño.
entity nombre is
end nombre;
Los puertos pueden ser de entrada in, salida out, entrada-salida inout o buffer. Los puertos de
entrada sólo se pueden leer y no se puede modificar su valor internamente en la descripción del
comportamiento del circuito (architecture), sobre los puertos de salida sólo se puede escribir, pero
nunca tomar decisiones dependiendo de su valor (esto implica una lectura). Si es estrictamente
necesario escribir sobre un puerto a la vez que se tiene que tener en cuenta su valor el tipo sería
inout o buffer.
Además, en la entity se pueden definir unos valores genéricos (generic) que se utilizarán para
declarar propiedades y constantes del circuito, independientemente de cual sea la arquitectura. A
nivel de simulación utilizaremos generic para definir retardos de señales y ciclos de reloj, estas
definiciones no serán tenidas en cuenta a nivel de síntesis. También se puede utilizar generic para
introducir una constante que será utilizada posteriormente en la architecture, utilizaremos esa
constante para hacer nuestro circuito más general. Por ejemplo, podemos definir el
comportamiento de un banco de registros teniendo en cuenta que puede tener cualquier número
de registros, fijando el número de registros particular que queremos simular e implementar a
través de una constante del generic. Esto implica que en toda la parte de nuestro código (el que
vamos a escribir dentro de architecture) donde haga falta el número de registros utilizaremos el
nombre de la constante definida en generic, de manera análoga a como se haría en cualquier
lenguaje de programación convencional. La sentencia generic no es necesaria, en caso de que no
vayamos a utilizarla puede desaparecer de la entity.
A
F Y
B
entity F is
end F;
DECLARACIONES DE ENTIDADES
Para la declaración de una entidad hay que definir un nombre y también el nombre de los puertos
de I/O que utilizara el diseño, a continuación, mostramos un esquema básico para la declaración
de entidades. Las entidades que usaremos inicialmente serán entidades en donde solo se
declararán puertos solamente.
Dentro de las declaraciones de las entidades, hay que realizar la declaración de los puertos
utilizados en el diseño del dispositivo. Los puertos se declaran utilizando el comando port en la
cual se debe definir los nombres, modo y tipos de las señales utilizadas como I/O.
Las declaraciones de los puertos se realizan dentro de la instrucción port la cual debe terminar en
un carácter de punto y coma; además de que cada declaración de un puerto debe terminar
también en un carácter de punto y coma, con excepción de la última declaración en donde no es
necesario. La declaración de los puertos consta de un nombre del puerto seguido de un carácter
de dos puntos (:), luego se debe especificar el modo del puerto y el tipo de dato. A continuación,
se listan los modo y tipos de datos más utilizados para la declaración de puertos.
In: Define un puerto como entrada de datos del dispositivo. Solo funciona como
entrada no puede ser utilizado como puerto bidireccional.
Out: Define un puerto como salida de datos provenientes del dispositivo. No puede ser utilizado
como un puerto bidireccional. Este modo solo permite sacar datos fuera del dispositivo; el
dispositivo no puede saber que dato se encuentra en el puerto en un momento determinado ya
que este modo no permite la retroalimentación de la señal.
InOut: Define un puerto como un puerto bidireccional o sea que el puerto es de entrada y
salida; este modo permite que el dispositivo pueda leer el valor colocado como dato de salida este
modo si permite la retroalimentación.
Buffer: Define un puerto como salida, pero ofrece la posibilidad de que el dispositivo pueda
leer el dato colocado en el puerto. El puerto no es de entrada es de solo salida, pero permite
la retroalimentación.
BIT y BIT_VECTOR: Este tipo de dato está definido en el estándar original de VHDL, el IEEE 1076 el
cual ya tiene varias versiones y también está definido en el estándar IEEE 1164. Estos datos
soportan valor lógico de '0' y '1'. El tipo BIT_VECTOR es un arreglo del tipo BIT cuya dimensión la
define el programador en el momento de la declaración del puerto.
Aunque los STD_LOGIC soportan estos nuevos valores, los únicos que se pueden considerar
verdaderamente útiles son los dos primeros además de los '0' y '1' que ya existían desde los tipos
BIT. Al igual que los tipos BIT los tipos STD_LOGIC, pueden definir arreglos de vectores, que
facilitan el trabajo con puertos que guardan alguna relación.
STD_ULOGIC: Este tipo de dato es igual que el STD_LOGIC, con la diferencia de que, en el
STD_LOGIC se contempla la utilización de las funciones de resolución que se emplean cuando dos
fuentes de señales tratan de dar valor a una sola señal; por ejemplo la salida de dos elementos de
tres estados que se conectan a una misma entrada, una salida puede ser de alta impedancia y
puede tener un valor lógico; entonces cual debe ser el valor que obtenga la señal de entrada a la
que se le conectaron las dos fuentes de señales; esta decisión se resuelve mediante una función
de resolución, los tipos de datos STD_LOGIC permiten el uso de funciones de resolución mientras
que los tipos de datos STD_ULOGIC no lo permiten, esta es la principal diferencia; por lo demás
aspectos son iguales soportan los mismo valores de datos.
Ejemplo 1
Del diagrama esquemático del ejemplo 1 vemos que para la declaración de la entidad
correspondiente al convertidor de BCD a 7 seg vemos que la entidad tiene 4 entradas y 7 salidas. Si
a la entidad le podemos como nombre BCD7seg la declaración sugerida seria el código que
mostramos a continuación.
Declaración de entidad:
Nombre: BCD7seg
Código necesario para la declaración de la entidad del ejemplo 1
En esta declaración de entidad de vemos que tanto las señales de entradas como las de salidas
fueron declaradas utilizando el tipo de datos STD_LOGIC, lo que implica que las señales serán
trabajadas dentro de la arquitectura bit a bit, esto puede ser útil en algunos casos y en otros no
tanto. Es por eso que expondremos otra posible declaración de la entidad de este mismo ejemplo,
pero esta vez usando como tipo de datos STD_LOGIC_VECTOR.
En esta ocasión se ha utilizado los arreglos vectoriales por lo que solo se necesitan dos
declaraciones de puertos lo que simplifica el desarrollo del código.
Ejemplo 2
Para esta entidad es evidente que los puertos correspondientes a los números de 4 bits es
conveniente utilizar como tipo de dato a los datos STD_LOGIC_VECTOR, este mismo tipo de datos
será utilizado para el puerto de salida correspondiente al resultado de la suma; para el dato del bit
de acarreo de entrada y el bit de acarreo de salida se usaran los STD_LOGIC.
Aunque en la figura 5 el código que se utiliza para la declaración de la entidad se utilizan como
tipos de datos STD_LOGIC y STD_LOGIC_VECTOR de manera combinada, es importante señalar
que el programador puede escoger como tipo de datos para todas las señales de entrada el
STD_LOGIC que es un tipo de dato de un solo bit; la definición del tipo de dato a utilizar para la
declaración de los puertos dependerá de la destreza y estilo de programación.
Ejemplo 3
En este caso es necesario que el dispositivo pueda leer el valor presente en el puerto de salida que
representa la cuenta, es por eso que el puerto Do debe ser del modo inout, los puerto CLK y RST
son puertos del modo in y del tipo STD_LOGIC.
-- declaraciones de la arquitectura:
-- tipos
-- señales
-- componentes
begin
-- código de descripción
-- instrucciones concurrentes
-- ecuaciones booleanes
-- componentes
process (lista de sensibilidad)
begin
-- código de descripción
Desde begin hasta end escribiremos todas las sentencias propias de VHDL, pero no todas pueden
utilizarse en cualquier parte del código. Así pues, aquellas sentencias de VHDL que tengan definido
un valor para cualquier valor de la entrada (y que nosotros denominamos sentencias
concurrentes) podrán ir en cualquier parte del código, pero fuera de la estructura process. Aunque
no es el fin de este manual, puede afirmarse que todas las sentencias concurrentes se traducirán
en subcircuitos combinacionales. También fuera de la estructura process, se instanciarán los
componentes, subcircuitos ya definido sutilizados por el circuito actual, indicando cuáles son sus
entradas y sus salidas de entre las señales del circuito del que forman parte.
El process es una estructura particular de VHDL (que se describe con mucho más detalle más
adelante) que se reserva principalmente para contener sentencias que no tengan obligatoriamente
que tener definido su valor para todas las entradas (el ejemplo más común es una estructura if-
else incompleta). Esto obliga a que la estructura process almacene los valores de sus señales y
pueda dar lugar (no siempre) a subcircuitos secuenciales. Además, en simulación sólo se ejecutan
las sentencias internas a esta estructura cuando alguna de las señales de su lista de sensibilidad
cambia de valor.
Como hemos visto los modelos VHDL están formados por dos partes: la entidad (entity) y la
arquitectura (architecture); es en esta última donde se escriben las sentencias que describen el
comportamiento del circuito, a este modelo de programación en VHDL se le suele denominar
behavioral.
-- señales
begin
-- sentencias concurrentes process (lista de sensibilidad) begin
-- sentencias secuenciales
-- sentencias condicionales
end process
end architecture circuito;
-Sentencias de asignación que deben realizarse siempre, así como sentencias concurrentes.
iii) -Uno a varios process que tienen en su interior sentencias condicionales y/o asignaciones a
señales que dan lugar a hardware secuencial.
iv)
SENTENCIAS CONCURRENTES
Las sentencias concurrentes son sentencias condicionales que tienen al menos un valor por
defecto para cuando no se cumplen ninguna de las condiciones. Aunque podría utilizarse una
sentencia común como un if con obligación de else, los desarrolladores de VHDL han preferido
utilizar dos sentencias particulares:
WHEN – ELSE
...
valor_por defecto;
En esta sentencia siempre modificamos el valor de una misma señal, pero las condiciones pueden
ser independientes (actuar sobre distintas señales cada una), dónde la colocación de las
condiciones indica la preferencia de unas sobre otras, es decir, la condición 1 tiene preferencia
sobre el resto, la condición 2 sobre todas menos la 1 y así sucesivamente.
-- Ejemplos when-else
---------------------------------------------
C <= “00” when A = B else “01” when A < B else “10”;
---------------------------------------------
C <= “00” when A = B else
“10”;
---------------------------------------------
Esta sentencia es menos general que la anterior. En este caso se modificará el valor de una señal
dependiendo de los valores de una señal condición, aparecerán como máximo tantas líneas como
valores posibles pueda tener la señal condición.
---------------------------------------------
-- Ejemplo with-select
---------------------------------------------
with entrada select
----------------------------------------------
Desde un punto de vista de HW estas dos sentencias dan como resultado HW convencional puro,
es decir, puertas lógicas, multiplexores, decodificadores …
Sentencias Condicionales
VHDL permite utilizar otro tipo de sentencias condicionales más parecidas a los lenguajes de
programación usados. Todas estas sentencias como se explicará la sección 3.3 tiene que ir
obligatoriamente dentro de un proceso. Las sentencias condicionales más comunes en VHDL son
las siguientes:
IF – THEN – ELSE
begin
if condición then
-- asignaciones
-- asignaciones
else
-- asignaciones
end if;
end process;
---------------------------------------------
-- Ejemplo
---------------------------------------------
process (control, A, B)
begin
if control = “00” then
resultado <= A + B;
resultado <= A – B;
else
resultado <= A;
end if;
end process;
----------------------------------------------
begin
case señal_condición is
Dentro de las asignaciones pueden parecer también sentencias if-else. Es necesario que aparezca
en la estructura when others, pero no es necesario que tenga asignaciones, se puede dejar en
blanco.
---------------------------------------------
-- Ejemplo
---------------------------------------------
process (control, A, B)
begin
case control is when “00” =>
FOR – LOOP
begin
for loop_var in range loop
-- asignaciones
---------------------------------------------
-- Ejemplo
---------------------------------------------
process (A)
begin
for i in 0 to 7 loop
WHILE – LOOP
process (lista de sensibilidad)
begin
while condición loop
-- asignaciones
---------------------------------------------
-- Ejemplo
---------------------------------------------
process (A)
variable i: natural := 0;
begin
while i < 7 loop B(i+1) <= A(i); i := i+1;
SIMULACIÓN EN VHDL
VHDL realiza la simulación siguiendo la técnica de simulación por eventos discretos (Discrete Event
Time Model). Esta es una técnica que permite avanzar el tiempo a intervalos variables, en función
de la planificación de ocurrencia de eventos (cambio de valor de alguna señal). Esto significa que
no se simula el comportamiento del circuito pico- segundo a pico-segundo, si no desde que ocurre
un evento hasta el siguiente, donde puede pasar un pico-segundo o varios segundos. Durante el
intervalo de tiempo en el que no se produce ningún evento se mantiene el valor de todas las
señales.
FASES DE LA SIMULACIÓN
Fase 0: la simulación comienza en la fase de inicialización donde a las señales se les asignan unos
valores iniciales y se pone el tiempo a cero. La asignación se hace rellenando una lista de eventos
para el instante t = 0.
Fase 1: todas las transiciones planificadas para ese tiempo son ejecutadas. Es decir, se ejecuta el
código ordenadamente teniendo en cuenta cuales son las señales que se han modificado,
cumpliendo las normas de ejecución explicadas para los procesos.
Fase 2: Las señales que se han modificado como consecuencia de las transiciones planificadas en
el instante t se escriben en la lista de eventos planificándose para el instante t + δ. Donde δ es un
instante infinitesimal.
Se repiten la fase 1 y 2 hasta que no existen más transiciones. Además, en los instantes entre
eventos se mantienen los valores de las señales.
Un contador es un circuito que genera un número nuevo cada ciclo de reloj, En VHDL tenemos que
escribir expresamente que se quiere un número nuevo cada ciclo de reloj, como muestra el
siguiente código:
entity contador is
end contador;
begin
begin
if (reset = '1')
interna <= “0000”;
end circuito;
La señal interna está definida como un std_logic_vector(3 downto 0), aplicando las definiciones del
estándar del IEEE obtenemos que “1111” + 1 = “0000”, por lo que el código anterior representa un
contador que cuenta de 0 a 15 y vuelta a empezar.
[1]
http://ciecfie.epn.edu.ec/wss/VirtualDirectories/80/pag_personales/PChico/Materiales_DLP/semi
nario_folleto.pdf
[2] https://eprints.ucm.es/26200/1/intro_VHDL.pdf
[3] https://www.editorialpatria.com.mx/pdffiles/9786074386219.pdf
[4] https://sites.google.com/site/logicaprogramable/vhdl/lenguaje-vhdl
[5]
http://www.profesores.frc.utn.edu.ar/electronica/tecnicasdigitalesi/pub/file/Publicaciones/VHDL.
pdf
[6] https://www.youtube.com/watch?v=co3YZcOwRAc
[7] https://www.youtube.com/watch?v=AZWH6ApZxnA