# Programación en VHDL/Arquitectura

Como se ha dicho en el capítulo anterior, la arquitectura es lo que define cómo se comporta un circuito. En el primer capítulo también se mostraron varias arquitecturas en las que se describía un multiplexor. La primera línea de cada una era
Los nombres de cada arquitectura son mux_comportamiento, mux_rtl y mux_estructural respectivamente. Todas están asociadas a la entidad mux. El nombre de la arquitectura se usará para indicar qué arquitectura se debe usar en caso que haya varias para una misma entidad.
Después de esta línea pueden aparecer varias instrucciones para indicar la declaración de señales, componentes, funciones, etc.. Estas señales son internas, es decir, a ellas no se puede acceder desde la entidad, por los que los circuitos de nivel superior no podrían acceder a ellas. En un símil con un microprocesador, estas señales podrían ser las líneas que comunican la unidad central con la ALU, a las que no se puede acceder directamente desde el exterior del microprocesador. Obsérvese que en este caso no se indica si son entradas o salidas, puesto que al ser internas pueden ser leídas o escritas sin ningún problema. En esta parte de la arquitectura también pueden aparecer otros elementos, como pueden ser las constantes. Lo siguiente es la palabra clave BEGIN, que da paso a la descripción del circuito, mediante una serie de sentencias. Por lo tanto, la sintaxis de una arquitectura sería.
Un ejemplo de una arquitectura podría ser la siguiente.
La descripción puede ser de tres tipos:
* Descripción de flujo de datos
* Descripción de comportamiento
* Descripción estructural

## Descripción 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.
Un posible ejemplo de este tipo de sentencias podría ser la siguiente.
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.
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.
Un ejemplo de esta sentencia es la siguiente.
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).

#### 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.
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.

## 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:
La lista de sensibilidad es una serie de señales que, al cambiar de valor, hacen que se ejecute el PROCESS.
Un ejemplo sería:
El PROCESS anterior sólo se ejecutará cuando señal1 o señal2 cambien de valor.

### Variables y Señales

Hay que distinguir las señales y las variables, las señales se declaran entre ARCHITECTURE y su correspondiente BEGIN mientras que las variables se declaran entre PROCESS y su BEGIN. Dentro de un PROCESS pueden usarse ambas, pero hay una diferencia importante entre ellas: las señales sólo se actualizan al terminar el proceso en el que se usan, mientras que las variables se actualizan instantáneamente, es decir, su valor cambia en el momento de la asignación.
Un ejemplo es:

### Sentencias secuenciales
#### IF ... THEN ... ELSE

Permite la ejecución de un bloque de código dependiendo de una o varias condiciones.
Un ejemplo es:

#### CASE

Es parecido al anterior porque también ejecuta un bloque de código condicionalmente, pero en esta ocasión se evalúa una expresión en vez de una condición. Se debe recordar que se deben tener en cuenta todos los casos, es decir, incluir como última opción la sentencia WHEN OTHERS.
Un ejemplo es:

#### LOOP

LOOP es la forma de hacer bucles en VHDL. Sería el equivalente a un FOR o WHILE de un lenguaje convencional.
Su estructura es:
Un ejemplo de bucles anidados es:
Otro ejemplo, este con FOR es:
Otro más con WHILE

#### NEXT y EXIT

NEXT permite detener la ejecución actual y seguir con la siguiente.
Como se puede suponer, la sentencia EXIT hace que se salga del bucle superior al que se ejecuta.
Se puede ver su uso en los ejemplos del apartado anterior.

#### ASSERT

Se usa para verificar una condición y, en caso de que proceda, dar un aviso.
La sintáxis es:
Este comando se estudiará en el subcapítulo de notificaciones, en la sección de bancos de prueba. Puesto que el uso de este comando se realiza únicamente en la simulación de circuitos.

#### WAIT

La ejecución de un bloque PROCESS se realiza de forma continuada, como si de un bucle infinito se tratara (se ejecutan todas las sentencias y se vuelven a repetir). Esto no tiene mucho sentido, puesto que continuamente se ejecutaría lo mismo una y otra vez, sería interesante poder parar la ejecución. Una forma de hacerlo es mediante las listas de sensibilidad, las cuales se han visto anteriormente, aunque existe otra forma de hacerlo mediante la sentencia WAIT, pero es algo más complejo.
La lista_sensible es un conjunto de señales separadas por comas. La condición es una sentencia que activará de nuevo la ejecución. El timeout es el tiempo durante el cual la ejecución está detenida.
No es necesario utilizar las tres opciones, en caso de hacerlo la primera condición que se cumpla volverá a activar la ejecución.
Si se utiliza una lista de sensibilidad no es posible utilizar la sentencia WAIT, sin embargo si es posible utilizar varias sentencias WAIT cuando esta actúa como condición de activación. Este comando se estudiará en el subcapítulo de retrasos, en la sección de bancos de prueba.

## Descripción estructural

Las dos descripciones anteriores son las más utilizadas por los diseñadores, ya que son más cercanos al pensamiento humano. Aunque existe otro tipo de descripción, que permite la realización de diseños jerárquicos. VHDL dispone de diferentes mecanismos para la descripción estructural.

### Definición de componentes

En VHDL es posible declarar componentes dentro de un diseño mediante la palabra COMPONENT. Un componente se corresponde con una entidad que ha sido declarada en otro módulo del diseño, o incluso en alguna biblioteca, la declaración de este elemento se realizará en la parte declarativa de la arquitectura del módulo que se está desarrollando. La sintaxis para declarar un componente es muy parecida a la de una entidad.
Si se dispone de un compilador de VHDL'93 no será necesario incluir en los diseños la parte declarativa de los componentes, es decir se pasaría a referenciarlos de forma directa. Un ejemplo de un componente podría ser el siguiente.

### Referencia de componentes

La referencia de componentes consiste en copiar en la arquitectura aquel componente que se quiera utilizar, tantas veces como sea necesario para construir el diseño. Para ello, la sintaxis que presenta la instanciación de un componente es la siguiente.
Un ejemplo de referenciación del componente anterior sería.
Las señales ctrl, e1, e2 y sal deben ser declaradas previamente en la sección de declaraciones de la arquitectura, estas señales sirven para poder conectar unos componentes con otros. También deben declararse las variables que se utilizan en la sección GENERIC.