Está en la página 1de 25

TECNOLÓGICO NACIONAL DE MÉXICO

CAMPUS MOTUL

SEMESTRE 2022B
PROFESOR: I.E. OMAR EDUARDO BASTO UC, M.I.

1
Ingeniería Electrónica
Diseño Digital con VHDL
Unidad No 1. “Programación VHDL”
Resumen No. 1 “Conceptos básicos”

Nombre del Alumno: Julian Javier Canul Pool Semestre: 5A


Nombre del Profesor: OMAR EDUARDO BASTO UC, M.I. Fecha: 18/09/2022
Calificación: Firma de conformidad:

(30 Puntos)

Competencia:

RÚBRICA Y NOTAS
INDICADOR VAL PTS
Emplea el formato propuesto sin alterar párrafos, tipos de letra,
espaciamientos, viñetas, numeraciones 10 0
Índice completo 10 0
Introducción redactada clara y coherentemente 10 0
Indica el objetivo general de la actividad 10 0
No hay plagios de internet y/o entre pares 10 0
Redacta el resumen con claridad, exactitud, coherencia y fiel a las ideas del
autor 10 0
Redacta sus con conclusiones de manera clara y coherente acorde al tema
tratado 10 0
Pone referencias bibliográficas (mínimo seis autores) 10 0
Puntuación y ortografía 10 0
Entrega a tiempo 10 0
TOTAL 100 0

NOTA:
Guardar este documento con la siguiente nomenclatura:
apellido_nombre_parcial_tema_actividad_carrera_semestre

2
DESCRIPCIÓN DE LA ACTIVIDAD A REALIZAR
OBJETIVO GENERAL:
• Desarrolla y simula estructuras avanzadas de un programa en VHDL de circuitos lógicos
secuenciales síncronos para la programación e implementación de FPGA´s o CPLD´s en
aplicaciones reales.
• Conoce y desarrolla los componentes que conforman las arquitecturas básicas de un
microprocesador.
OBJETIVO (COMPETENCIA) ESPECÍFICO:
• Desarrolla y simula estructuras avanzadas de un programa en VHDL de circuitos secuenciales
síncronos para la programación de CPLD´s o FPGA´s.
QUÉ HACER:
Realiza una práctica simulada con las funciones booleanas programadas en simulador, Arduino,
display de 7 segmentos y cuatro interrumptores. La práctica simulada debe convertir de binario a
hexadecimal en el display de 7 segmentos mediante sus funciones booleanas.
Elabora un resumen con los siguientes conceptos (TODOS):
1.1. Elementos del lenguaje VHDL.
1.1.1. Elementos sintácticos del VHDL.
1.1.2. Operadores y expresiones en VHDL.
1.2. Declaraciones de objetos.
1.2.1. Declaración de señales
1.2.2. Declaración de ficheros.
1.3. Declaraciones concurrentes.
1.3.1. Declaración de arquitectura de flujo de datos.
1.3.2. Ejemplos de descripción flujo de datos.
1.4. Ejemplos de declaraciones secuenciales.
1.4.1. Ejemplos de diagramas de máquinas de estado.
1.5. Funciones y subprogramas.
1.5.1. Declaración de procedimientos y funciones.
1.5.2. Subprogramas.
1.5.3. Paquetes.
1.5.4. Bibliotecas
1.6. Programación de FPGA´s ó CPLD’S en diferentes aplicaciones

EN LAS SIGUIENTES HOJAS ENCONTRARÁ UNA DESCRIPCIÓN DE QUÉ ES UN


RESUMEN, QUÉ CONTIENE Y SUS PAUTAS.

EN LAS HOJAS POSTERIORES YA SE INCLUYEN LOS ENCABEZADOS DE CADA UNA


DE LAS PAUTAS DEL RESUMEN.

3
FORMATO PROPUESTO PARA LA ELABORACIÓN DE
RESÚMENES
Resumen
Documento escrito que refleja las ideas principales del autor de forma condensada, precisa y
objetiva sin interpretación crítica.

¿Cómo elaborar un resumen?

1. Identifica el objetivo de la actividad y redáctala a tu criterio (por ejemplo:


Objetivo: Este documento pretende describir y hacer entendible el concepto de
cálculo integral, indicando sus aplicaciones en la vida cotidiana y resaltando la
importancia de la herramienta en la ingeniería).
2. Identifica el tema central de cada párrafo.
3. Identifica aquellas frases y el material redundante que ayuden a comprender el
tema principal, pero que se podría prescindir de ellos y elimínalos. Cuando
encuentras expresiones como “en otras palabras” o “es decir” muy
probablemente encontrarás después una frase redundante.
4. Agrupa información similar o ideas comunes que puedas representar con
menos palabras y sustitúyelas.
5. Redacta tu resumen, el cual debe conservar la idea original del texto,
conteniendo las ideas sin alterarlas NI HACER COPIA Y PEGA DE PÁGINAS
DE INTERNET.

¿Qué debe contener mi resumen?

Texto de tamaño 11, letra Arial, justificado, con márgenes por defecto (los que trae Microsoft
Word por defecto para hojas tamaño carta o letter), con el mismo sangrado y espaciado de este texto
(tome como base este documento respetando su encabezado y pie de página).

La estructura es la siguiente:

• Portada (la que se incluye en este documento rellenando los espacios en blanco, sustituyendo
las líneas por el texto correspondiente).
• Índice (cuadro de contenido).
• Introducción que explique a vista rápida el contenido general del escrito.
• Desarrollo observando los puntos 1 al 5 citados arriba, evitando plagios de autores o de otros
alumnos. El plagio invalida automáticamente el trabajo. Si se detecta que el trabajo corresponde
a otro compañero, se invalidan en automático los trabajos. Extensión mínima de tres cuartillas
sin imágenes y de cinco con imágenes.
• Conclusiones individuales o grupales en caso de trabajo en grupo, anotando el nombre
empezando por apellidos de cada integrante.

4
• Citar fuentes de manera correcta en cada párrafo, considerando que se debe consultar y citar
mínimo 6 autores, dos de internet, dos de artículos y dos de bibliografías.

¡Empiece a desarrollar el suyo en las siguientes hojas!

FIN DE LA
DESCRIPCIÓN DE
RESUMEN

5
ÍNDICE

La una práctica simulada ....................................................................................................................... 7


1.1. Elementos del lenguaje VHDL. ..................................................................................................... 10
1.1.1. Elementos sintácticos del VHDL. ............................................................................................ 10
1.1.2. Operadores y expresiones en VHDL. ..................................................................................... 10
OPERADOR DE CONCATENACIÓN. .......................................................................................... 10
OPERADORES ARITMÉTICOS. .................................................................................................. 11
OPERADORES DE DESPLAZAMIENTO. .................................................................................... 11
OPERADORES RELACIONALES. ............................................................................................... 12
OPERADORES LÓGICOS. .......................................................................................................... 12
1.2. Declaraciones de objetos. ......................................................................................................... 12
1.3. Declaraciones concurrentes. ......................................................................................................... 14
1.3.1. Declaración de arquitectura de flujo de datos. ........................................................................ 14
Sentencias Concurrentes.............................................................................................................. 14
Descripción de comportamiento .............................................................................................. 16
PROCESS .................................................................................................................................... 16
1.3.2. Ejemplos de descripción flujo de datos. .................................................................................. 17
1.5. Funciones y subprogramas. .......................................................................................................... 19
1.5.1. Declaración de procedimientos y funciones. ........................................................................... 19
1.5.2. Subprogramas. ....................................................................................................................... 20
1.5.3. Paquetes. ............................................................................................................................... 21
Definición de paquetes ............................................................................................................... 21
1.5.4. Bibliotecas .............................................................................................................................. 22
Librería ieee.................................................................................................................................. 23
1.6. Programación de FPGA´s ó CPLD’S en diferentes aplicaciones ................................................... 24
CONCLUSIONES PERSONALES ....................................................................................................... 24
REFERENCIAS BIBLIOGRÁFICAS ..................................................................................................... 24

6
INTRODUCCIÓN
En este trabajo en sus páginas encontraras un resumen de investigación tomada de internet y de
algunos libros además de una práctica que se llevó a cabo en clase, el cual fue un contador de binario
a hexadecimal. Bueno ahora te toca a ti cursarle el mayor provecho a este trabajo.

OBJETIVO GENERAL
Desarrolla y simula estructuras avanzadas de un programa en VHDL de circuitos lógicos secuenciales
síncronos para la programación e implementación de FPGA´s o CPLD´s en aplicaciones reales.

Conoce y desarrolla los componentes que conforman las arquitecturas básicas de un microprocesador.

DESARROLLO
La una práctica simulada con las funciones booleanas programadas en simulador,
Arduino, display de 7 segmentos y cuatro interrumptores. La práctica simulada debe convertir de binario
a hexadecimal en el display de 7 segmentos mediante sus funciones booleanas.

Para poder realizar esta práctica se creo una tabla de verdad que me ayudara a decidir que led del
display de 7segmentos se debe de usar y así formar el número.

# A B C D a b c d e f g
0 0 0 0 0 1 1 1 1 1 1 0
1 0 0 0 1 0 1 1 0 0 0 0
2 0 0 1 0 1 1 0 1 1 0 1
3 0 0 1 1 1 1 1 1 0 0 1
4 0 1 0 0 0 1 1 0 0 1 1
5 0 1 0 1 1 0 1 1 0 1 1
6 0 1 1 0 1 0 1 1 1 1 1
7 0 1 1 1 1 1 1 0 0 0 0
8 1 0 0 0 1 1 1 1 1 1 1
9 1 0 0 1 1 1 1 0 0 1 1
A 1 0 1 0 1 1 1 0 1 1 1
B 1 0 1 1 0 0 1 1 1 1 1
C 1 1 0 0 1 0 0 1 1 1 0
D 1 1 0 1 0 1 1 1 1 0 1
E 1 1 1 0 1 0 0 1 1 1 1
F 1 1 1 1 1 0 0 0 1 1 1

7
Despues con ayuda de la siguiente aplicación se introducen los datos de la tabla verdad ya generado.
Ya que lo que haces proporcionarnos las compuestas logicas para poder tener las salidad que indica la
tabal de verdad.

Una vez teniendo el código VHDL generado este se procedió a programar el Arduino.
Declarando las variables de entradas y salida.

Después de declarar las variables se colocaron las fórmulas generadas en el programa de sistemas
combinacionales, y almacenar las entradas.

8
Por ultimo se comprueba que funciona el contador de binario a hexadecimal.

9
Elabora un resumen con los siguientes conceptos (TODOS):

1.1. Elementos del lenguaje VHDL.


1.1.1. Elementos sintácticos del VHDL.

Comentarios. Cualquier línea que empieza por dos guiones “-- “es un comentario.

Símbolos especiales. De un solo carácter: + - / * ( ) . , : ; & ´ “ < > = | # De dos caracteres: ** => := /=
>= <= --

Identificadores. Se utilizan para dar nombre a variables, señales, nombres de rutinas, etc. puede ser
cualquier nombre compuesto por letras y números, incluyendo el símbolo del subrayado “_”; nunca
puede contener símbolos especiales o palabras claves del VHDL ni empezar por un número o
subrayado; tampoco se permite que el identificador acabe con un subrayado ni que haya dos seguidos.
Las mayúsculas o minúsculas son consideradas iguales.

Números. Cualquier número se considera que se encuentra en base 10. Se admite la notación
científica convencional para números en punto flotante. Es posible manejar números en otras bases
utilizando el símbolo del sostenido “#”. Ejemplo: 2#11000100# y 16#c4# representan el entero 196.

Caracteres. Es cualquier letra o carácter entre comillas simples: ´1´, ´3´, ´t´.

Cadenas. Son un conjunto de caracteres englobados por comillas dobles: “esto es una cadena”.

Cadenas de bits. Los tipos bit y bit_vector son de tipo carácter y matriz de caracteres
respectivamente. En VHDL se tiene una forma elegante de definir números con estos tipos y es
mediante la cadena de bits. Dependiendo de la base en que se especifique el número, se puede poner
un prefijo B (binario), O (octal), o X (hexadecimal). Ejemplos: B”11101001”, O”126”, X”FE”.

Palabras reservadas. Son aquellas que tienen un significado especial. Son las instrucciones, órdenes
y elementos que permiten definir sentencias. La tabla 1 muestra las palabras clave del VHDL`87 y la
tabla 2 las que se agregaron en el VHDL`93.

1.1.2. Operadores y expresiones en VHDL.

OPERADOR DE CONCATENACIÓN.

& (concatenación). Concatena matrices de manera que la dimensión de la matriz resultante es la


suma de las dimensiones de las matrices sobre las que opera. Por ejemplo, punto<=x&y construye
la matriz punto con la matriz x en las primeras posiciones y la matriz y en las últimas.

10
OPERADORES ARITMÉTICOS.

** (exponencial). Eleva un número a una potencia: 4**2 es 42

abs( ) (valor absoluto). Devuelve el valor absoluto de su argumento.


* (multiplicación). Multiplica dos números de cualquier tipo numérico.
/ (división). Funciona con cualquier dato numérico
mod (módulo). Calcula el módulo de dos números.
rem (resto). Calcula el resto de una división entera.
+ (suma y signo positivo). Indica suma o signo.
- (resta y signo negativo). Indica resta y signo negativo.

OPERADORES DE DESPLAZAMIENTO.
Estos operadores solo existen en el VHDL`93.

11
sll, srl (desplazamiento lógico, a la izquierda o a la derecha). Desplaza un vector un número de bits a
izquierda o derecha rellenando con ceros los huecos libres. Ejemplo: dato sll 2, desplaza a la izquierda
dos posiciones al vector dato, es decir, lo multiplica por 4.

sla, sra (desplazamiento aritmético a la izquierda o a la derecha). La diferencia con el anterior es que
este desplazamiento conserva el signo, es decir, conserva el valor que tiene el bit más significativo del
vector.

rol, ror (rotación a la izquierda o a la derecha). Es como el desplazamiento, pero los huecos que se
forman son ocupados por los bits que van saliendo.

OPERADORES RELACIONALES.

Devuelven siempre un valor de tipo booleano (true o false). Los tipos con los que pueden operar
dependen de la operación.

=, /= (igualdad, desigualdad). El primero devuelve true si los operandos son iguales y false en caso
contrario. El segundo indica desigualdad, así que funciona al revés. Los operandos deben ser del
mismo tipo.

<=, >, >= (menor, mayor) Tienen el significado habitual. Los tipos de datos que pueden manejar son
escalares o matrices de una sola dimensión de tipos discretos.

OPERADORES LÓGICOS.

1.2. Declaraciones de objetos.


1.2.1. Declaración de señales

Las señales se declaran igual que las constantes y variables, con la diferencia de que
las señales pueden ser normal, register o bus. Si en la declaración no se especifica nada,
se entiende que la señal es de tipo normal; para que sea de tipo bus o register se debe declarar
explícitamente con las palabras clave bus o register.

Una señal no es lo mismo que una variable, La señal no es exactamente un objeto


del lenguaje que guarda un valor, sino que lo hace en realidad es guardar un valor (o varios
cómo se verá más adelante) y hacerlo visible en el momento adecuado. Esto es, se puede
decir que la señal tiene dos partes, una donde se escribe y que almacena el valor y otra que
se leé y que no tiene por qué coincidir con lo que se acaba de escribir.

Internamente se establece una conexión entre la parte que se escribe y la que se lee.
Es posible en VHDL desconectar una parte de la otra, de manera que al leer la señal no se
tenga acceso a lo que se escribió. La desconexión de una señal se hace asignándole el valor
null. La diferencia entre una señal normal, register o bus viene del comportamiento al
desconectarse. Las de tipo normal no se pueden desconectar. Las de clase bus y register se
pueden desconectar, ya que o bien se trata de señales de tipo resuelto, que admiten varios o
ningún valor escrito a un tiempo, o bien de tipo vigiladas, que tienen una condición de

12
desconexión. La diferencia entre ambas es que la señal de tipo bus tiene un valor por
defecto cuando todas las fuentes de la señal están desconectadas y las de clase register no
tienen un valor por defecto, pero conservan el último valor que se escribió.

Al igual que en variables y constantes, a las señales también se les puede dar un
valor inicial si se quiere. Ejemplos:

signal selec: bit := ´0´;


signal datos: bit_vector(7 downto 0) bus := B”00000000”;

1.2.2. Declaración de ficheros.

TYPE fichero_tipo IS FILE OF tipo;


FILE nombre :
fichero_tipo IS [modo] "fichero": -- VHDL'87
[fichero_tipo [OPEN modo] IS "fichero"] -- VHDL'93

Cuando se tratan con ficheros en VHDL, la estructura anterior depende del compilador que se utilice
(VHDL'87 y VHDL'93). La primeras líneas son iguales en ambos casos, pero a la hora de indicar el
acceso al fichero la sintáxis difiere 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 definido mediante
un tipo enumerado declarado en la librería correspondiente (file_open_kind), donde se encuentra
write_mode, read_mode (por defecto) o append_mode, que indica escritura, lectura y concatenación
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 podría utilizar el
siguiente subprograma.

PROCEDURE file_open(status: OUT file_open_status;


FILE f: file_type;
external_name: IN string;
open_kind: IN file_open_kind:=read_mode);

Al realizar la apertura después de la declaración conlleva una flexibilidad mayor, como puede ser la
petición del nombre del fichero. También es posible obtener el estado en el cual se quedó el fichero:
open_ok, status_error, name_error y mode_error, aunque este parámetro es opcional.

Además de este subprograma existe otro para poder cerrar el fichero abierto.

PROCEDURE file_close(FILE f: file_type);

13
A continuación se muestra un ejemplo de declaración, apertura y cierre de ficheros.

TYPE arch_integer IS FILE OF integer;

-- Declaración y apertura a la vez


FILE datos: arch_integer OPEN read_mode IS "input.txt";

-- Declaración y apertura posterior


FILE datos: arch_integer;
.....
file_open(datos, "input.txt",read_mode);

-- Cerrar
file_close(datos);

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.

1.3. Declaraciones concurrentes.


1.3.1. Declaración de arquitectura de flujo de datos.
A la hora de plantearse crear un programa en VHDL no hay que pensar como si fuera un programa típico
para ordenador. No hay que olvidar que en VHDL hay que describir un hardware, algo que no se hace en
un programa para ordenador. Un circuito electrónico puede tener muchos elementos que estén ejecutando
acciones a la vez, por ejemplo en un circuito puede tener una entrada que se aplique a dos puertas lógicas
y de cada una obtener una salida, en este caso tendría dos caminos en los que se ejecutarían acciones
(operaciones lógicas (AND,OR,NOT,IF), de unión, de intersección y de complemento) de forma paralela.
Esto es lo que se llama concurrencia.
VHDL es un lenguaje concurrente, como consecuencia no se seguirá el orden en que están escritas las
instrucciones a la hora de ejecutar el código. De hecho, si hay dos instrucciones, no tiene porqué ejecutarse
una antes que otra, pueden ejecutarse a la vez.

Sentencias Concurrentes
La instrucción básica de la ejecución concurrente es la asignación entre señales a través del símbolo <=.
Para facilitar la asignación de las señales VHDL incluye elementos de alto nivel como son instrucciones
condicionales, de selección, etc, que se verán a continuación.
WHEN ... ELSE
Sentencia de selección múltiple. En hardware es necesario incluir todas las opciones posibles. En este caso
es obligatorio siempre acabar la expresión con un ELSE.

<señal> <= <asignación1> WHEN <condición1> ELSE


<asignación2> WHEN <condición2> ELSE

14
...
<asignaciónN> WHEN <condiciónN> ELSE
<asignaciónM>;

Un posible ejemplo de este tipo de sentencias podría 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 acción alguna, para ello se utiliza la
palabra reservada UNAFFECTED. De esta forma se asignará el mismo valor que tenía la señal.

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 transacción, aspecto
que en la primera no sucede.
WITH ... SELECT ... WHEN
Es similar a las sentencias CASE o SWITCH de C. La asignación se hace según el contenido de un objeto
o resultado de cierta expresión.

WITH <señal1> SELECT


<señal2> <= <asignación1> WHEN <estado_señal1>,
<asignación2> WHEN <estado_señal2>,
...
<asignaciónN> 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 cláusula WHEN OTHERS especifica todos los demás valores que no han sido contemplados. También
es posible utilizar la opción que se contempló en el caso anterior (UNAFFECTED).

15
BLOCK
En ocasiones interesa agrupar un conjunto de sentencias en bloques. Estos bloques permiten dividir el
sistema en módulos, estos módulos pueden estar compuestos de otros módulos. La estructura general es
la siguiente.

block_id: BLOCK(expresión de guardia)


declaraciones
BEGIN
sentencias concurrentes
END BLOCK block_id;

El nombre del bloque es opcional (block_id), al igual que la expresión de guardia. Un ejemplo de esto
podría ser el siguiente.

latch: BLOCK(clk='1')
BEGIN
q <= GUARDED d;
END BLOCK latch;

Descripción de comportamiento
Como la programación concurrente no siempre es la mejor forma de describir ideas, VHDL incorpora la
programación serie, la cual se define en bloques indicados con la sentencia PROCESS. En un mismo
diseño puede haber varios bloques de este tipo, cada uno de estos bloques corresponderá a una
instrucción concurrente. Es decir, internamente la ejecución de las instrucciones de los PROCESS es serie,
pero entre los bloques es concurrente.
A continuación se verán la estructuras más comunes de la ejecución serie y sus características.

PROCESS
Un PROCESS, como se ha dicho antes, es una sentencia concurrente en el sentido de que todos
los PROCESS y todas las demás sentencias concurrentes se ejecutarán 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 genérica de esta sentencia es:

PROCESS [lista de sensibilidad]


[declaración de variables]
BEGIN
[sentencias secuenciales]
END PROCESS;

La lista de sensibilidad es una serie de señales que, al cambiar de valor, hacen que se ejecute
el PROCESS.

16
Un ejemplo sería:

PROCESS(señal1, señal2)
...

El PROCESS anterior sólo se ejecutará cuando señal1 o señal2 cambien de valor

1.3.2. Ejemplos de descripción flujo de datos.

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; --asignación de señales: después de ejecutarse esta
línea, "a" seguirá valiendo lo mismo, sólo se actualiza al acabar el PROCESS
z:= a or c; --asignación de variables: en el momento de ejecutarse
esta línea z valdrá "a or c" (el valor que tenía a cuando empezó el PROCESS)
END PROCESS;
END ARCHITECTURE;

#2

IF (reloj='1' AND enable='1') THEN


salida<=entrada;
ELSIF (enable='1') THEN
salida<=tmp;
ELSE
salida<='0';
END IF;

1.4. Ejemplos de declaraciones secuenciales.


1.4.1. Ejemplos de diagramas de máquinas de estado.

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;

ENTITY maquina_estados IS
PORT (clk : IN std_logic;

17
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

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

1.5. Funciones y subprogramas.


1.5.1. Declaración de procedimientos y funciones.

Las declaraciones de estos elementos pueden realizarse en la parte declarativas de las arquitecturas,
bloques, paquetes, etc. A continuación, se muestra la estructura de un procedimiento.

PROCEDURE nombre[(parámetros)] IS
[declaraciones]
BEGIN
[sentencias]
END [PROCEDURE] [nombre];

La estructura de las funciones corresponden a las siguientes líneas.

[PURE | IMPURE]
FUNCTION nombre[(parámetros)] RETURN tipo IS
[declaraciones]
BEGIN
[sentencias] -- Debe incluir un RETURN
END [FUNCTION] [nombre];

Como ya se explicó, la lista de parámetros es opcional en ambos casos. Estos parámetros se declaran de
forma similar a como se hacen los puertos de una entidad.

<nombre del puerto> : <tipo de puerto> <tipo de objeto>

Dependiendo de la estructura que se utilice, funciones o procedimientos, los parámetros tendrán un


significado u otro. En las funciones sólo es posible utilizar el tipo de puerto IN, mientras que en los
procedimientos pueden usarse los tipos IN, OUT e INOUT. Además, en las funciones el parámetro puede
ser CONSTANT o SIGNAL, por defecto es CONSTANT. Por otro lado, en los procedimientos los
parámetros de tipo IN son CONSTANT por defecto y VARIABLE para el resto, aunque también es posible
utilizar SIGNAL siempre que se declare explícitamente. No se aconseja utilizar señales como parámetros,
por los efectos que pueden tener en la ejecución de un programa.
Las funciones PURE o puras devuelven el mismo valor para unos parámetros de entrada determinados.
Mientras que una función es IMPURE o impura si para los mismos valores de entrada se devuelve distinto

19
valor. Estas últimas pueden depender de una variable o señal global. Realmente, estas palabras
reservadas hacen de comentario, puesto que una función no se hace impura o pura por indicarlo.
Un ejemplo de una función sería 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 podría pertenecer a las siguientes líneas.

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 asignación a la señal de salida se realiza con el operador :=, puesto que no es una señal, es decir que
se trata de un tipo VARIABLE. Si se tratara de una señal se haría con el operador de asignación <=.

1.5.2. Subprogramas.
Como en otros lenguajes de programación, en VHDL es posible estructurar el código mediante el uso de
subprogramas. Realmente, un subprograma es una función o procedimiento que realiza una determinada
tarea, aunque existen ciertas diferencias entre ambas.

• Una función devuelve un valor y un procedimiento devuelve los valores a través de los
parámetros que le han sido pasados como argumentos. Por ello, las primeras deberán 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 ejecución del
procedimiento.

20
• A consecuencia de la anterior, en una función todos sus parámetros son de entrada, por lo que
sólo pueden ser leidos dentro de la misma, por el contrario en un procedimiento los parámetros
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 señales externas que
han sido pasadas como parámetros, por otro lado las funciones no poseen estos efectos.
• Las funciones nunca pueden tener una sentencia WAIT, pero los procedimientos sí.

1.5.3. Paquetes.
Como se comentó al principio, un paquete consta de un conjunto de subprogramas, constantes,
declaraciones, etc., con la intención de implementar algún servicio. Así se pueden hacer visibles las
interfaces de los subprogramas y ocultar su descripción.

Definición de paquetes
Los paquetes se separan en dos zonas: declaraciones y cuerpo, aunque esta última puede ser eliminada si
no se definen funciones y/o procedimientos. Las siguientes líneas muestra la estructura de un paquete.

-- Declaración de paquete
PACKAGE nombre IS
declaraciones
END [PACKAGE] [nombre];

-- Declaración del cuerpo


PACKAGE BODY nombre IS
declaraciones
subprogramas
...
END [PACKAGE BODY] [nombre];

El nombre del paquete debe coincidir en la declaración del paquete y del cuerpo. A continuación, se
muestra un ejemplo de un paquete.

-- Declaración de paquete
PACKAGE mi_paquete IS
SUBTYPE dir_type IS std_logic_vector(31 DOWNTO 0);
SUBTYPE dato_type IS std_logic_vector(15 DOWNTO 0);
CONSTANT inicio : dir_type; -- Hay que definirlo en el BODY
FUNCTION inttodato(valor : integer) RETURN dato_type;
PROCEDURE datotoint(dato : IN dato_type; valor : OUT integer);
END mi_paquete;

-- Declaración del cuerpo


PACKAGE BODY mi_paquete IS
CONSTANT inicio : dir_type := X"FFFF0000";

FUNCTION inttodato(valor : integer) RETURN dato_type IS

21
-- Cuerpo de la función
END inttodato;

PROCEDURE datotoint(dato : IN dato_type; valor : OUT integer) IS


-- Cuerpo del procedimiento
END datotoint;

END PACKAGE BODY mi_paquete;

Para acceder a los tipos creados en un paquete, se debe indicar el nombre del paquete seguido del
elemento que se desea utilizar, separados por un punto. Para el ejemplo anterior sería algo parecido a las
siguientes líneas.

VARIABLE dir : work.mi_paquete.dir_type;


dir := work.mi_paquete.inicio;

Existe otra forma de realizarlo, haciendo visible al paquete. De esta forma no se necesitará el punto ni
tampoco indicar el nombre del paquete. Para ello, se debe utilizar la sentencia USE seguido del paquete
que se va a utilizar y el método a utilizar, todo ello separado por puntos. El ejemplo anterior se podría
realizar de la siguiente forma.

USE work.mi_paquete.ALL
VARIABLE dir : dir_type;
dir := inicio;

1.5.4. Bibliotecas
Cuando se realiza una descripción en VHDL se utilizan estas unidades, en uno o más ficheros, éstos se
denominan ficheros de diseño. Posteriormente, estos ficheros serán compilados para obtener
una librería o biblioteca de diseño, de forma que esta biblioteca contiene los elementos que componen el
circuito. La biblioteca donde se guardan los resultados de la compilación se denomina work.
Una librería se compone de dos partes bien diferenciadas, dependiendo de las unidades que la formen. Por
un lado, están las unidades primarias, que corresponderán a entidades, paquetes y archivos de
configuración. Mientras que las unidades secundarias serán arquitecturas y cuerpos de paquetes. Por lo
tanto, se puede sacar la conclusión de que cada unidad secundaria deberá estar asociada con una unidad
primaria.
Al realizar una compilación se analizarán las unidades que vayan apareciendo en el texto. Por consiguiente,
es importante establecer un orden lógico de las distintas unidades, para que de esta forma se puedan
cumplir las dependencias existentes entre las mismas. La forma que toma la librería una vez compilada es
muy diversa; dependiendo de la herramienta de compilación utilizada así será el resultado obtenido, esto se
debe a que en VHDL no existe un estándar para crear bibliotecas.

22
Para incluir una librería a un diseño basta con utilizar la palabra reservada LIBRARY seguida del nombre
de la biblioteca a utilizar. Además, también 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 librerías que no hacen falta importarlas. Por un lado está la librería work, que contiene las
unidades que se están compilando, y por otro lado, la librería std que contiene los
paquetes standard y textio, las cuales contienen definiciones de tipos y funciones para el acceso a ficheros
de texto.

Librería ieee
Una de las bibliotecas más utilizadas en el mundo de la industria es la denominada ieee, la cual contiene
algunos tipos y funciones que completan a las que vienen por defecto en el propio lenguaje. Dentro de la
librería existe un paquete denominado std_logic_1164, con el cual se pueden trabajar con un sistema de
nueve niveles lógicos, como puede ser: valor desconocido, alta impedancia, etc. El siguiente código
muestra parte de este paquete.

PACKAGE std_logic_1164 IS
TYPE std_ulogic IS( 'U', -- Indefinido
'X', -- Desconocido
'0', -- 0
'1', -- 1
'Z', -- Alta impedancia
'W', -- Desconocido
'L', -- LOW (weak low o 0 débil)
'H', -- HIGH (weak high o 1 débil)
'-' -- Desconocido
);

TYPE std_ulogic_vector IS ARRAY(NATURAL RANGE <>) OF std_ulogic;

FUNCTION resolved(s : std_ulogic_vector) RETURN std_ulogic;

SUBTYPE std_logic IS resolved std_ulogic;

TYPE std_logic_vector IS ARRAY (NATURAL RANGE <>) OF std_logic;

23
1.6. Programación de FPGA´s ó CPLD’S en diferentes
aplicaciones

CONCLUSIONES PERSONALES
La importancia de los dispositivos lógicos programables radica en el hecho de que la mayoría de los
equipos electrónicos modernos incluyen en su diseño PLDs, por lo que todo profesional relacionado
con el mantenimiento o fabricación de equipo electrónico debería dominar dicha metodología.

Los PLDs combinan muchos de los beneficios de la lógica discreta, utilización de circuitos integrados
comerciales TTL o CMOS, con la gran ventaja de implementar circuitos a la medida del cliente

REFERENCIAS BIBLIOGRÁFICAS
https://es.wikibooks.org/wiki/Programaci%C3%B3n_en_VHDL/Bancos_de_pruebas
https://cursos.mcielectronics.cl/2019/06/18/fpga-field-programmable-gate-array/
http://www.itcg.edu.mx/pdf/IELC/4/Diseno%20Digital%20con%20VHDL.pdf

24
http://www.itq.edu.mx/carreras/IngElectronica/archivos_contenido/Apuntes%20de%20materias
/Apuntes_VHDL_2016.pdf
https://www.fceia.unr.edu.ar/eca1/files/LDD/Tipo_datos%20V_2006.pdf
https://docplayer.es/94081349-Cplds-y-fpgas-tema-ii-circuitos-integrados-programables-
roberto-gutierrez-mazon

25

También podría gustarte