• No se han encontrado resultados

Dependencias entre las declaraciones

In document Diseño de un elaborador VHDL (página 53-59)

4. ELABORACIÓN DE UNIDADES

4.3. Elaboración de un paquete

4.3.1. Dependencias entre las declaraciones

La declaración de un objeto VHDL puede depender de la declaración de otro objeto. Por ejemplo, dado el siguiente fragmento de la declaración de un componente,

[54]

CONSTANT number_of_bits: integer := 32;

TYPE bit_index IS RANGE 0 TO number_of_bits – 1;

se observa que la declaración de la constante number_of_bits depende del tipo integer, y la declaración del tipo bit_index depende de la declaración de la constante anterior. El uso de las declaraciones de otros objetos para formar nuevas declaraciones es una práctica generalizada en cualquier diseño VHDL. Esta dependencia implícita entre objetos de diferentes unidades debe ser resuelta por el elaborador, de tal manera que la siguiente fase de la elaboración tenga como punto de partida un código VHDL sin ninguna dependencia entre unidades.

En el fragmento de código anterior, para que sea semánticamente correcto necesita al principio la declaración del tipo integer, así como también hubiera necesitado importar la declaración de la constante si no hubiera sido declarada en el mismo bloque. De esta manera surgen dos posibles dependencias, las internas y las externas a una unidad. Si las dependencias se resuelven con las mismas declaraciones realizadas en el bloque, entonces se denominan internas. En el ejemplo, existe una dependencia interna entre bit_index y number_of_bits. Sin embargo, si las dependencias no se resuelven con las declaraciones del mismo bloque, sino que requieren de declaraciones de otros objetos existentes en otras unidades (necesariamente estas unidades deben ser del tipo paquete) entonces se denominan externas.

Las dependencias internas en un primer momento parece que no necesiten de ningún tipo de mecanismo de importación, ya que se encuentran en el mismo bloque donde surge la dependencia. Con las dependencias externas sí que debe desarrollarse este mecanismo que la resuelva importando las declaraciones necesarias.

Una posible solución para las dependencias externas sería añadir a la tabla de símbolos un nuevo campo que permita recuperar la declaración de un identificador de tipo declarativo. De esta manera, al realizar una búsqueda en la tabla de símbolos por el nombre del identificador requerido se importaría su declaración al encontrarlo en el componente donde hubiera sido declarado.

[55]

Figura 4.7. Modificación a la tabla de símbolos para incluir la declaración.

Esto supone que durante el proceso de elaboración de la parte declarativa, los identificadores insertados almacenen además de su información asociada, una referencia a la misma declaración que se insertará en las declaraciones de la unidad una vez finalizada la elaboración de la declaración.

Si durante la elaboración de una declaración o sentencia se encuentra un identificador, comienza una búsqueda por las diferentes tablas de símbolos visibles de la unidad hasta encontrar dicho identificador. Acto seguido se importaría la declaración del objeto buscado insertándolo en las declaraciones del componente actual.

[56]

Figura 4.8. Inserción de declaraciones de otras unidades.

Esta solución sólo es válida para un nivel de dependencia, ya que no sería posible resolver una dependencia de un elemento que a su vez depende de otro. Por ejemplo, si en la Figura 4.8 un nueva unidad UNIT_C usara la constante pos_pt1 declarada en UNIT_B, sólo se importaría la declaración M faltando la declaración M-1. Surge de esta manera la necesidad de añadir una entrada más a la tabla de símbolos que indique el conjunto de dependencias de declaraciones necesarias que deben importar aquellas unidades que utilicen ese elemento.

Por tanto, se agrega el campo de dependencias en la tabla de símbolos, de tal manera que cuando se elabore una declaración, si ésta depende de uno o más elementos, se inserta en su conjunto de dependencias las referencias a las declaraciones de cada uno de estos elementos, uniendo también sus conjuntos de de dependencias con el conjunto de la declaración que se está elaborando.

Por ejemplo, dado el siguiente fragmento del paquete standard,

TYPE BIT IS ('0', '1');

TYPE INTEGER IS RANGE -2147483648 TO 2147483647; SUBTYPE NATURAL IS INTEGER RANGE 0 TO INTEGER'HIGH; TYPE BIT_VECTOR IS ARRAY (NATURAL RANGE <>) OF BIT;

[57]

La unidad elaborada almacenaría la siguiente información relativa al conjunto de dependencias:

Figura 4.9. Ejemplo de dependencias en el paquete Standard.

Al elaborar la declaración de bit_vector aparecen los identificadores natural y bit, los cuales se buscan y encuentran en la propia tabla de símbolos del componente, por lo que las referencias a sus declaraciones ([1], [3]) pasan directamente a formar parte del conjunto de dependencias de bit_vector. Además, como el conjunto de dependencias de natural no es vacío, también pasa a formar parte del conjunto ([2]). De tal manera que si otra unidad utiliza en sus declaraciones el tipo bit_vector, automáticamente pasarían a formar parte de su conjunto de dependencias la declaración del tipo y el conjunto de dependencias de bit_vector ([1], [2], [3]).

[58]

Figura 4.10. Uso del conjunto de dependencias entre componentes.

Como se observa en la Figura 4.10, la entrada correspondiente al identificador de la señal declarada engloba en el campo de dependencias las referencias que hereda por el uso del tipo bit_vector, cuya declaración se encontró en el paquete standard (STD). Además se han insertado en la unidad las declaraciones del conjunto de dependencias antes de insertar la propia declaración de la señal, manteniendo por tanto el orden correcto.

La declaración de un objeto de un paquete puede ser utilizada por más de una unidad de diseño. Si cada dependencia que se produzca por dicha declaración en el resto de unidades provoca que cada uno de éstos la incorpore a sus contenedores respectivos, como se ha explicado en el párrafo anterior, sucederá que en el momento de instanciar los componentes heredarán irremediablemente las declaraciones de los compontes de más bajo nivel, produciéndose de esta manera una redeclaración de los objetos en el componente más alto.

Por esta razón, se pospone la inserción de las dependencias hasta que no se instancien todos los componentes, momento en el cual se habrán obtenido todas las declaraciones dependientes necesarias, mediante el almacenamiento en la tabla de

[59]

símbolos de los conjuntos de dependencias. Se pasará a unir todos estos conjuntos, dando como resultado el conjunto mínimo de declaraciones que deben importarse para una correcta declaración del componente.

In document Diseño de un elaborador VHDL (página 53-59)