# Programación en Verilog/Módulos
## Características

Las características principales de los módulos se pueden recoger en los siguientes puntos.
* Cada módulo dispone de una serie de entradas y salidas, por las cuales se puede interconectar otros módulos, aunque puede no tener entradas ni salidas, como es el caso de los testbenches.
* No existen variables globales.
* Fuera de los módulos solo hay directivas del compilador, que afectarán a partir del punto en donde aparecen.
* A pesar de que se pueden realizar varias simulaciones concurrentes, en general se suele tener un único módulo que emplea los módulos previamente definidos.
* Cada módulo puede describirse de forma arquitectural o de comportamiento.

## Estructura

En Verilog un sistema digital esta compuesto por la interconexión de un conjunto de módulos. La estructura general de estos módulos es la siguiente.
A continuación, se muestra un ejemplo de un módulo que suma un array de 3 bits indicando si hay acarreo o no.

### Interfaz del módulo

Los argumentos del módulo pueden ser de tres tipos, estos argumentos comunicarán el interior o funcionalidad del módulo con otros elementos del propio diseño.
* input: Entradas del módulo, cuyo tipo son wire.
* output: Salidas del módulo. Dependiendo del tipo de asignación que las genere serán wire si proceden de una asignación continua y reg si proceden de una asignación procedural.
* inout: Son a la vez entradas y salidas. Únicamente, son de tipo wire.

### Procesos

Uno de los aspectos que diferencian Verilog de los lenguajes procedurales como es el lenguaje c, es la posibilidad de ejecutar en paralelo varios procesos, aspecto que es fundamental en el lenguaje. Cada proceso se ejecuta de forma secuencial, es decir se ejecuta cada línea del proceso según su orden de precedencia.
Toda la descripción del comportamiento en Verilog debe declararse dentro de un proceso, estos pueden ser de dos tipos: initial o always.
* Initial: Este tipo de procesos se ejecuta sólo una vez comenzando su ejecución al inicio, y por tanto no existen retardos. Este proceso no es sintetizable, es decir, no puede ser utilizado en una descripción RTL. Su uso esta justificado en los testbenches, para la verificación de los distintos diseños.
A continuación se muestra un ejemplo de este tipo de procesos.
* Always: Este tipo de procesos se ejecuta continuamente a modo de bucle, y como su propio nombre indica, está continuamente ejecutándose. Este proceso si que es sintetizable y es controlada por la temporización o por eventos. Si dicho bloque se ejecuta por más de un evento, dicho conjunto se denomina lista sensible. La sintaxis de este proceso es la siguiente.
El siguiente código muestra un ejemplo de los procesos always.
Si el proceso engloba más de una asignación procedural o más de una estructura de control, estas deben estar contenidas en un bloque delimitado entre las palabras reservadas begin y end. Es decir, en el ejemplo no es necesario incluir estas palabras.
Otro ejemplo de los procesos always es el siguiente, donde no existe una lista de sensibilidad.
En este proceso pasadas 10 unidades de tiempo se asigna a 0 la variable clk, después de otras 10 unidades se asigna a 1, comenzando de nuevo esta ejecución.

### Estructuras de control

Verilog dispone de una elevada cantidad de estructuras de control, similares a las disponibles en otros lenguajes de programación. A continuación, se enumeran las estructuras que pueden ser utilizadas.

#### if - else

La sentencia condicional if-else controla la ejecución de otras sentencias y/o asignaciones. En caso de haber múltiples sentencias o asignaciones es necesario hacer uso del bloque begin-end. La sintaxis de esta estructura es la siguiente.
Si la expresión es cierta se ejecutan las Sentencias 1, en caso contrario se ejecutan las Sentencias 2. Un ejemplo puede ser el siguiente.

#### Case

La sentencia case evalúa una expresión y en función de su valor ejecutará la sentencia o grupo de sentencias agrupadas en el primer caso que coincida. Si existen varias sentencias se deben agrupar en un bloque begin-end. Si no se cubren todos los posibles valores se debe hacer uso del caso por defecto, denominado default, el cual se ejecutará cuando ninguno de los casos anteriores se cumplan. La sintaxis de esta estructura es la siguiente.
A continuación se detalla un ejemplo, donde dependiendo del valor que tome la expresión se asignará a la variable A un valor.

#### Casez y Casex

Estas estructuras corresponden a versiones especiales del case, cuya particularidad radica en que los valores lógicos 'X' y 'Z' se tratan como indiferentes.
* casez: Usa el valor 'Z' como indiferente.
* casex: Toma como indiferentes los valores lógicos 'Z' y 'X'.
Un ejemplo del tipo de la estructura casez se muestra en las siguientes líneas.
Otro ejemplo para el tipo casex sería el siguiente.

#### For

El bucle for es idéntico a los utilizados en otros lenguajes de programación, como en los anteriores pasos si existen varias sentencias se deben incluir dentro del bloque begin-end. Su sintaxis es la siguiente.
Un ejemplo de esta estructura es la siguiente.

#### While

El bucle while se ejecuta mientras la condición que evalúa sea cierta. Su sintaxis es la siguiente.
A continuación se muestra un ejemplo de este tipo de bucle.

#### Repeat

EL bucle repeat se ejecuta un determinado número de veces, siendo este número la condición de salida del bucle. SU sintaxis es la que se muestra en las siguientes líneas.
A continuación se muestra un ejemplo del bucle repeat, el cual se repetirá 9 veces.

#### Forever

El bucle forever se ejecuta de forma continua sin condición de finalización. Su sintaxis es la siguiente.
Un ejemplo de este bucle podría ser el siguiente

#### Wait

La ejecución de un bloque se realiza de forma continuada, como si de un bucle infinito se tratara (se ejecutan todas las sentencias y se vuelven a repetir). Sería interesante poder parar la ejecución. Una forma de hacerlo e mediante las listas de sensibilidad y la otra forma de hacerlo es mediante la sentencia wait. Su sintaxis es la siguiente.
Un ejemplo de wait podría ser el siguiente

## Asignaciones

Existen dos maneras de asignar valores en Verilog, de forma continua o procedural.

### Asignación continua

La asignación continua se utiliza exclusivamente para modelar lógica combinacional, donde no se necesita de una lista de sensibilidad para realizar la asignación. La variable a la que se realiza la asignación continua sólo puede ser declarada de tipo net, es decir wire. Y la asignación sólo puede ser declarada fuera de cualquier proceso y nunca dentro de bloques always o initial. La sintaxis es la siguiente.
Un ejemplo de la asignación continua podría ser el siguiente.
En el ejemplo no se ha añadido una temporización en la asignación, por lo tanto en cada ciclo se revisará dicha sentencia. Estas asignaciones también se ejecutan de forma secuencial las cuales se pueden controlar mediante la temporización.

### Asignación procedural

La asignación procedural es la que se ha visto hasta el momento, donde a las variables se le asigna un valor dentro de un proceso always o initial, el tipo de variable a la que se le asigna el valor puede ser de cualquier tipo. Su sintaxis es la siguiente.
Un ejemplo de esta asignación es el siguiente.

## Temporizaciones

Las temporizaciones se consiguen mediante el uso de retardos. El retardo se especifica mediante el símbolo # seguido de las unidades de tiempo del retardo. Un ejemplo podría se el siguiente, donde en el instante 0 se ejecutan las dos primeras sentencias, cinco unidades de tiempo más tarde se realiza la tercera asignación y cuatro más tarde se ejecutan las dos últimas.
En las temporizaciones caben destacar dos tipos de asignaciones procedurales.
* Con bloqueo: La asignación se realiza antes de proceder con la siguiente.
* Sin bloqueo: El término se evalúa en el instante actual, pero no se asigna hasta finalizar dicho instante.
En el ejemplo, inicialmente se realiza una asignación con bloqueo, donde el resultado será a = 6 y b = 7, ya que a se ha calculado previamente. Mientras que en la asignación sin bloque a y b serán 6, ya que a no ha sido calculado.

## Eventos

La asignación procedural puede ser controlada por el cambio de una variable en un proceso always, es decir por eventos. Para ello se utiliza el carácter @ seguido del evento que permite la ejecución de la asignación procedural. Se distinguen dos tipos de eventos.
* De nivel: El cambio de valor de una o un conjunto de variables controla el acceso.
* De flanco: La combinación de flanco de subida (de 0 a 1) o de bajada (de 1 a 0).

## Parámetros

Los parámetros son como en otros lenguajes las denominadas constantes, su definición sólo puede realizarse en el interior de un módulo, como puede ser el tamaño de un bus. La sintaxis de los parámetros es la siguiente.
Un ejemplo podría ser el siguiente.