6. ELABORACION DE SENTENCIAS VHDL
6.2. Sentencias concurrentes VHDL
6.2.1. Sentencia concurrente Process
Un proceso es una sentencia concurrente que define su comportamiento a través de sentencias secuenciales. Cualquier sentencia concurrente VHDL tiene su proceso equivalente, por lo que se deben obtener estas equivalencias para todas las sentencias declaradas, puesto que el simulador VHDL sólo trabaja con procesos [VTOT98].
La sintaxis general de un proceso es:
[label:] PROCESS [(sensitivity_list)] [IS]
process_declarative_part
BEGIN
process_statement_part
END PROCESS [label];
Sintaxis VHDL 6.3. Sentencia Process.
Donde process_declarative_part es la producción que permite declarar datos locales al proceso, y process_statement_part es la zona de las sentencias secuenciales que definen el comportamiento del proceso a través de un algoritmo.
Toda sentencia VHDL concurrente tiene un process equivalente. El elaborador es el encargado de transformar cualquier sentencia declarada en el diseño a la sentencia process correspondiente. De esta manera el resultado de la elaboración de la zona de sentencias de una unidad estará formado únicamente por un conjunto de sentencias process, convirtiendo de esta forma su naturaleza concurrente en secuencial.
Una sentencia process elaborada tiene una sintaxis diferente a la mostrada anteriormente: [label:] PROCESS process_declarative_part BEGIN process_statement_part WAIT [ON sensitivity_list]; END PROCESS;
[99]
La diferencia está en que el process elaborado no presenta la lista de señales que forman sensitivity_list, sino que contiene en la zona correspondiente una última sentencia de tipo wait que recoge dicha lista, en caso de haber sido declarada.
La Sintaxis VHDL 6.4 para la sentencia process elaborada es la que se debe utilizar para transformar el resto de sentencias VHDL concurrentes, y también para aquellos process que presenten la lista de señales a la que es sensible el proceso.
Para los procesos que tienen declarado la parte de sensitivity_list, la única modificación que deben sufrir es la inclusión de una última sentencia secuencial de tipo wait que recoja las señales declaradas en dicha lista. Su parte declarativa y la zona de sentencias secuenciales no se ven afectadas.
p_res: PROCESS (opera, reset)
BEGIN
IF opera == SHIFT_R THEN
opera <= operaciones’succ(opera);
ELSE IF reset THEN
opera <= OP_INI;
END IF;
END PROCESS p_res;
Fragmento de código 6.3. Ejemplo de proceso con lista de sensibilidad.
Se muestra un ejemplo de un process que tiene declarada una lista de sensibilidad formada por dos señales. El resultado de la elaboración del ejemplo anterior es el siguiente:
p_res: PROCESS BEGIN
IF opera == SHIFT_R THEN
opera <= operaciones’succ(opera);
ELSE IF reset THEN
opera <= OP_INI;
END IF;
WAIT ON opera, reset;
END PROCESS;
Fragmento de código 6.4. Ejemplo de proceso elaborado.
Donde se ha obtenido un proceso sin lista de sensibilidad, con las mismas sentencias secuenciales incluyendo una última de tipo wait que contiene todas las señales declaradas en esa lista de sensibilidad.
[100]
Si un proceso no tiene declarado esa lista, entonces se considera como elaborado, ya que no se debe incluir la última sentencia wait al no tener señales que sean sensibles al proceso.
Detalles de la implementación.
Un proceso debe ser elaborado de tal forma que las declaraciones realizadas en su interior tengan un ámbito local a éste, y se debe generar una última sentencia secuencial de tipo wait si el proceso tiene definida una lista de sensibilidad.
Para poder explicar las acciones tomadas durante la implementación de su elaboración, se presenta un esquema del árbol gramatical que define la sentencia. Se remarcan en orden las acciones semánticas más destacadas durante la elaboración. Debe recordarse que el análisis sintáctico se realiza de forma ascendente.
Figura 6.4. Esquema de las producciones implicadas en la sentencia process.
Dentro de la producción sensitivity_list se ha generado una lista con los nombres de las señales que definen la lista de sensibilidad. En la acción semántica 1, se sube la lista hacia el padre (procs_stat1_1).
Durante la acción semántica 2 se recuperan las declaraciones internas al proceso de la lista que sube por la producción procs_stat1_2. El ámbito de estas declaraciones es local, por lo que se inicia una funcionalidad que modifica todos los identificadores encontrados en las declaraciones convirtiéndolos en literales, ya que sus nombres no se verán afectados por la instanciación de la unidad contenedora.
[101]
A continuación se crea una lista de tokens que almacena la propia sentencia del proceso. Se inserta el token “PROCESS”, se une con la lista de tokens correspondiente a las declaraciones internas del process, si ésta existe, se inserta el token “BEGIN” y se une con la lista de tokens correspondiente a las sentencias internas recogidas en la producción seq_stat.
Si el proceso tiene declarado una lista de sensibilidad, se recoge dicha lista de la producción procs_stat1_1, y crea una nueva sentencia para el proceso de tipo wait donde se almacenan las señales declaradas en la lista. Se insertan los tokens de la nueva sentencia “wait on señales” en la lista de tokens del proceso.
La acción semántica 2 finaliza insertando los tokens “END” y “PROCESS” y subiendo la lista de tokens elaborada hacia la producción padre procs_stat1.
La acción semántica 1 recoge el identificador de la etiqueta del proceso, el cual es el único identificador que será insertado en la tabla de símbolos de la unidad actual de toda la sentencia process, ya que como se indicó anteriormente todas las declaraciones realizadas en la sentencia tienen un ámbito local, por lo que no necesitan ser insertadas en la tabla. Una vez almacenada la etiqueta, se inserta en la lista de tokens del proceso, y ésta se inserta como una nueva sentencia elaborada de la unidad actual.