SED 04 1b Imprimir

2
1 4.1.2.4 Sentencias secuenciales y concurrentes. -El cuerpo de una architectura en VHDL está formado por sentencias concurrentes. - Las sentencias secuenciales sólo pueden aparecer en los cuerpos de subprogramas y dentro de sentencias process. - Algunas sentencias concurrentes tienen un equivalente secuencial; el uso de una forma u otra depende de su ubicación en el código VHDL. Sentencias concurrentes: block process assert asignación a señal instancias de componentes generate llamadas a procedimientos Sentencias secuenciales if, case, loop, null, wait, next, exit, assert asignación a señal, asignación a variable, llamadas a procedimientos, Declaración de variables Cuerpo del subprograma (procedure ó function) Subprograma (parte declarativa) Clasificación de sentencias secuenciales: - Sentencias de asignación, a variables o a señales. - Sentencias condicionales (if, case) - Sentencias iterativas (loop, exit, next) - Otras (wait, assert, null) y llamadas a subprogramas. Sentencias secuenciales Permiten modelar la funcionalidad de los componentes, dentro de procesos y en los cuerpos de subprogramas Sentencia de asignación de variable (:=) Sintaxis: nombre_variable := expresión; Sentencia if if condición then sentencias_secuenciales {elsif condición then sentencias_secuenciales;} [else sentencias_secuenciales;] end if; Sentencia case case expresión is when valor => sentencias_secuenciales; {when valor => sentencias_secuenciales;} end case; Sentencia loop [etiqueta:] [while condición_booleana | for control_repetición] loop sentencias-secuenciales; end loop [etiqueta]; control_repetición ::== identificador in rango_discreto En su forma básica (sin while ni for), la sentencia loop produce una ejecución continua (bucle infinito) del bloque de sentencias secuenciales. Hay dos sentencias asociadas con loop: Sentencia next: que finaliza la ejecución de la iteración actual para que inicie la siguiente: next [etiqueta_loop] [when condición_ booleana]; Sentencia exit: que finaliza la iteración actual y el bucle: exit [etiqueta_loop] [when condición_ booleana]; Hay que contemplar todos los posibles valores de la expresión de selección y no pueden solaparse las de distintas opciones de ejecución. Como valor puede emplearse un rango (con to), others, y la unión de varios valores (con | ). Sentencia de asignación a señal (<=) : nombre_señal <= [transport | inertial] {expresión_valor after expresión_tiempo, ...}; -Planifica los valores que irá tomando una señal a lo largo del tiempo. - Cada señal tiene asociado un valor actual (el que leen los distintos procesos) y un driver o cola de eventos. La ejecución de la asignación modifica dicho driver, añadiendo a él uno o varios pares <valor, tiempo>. s <= ‘0’ after 5 ns, ‘1’ after 10 ns, ‘0’ after 20 ns, ‘1’ after 25ns; - En simulación, el valor actual no se modifica hasta un tiempo de retardo indicado mediante after expresión_tiempo, o tras un tiempo mínimo (retardo-delta) - Normalmente, los sintetizadores RT-lógicos ignoran (o prohíben) la cláusula after. PROCESS (e) BEGIN S<= TRANSPORT NOT e AFTER 10 ns; END PROCESS; PROCESS (e) BEGIN S<= INERTIAL NOT e AFTER 10 ns; END PROCESS; Modalidades de retardo: transporte e inercial (valor por defecto). Sus diferencias importan en simulación y en el modelado funcional de circuitos o componentes básicos de bibliotecas de diseño. El modelo transporte propaga cualquier cambio que se produzca, mientras que el inercial hace que se filtren los cambios proyectados para tiempos anteriores a los impuestos en la asignación. (no entramos en más detalle, ya que para síntesis no afecta) Sentencia wait wait [on señal {,...} ] [until expresión_booleana] [for expresión_tiempo]; - Suspende la ejecución del proceso y fija las condiciones para su reactivación. - Se contemplan tres posibles cláusulas de reactivación: sensibilización (on signal,..), condición (con until) y temporización (con for) - La lista de sensibilización especifica el conjunto de señales a las que es sensible el proceso mientras está suspendido. Cuando ocurra un evento en alguna de ellas, se evalúa la condición. Si el resultado es true (o si se ha omitido la condición), se activa la ejecución del proceso a partir de la siguiente sentencia. - Si se ha omitido la cláusula de sensibilización, el proceso es sensible a todas las señales que aparecen en la expresión de condición. - La expresión de temporización indica el tiempo máximo que permanecerá suspendido el proceso. - Si se omiten todas las cláusulas, la suspensión del proceso es indefinida. Ź Los sintetizadores interpretan las sentencias wait sólo con ciertas clausulas y formas concretas de uso. 7 EJEMPLOS wait [on señal {,...} ] [until expresión_booleana] [for expresión_tiempo]; -- Generación de señal de reloj (para aplicación de estímulos de simulación): -- process begin reloj<= not reloj; wait for 10 ns;-- señal cuadrada de periodo 20 ns end process; --interpretación de wait con varias cláusulas de reactivación: wait on a, b until c = ´1´; --suspende hasta evento en a o en b, y que además se cumpla c=1. --es sensible sólo a a y b. Un evento en c no causa la activación. wait on a, b for 10ns; --suspende hasta evento en a o en b, o hasta que el tiempo avance 10ns. -- Puerta AND 2 entradas -- Descripción funcional process begin c <= a and b; wait on a,b; end process; -- Biestable D sensible a flanco de reloj -- Descripción funcional process begin q <= d; wait until clk =‘1’; --equivale a wait until clk’event and clk=‘1’; end process; Sentencia assert : assert expresión_booleana [report cadena_caracteres] [expresión_severidad]; - Se emplea en simulación para generar mensajes según se cumpla o no una determinada condición. - La cadena de caracteres se envía al dispositivo estándar de salida cuando no se cumple la condición. - La expresión_severidad debe ser del tipo enumerado severity_level, definido en el paquete standard, y puede tomar los valores: note, warning, error, y failure. Sentencia null: [etiqueta :] null; - Indica que no se realice acción alguna. Muy utilizada en sentencias case Llamadas secuenciales a subprogramas (procedure y function) dentro de un proceso : [etiqueta :] nombre_procedimiento [(parámetros)]; A diferencia de la llamada a procedimientos, las llamadas a funciones forman parte de expresiones en las asignaciones. Sintaxis: nombre_función [(parámetros)] Sentencia return: [etiqueta :] return [expresión] ; Termina la ejecución de un subprograma, pasando a ejecutar la instrucción siguiente a la que efectuó la llamada: Se utiliza en la definición del cuerpo de los subprogramas. Más adelante se verá la forma de definición de procedimientos y funciones La expresión de retorno se emplea cuando se trata de funciones 10 Sentencias concurrentes La descripción de una arquitectura en VHDL está formada por sentencias concurrentes Relación de sentencias concurrentes: process, asignación concurrente a señal, sentencias estructurales (component, generate, configuration, generic), bloques y llamadas concurrentes a subprogramas. Sentencia process : [etiqueta:] process [(nombre_señal {,...})] [is] declaraciones begin sentencias secuenciales; end process [etiqueta]; Sentencia concurrente que hace que se ejecute continuamente un grupo de sentencias secuenciales. La parte de declaraciones se emplea para declarar datos locales y subprogramas locales al proceso. Las señales entre paréntesis constituyen la lista (opcional) de sensibilidad del proceso, de manera que las dos descripciones siguientes son equivalentes: PROCESS BEGIN sentencias secuenciales; WAIT ON lista_de_sensibilidad; END PROCESS; PROCESS (lista_de_sensibilidad) BEGIN sentencias secuenciales; END PROCESS; Asignación concurrente a señal : Su sintaxis más sencilla coincide con la de una asignación secuencial: [etiqueta:] nombre_señal <= [transport] forma_onda; La diferencia está en que la asignación concurrente se ubica fuera de cualquier sentencia process, siendo en sí misma equivalente a un proceso con una asignación secuencial. La asignación concurrente es sensible a todas las señales que se encuentren en la parte derecha de la misma: a <= b; es equivalente al proceso: process (b) begin a <=b; end process; Las asignaciones concurrentes admiten además dos formas compuestas alternativas: asignación condicional y asignación con selección. Asignación concurrente condicional: [etiqueta:] nombre_señal <= [transport] {forma_de_onda when expresión_booleana else} forma_de_onda; La asignación se realiza cada vez que se produzca un evento en alguna de las señales de la expresión de asignación (forma_onda) o de la parte de condición (expresión_booleana). La asignación condicional es una forma compacta de expresar asignaciones secuenciales con la sentencia if dentro de un proceso: -- La sentencia: Z <= X0 when S = ‘0’ else X1; -- es equivalente a la construcción: process (S, X0, X1) begin if S = ‘0’ then Z <= X0; else Z <= X1; end if; end process; Asignación concurrente con selección: [etiqueta:] with expresión select nombre_señal <= [transport] {forma_de_onda when valor,} forma_de_onda when valor ; Es equivalente a un proceso que contenga asignaciones secuenciales en una sentencia case. El proceso equivalente se ejecuta cada vez que se produce un evento en alguna de las señales de la expresión de selección o de las formas de onda. Estas dos construcciones son equivalentes: with alu_op select result <= op1 + op2 when alu_suma, op1 – op2 when alu_resta, op1 nand op2 when alu_nand, op1 xor op2 when alu_xor; process (op1, op2, alu_op) begin case alu_op is when alu_suma => result <= op1 + op2; when alu_resta => result <= op1 – op2; when alu_nand => result <= op1 nand op2; when alu_xor => result <= op1 xor op2; end case; end process; Sentencias estructurales: En este grupo incluimos las sentencias component, generate, así como las construcciones configuration y generic. Componentes: definen módulos estructurales interconectables. Para utilizar un componente primero se declara y después se hacen copias del mismo (instancias). - Sintaxis de declaración de un componente: component nombre_de_componente [ generic (lista_de_genéricos);] [port (lista_de_puertos)]; end component ; - Sintaxis de la instanciación o referencia a un componente: etiqueta_instancia : nombre_de_componente [generic map (lista_asociación_de_genéricos)] [port map (lista_asociación_de_puertos);] La etiqueta es obligatoria Más adelante veremos el significado de generic 16 component Descripción estructural de un sumador completo en términos de semisumadores: Ejemplo de declaración e instaciación de componentes: entity SumadorCompleto is port (X,Y,CIn : in bit; COut,Sum: out bit); end SumadorCompleto; --------------- architecture Estructura of SumadorCompleto is signal A,B,C: bit; component Semisumador is port (I1,I2: in bit; COut, Sum: out bit); end component; component or_2 is port (e1,e2: in bit; y: out bit); end component; begin U1: Semisumador port map (X,Y,A,B); U2: Semisumador port map (B,CIn,C,Sum); U3: or_2 port map (A,C,COut); end Estructura; Obsérvese que sólo se están declarando los componentes utilizados, cuya definición detallada deberá también estar visible. La lista de asociación que definimos (con port map) al instanciar, puede ser posicional o por nombres: U2 : Semisumador port map (I1=>B, Sum=> Sum, I2=>Cin, Cout=>C); es equivalente a la asignación posicional anterior de la instancia U2.

Transcript of SED 04 1b Imprimir

Page 1: SED 04 1b Imprimir

1

4.1.2.4 Sentencias secuenciales y concurrentes.

-El cuerpo de una architectura en VHDL está formado por sentencias concurrentes.

- Las sentencias secuenciales sólo pueden aparecer en los cuerpos de subprogramas

y dentro de sentencias process.

- Algunas sentencias concurrentes tienen un equivalente secuencial; el uso de una

forma u otra depende de su ubicación en el código VHDL.

Sentencias concurrentes:

block

process

assert

asignación a señal

instancias de componentes

generate

llamadas a procedimientos

Sentencias secuenciales

if, case, loop, null,

wait, next, exit, assert

asignación a señal,

asignación a variable,

llamadas a procedimientos,

Declaración de variables

Cuerpo del subprograma

(procedure ó function)

Subprograma

(parte declarativa)

Clasificación de sentencias secuenciales:

- Sentencias de asignación, a variables o a señales.

- Sentencias condicionales (if, case)

- Sentencias iterativas (loop, exit, next)

- Otras (wait, assert, null) y llamadas a subprogramas.

Sentencias secuenciales

Permiten modelar la funcionalidad de los componentes, dentro de procesos y en los cuerpos de subprogramas

Sentencia de asignación de variable (:=)

Sintaxis: nombre_variable := expresión;

Sentencia if if condición then sentencias_secuenciales

{elsif condición then sentencias_secuenciales;}

[else sentencias_secuenciales;]

end if;

Sentencia case case expresión is

when valor => sentencias_secuenciales;

{when valor => sentencias_secuenciales;}

end case;

Sentencia loop

[etiqueta:] [while condición_booleana | for control_repetición] loop

sentencias-secuenciales;

end loop [etiqueta];

control_repetición ::== identificador in rango_discreto

En su forma básica (sin while ni for), la sentencia loop produce una ejecución continua (bucle infinito) del bloque de sentencias secuenciales.

Hay dos sentencias asociadas con loop:

Sentencia next: que finaliza la ejecución de la iteración actual para que inicie la siguiente:

next [etiqueta_loop] [when condición_ booleana];

Sentencia exit: que finaliza la iteración actual y el bucle:

exit [etiqueta_loop] [when condición_ booleana];

Hay que contemplar todos los posibles valores de la expresión de selección y no pueden solaparse las de distintas opciones de ejecución. Como valor puede

emplearse un rango (con to), others, y la unión de varios valores (con | ).

Sentencia de asignación a señal (<=) :

nombre_señal <= [transport | inertial] {expresión_valor after expresión_tiempo, ...};

-Planifica los valores que irá tomando una señal a lo largo del tiempo.

- Cada señal tiene asociado un valor actual (el que leen los distintos procesos) y un driver o cola de eventos. La ejecución de la asignación modifica dicho driver, añadiendo a él uno o varios pares <valor, tiempo>.

s <= ‘0’ after 5 ns, ‘1’ after 10 ns, ‘0’ after 20 ns, ‘1’ after 25ns;

- En simulación, el valor actual no se modifica hasta un tiempo de retardo indicado mediante after expresión_tiempo, o tras un tiempo mínimo (retardo-delta)

- Normalmente, los sintetizadores RT-lógicos ignoran (o prohíben) la cláusula after.

PROCESS (e) BEGIN

S<= TRANSPORT NOT e AFTER 10 ns;

END PROCESS;

PROCESS (e) BEGIN

S<= INERTIAL NOT e AFTER 10 ns;

END PROCESS;

Modalidades de retardo: transporte e inercial (valor por defecto).

Sus diferencias importan en simulación y en el modelado funcional de

circuitos o componentes básicos de bibliotecas de diseño.

El modelo transporte propaga cualquier cambio que se produzca, mientras

que el inercial hace que se filtren los cambios proyectados para tiempos

anteriores a los impuestos en la asignación.

(no entramos en más detalle, ya que para síntesis no afecta)

Sentencia wait

wait [on señal {,...} ] [until expresión_booleana] [for expresión_tiempo];

- Suspende la ejecución del proceso y fija las condiciones para su reactivación.

- Se contemplan tres posibles cláusulas de reactivación: sensibilización (on signal,..), condición (con until) y temporización (con for)

- La lista de sensibilización especifica el conjunto de señales a las que es sensible el

proceso mientras está suspendido. Cuando ocurra un evento en alguna de ellas, se evalúa

la condición. Si el resultado es true (o si se ha omitido la condición), se activa la ejecución

del proceso a partir de la siguiente sentencia.

- Si se ha omitido la cláusula de sensibilización, el proceso es sensible a todas las señales

que aparecen en la expresión de condición.

- La expresión de temporización indica el tiempo máximo que permanecerá suspendido el

proceso.

- Si se omiten todas las cláusulas, la suspensión del proceso es indefinida.

Los sintetizadores interpretan las sentencias wait sólo con ciertas clausulas y formas concretas de uso.

7

EJEMPLOSwait [on señal {,...} ] [until expresión_booleana] [for expresión_tiempo];

-- Generación de señal de reloj (para aplicación de estímulos de simulación):--processbeginreloj<= not reloj;wait for 10 ns;-- señal cuadrada de periodo 20 nsend process;

--interpretación de wait con varias cláusulas de reactivación:wait on a, b until c = ´1´;--suspende hasta evento en a o en b, y que además se cumpla c=1.--es sensible sólo a a y b. Un evento en c no causa la activación.wait on a, b for 10ns;--suspende hasta evento en a o en b, o hasta que el tiempo avance 10ns.

-- Puerta AND 2 entradas

-- Descripción funcional

process

begin

c <= a and b;

wait on a,b;

end process;

-- Biestable D sensible a flanco de reloj

-- Descripción funcional

process

begin

q <= d;

wait until clk =‘1’;

--equivale a wait until clk’event and clk=‘1’;

end process;

Sentencia assert :

assert expresión_booleana [report cadena_caracteres] [expresión_severidad];

- Se emplea en simulación para generar mensajes según se cumpla o no una determinada condición.

- La cadena de caracteres se envía al dispositivo estándar de salida cuando no se cumple la condición.

- La expresión_severidad debe ser del tipo enumerado severity_level, definido en el paquete standard, y puede tomar los valores: note, warning, error, y failure.

• Sentencia null:

[etiqueta :] null;

- Indica que no se realice acción alguna. Muy utilizada en sentencias case

Llamadas secuenciales a subprogramas (procedure y function) dentro de un proceso :

[etiqueta :] nombre_procedimiento [(parámetros)];

A diferencia de la llamada a procedimientos, las llamadas a funciones forman parte de expresiones en las asignaciones. Sintaxis:

nombre_función [(parámetros)]

Sentencia return:

[etiqueta :] return [expresión] ;

Termina la ejecución de un subprograma, pasando a ejecutar la instrucción siguiente a la que efectuó la llamada:

Se utiliza en la definición del cuerpo de los subprogramas.

Más adelante se verá la forma de definición de procedimientos y funciones

La expresión de retorno se emplea cuando se trata

de funciones

10

Sentencias concurrentes

La descripción de una arquitectura en VHDL está formada porsentencias concurrentes

Relación de sentencias concurrentes: process, asignación concurrente a señal, sentencias estructurales

(component, generate, configuration, generic), bloques y llamadas concurrentes a subprogramas.

Sentencia process :

[etiqueta:] process [(nombre_señal {,...})] [is]

declaraciones

begin

sentencias secuenciales;

end process [etiqueta];

• Sentencia concurrente que hace que se ejecute continuamente un grupo de sentencias secuenciales.

• La parte de declaraciones se emplea para declarar datos locales y subprogramas locales al proceso.

• Las señales entre paréntesis constituyen la lista (opcional) de sensibilidad del proceso, de manera que las dos descripciones siguientes son equivalentes:

PROCESS

BEGIN

sentencias secuenciales;

WAIT ON lista_de_sensibilidad;

END PROCESS;

PROCESS (lista_de_sensibilidad)

BEGIN

sentencias secuenciales;

END PROCESS;

Asignación concurrente a señal :

Su sintaxis más sencilla coincide con la de una asignación secuencial:

[etiqueta:] nombre_señal <= [transport] forma_onda;

• La diferencia está en que la asignación concurrente se ubica fuera de cualquier sentencia process, siendo en sí misma equivalente a un proceso con una asignación secuencial.

• La asignación concurrente es sensible a todas las señales que se encuentren en la parte derecha de la misma:

a <= b; es equivalente al proceso: process (b)

begin

a <=b;

end process;

Las asignaciones concurrentes admiten además dos formas compuestas alternativas:

asignación condicional y asignación con selección.

Asignación concurrente condicional:

[etiqueta:] nombre_señal <= [transport]

{forma_de_onda when expresión_booleana else}

forma_de_onda;

• La asignación se realiza cada vez que se produzca un evento en alguna de las señales de la expresión de asignación (forma_onda) o de la parte de condición (expresión_booleana).

• La asignación condicional es una forma compacta de expresar asignaciones secuenciales con la sentencia if dentro de un proceso:

-- La sentencia:Z <= X0 when S = ‘0’ else X1;

-- es equivalente a la construcción:process (S, X0, X1)begin

if S = ‘0’ thenZ <= X0;

elseZ <= X1;

end if;end process;

Asignación concurrente con selección:

[etiqueta:] with expresión select nombre_señal <= [transport]

{forma_de_onda when valor,}

forma_de_onda when valor ;

• Es equivalente a un proceso que contenga asignaciones secuenciales en una sentencia case.

• El proceso equivalente se ejecuta cada vez que se produce un evento en alguna de las señales de la expresión de selección o de las formas de onda.

• Estas dos construcciones son equivalentes:

with alu_op selectresult <= op1 + op2 when alu_suma,

op1 – op2 when alu_resta,op1 nand op2 when alu_nand,

op1 xor op2 when alu_xor;

process (op1, op2, alu_op)begin

case alu_op is

when alu_suma => result <= op1 + op2;

when alu_resta => result <= op1 – op2;

when alu_nand => result <= op1 nand op2;

when alu_xor => result <= op1 xor op2;

end case;

end process;

Sentencias estructurales:

En este grupo incluimos las sentencias component, generate, así como las

construcciones configuration y generic.

Componentes: definen módulos estructurales interconectables. Para utilizar un

componente primero se declara y después se hacen copias del mismo (instancias).

- Sintaxis de declaración de un componente:

component nombre_de_componente

[ generic (lista_de_genéricos);]

[port (lista_de_puertos)];

end component ;

- Sintaxis de la instanciación o referencia a un componente:

etiqueta_instancia : nombre_de_componente

[generic map (lista_asociación_de_genéricos)]

[port map (lista_asociación_de_puertos);]La etiqueta es obligatoria

Más adelante veremos el significado de generic

16

component

• Descripción estructural de un sumador completo en términos de semisumadores:

Ejemplo de declaración e instaciación de componentes:

entity SumadorCompleto is

port (X,Y,CIn : in bit; COut,Sum: out bit);

end SumadorCompleto;

---------------

architecture Estructura of SumadorCompleto is

signal A,B,C: bit;

component Semisumador is

port (I1,I2: in bit; COut, Sum: out bit);

end component;

component or_2 is

port (e1,e2: in bit; y: out bit);

end component;

begin

U1: Semisumador port map (X,Y,A,B);

U2: Semisumador port map (B,CIn,C,Sum);

U3: or_2 port map (A,C,COut);

end Estructura;

Obsérvese que sólo se están declarando los componentes utilizados, cuya definición detallada deberá también estar visible.

La lista de asociación que definimos (con port map) al instanciar, puede ser posicional o por

nombres:

U2 : Semisumador port map (I1=>B, Sum=> Sum, I2=>Cin, Cout=>C);

es equivalente a la asignación posicional anterior de la instancia U2.

Page 2: SED 04 1b Imprimir

Sentencia generate: permite definir estructuras repetitivas (equivalentes a instanciaciones

múltiples de componentes) o múltiples copias de sentencias concurrentes (incluida la propia

generate).

etiqueta_generate : { [for especificiación_for | if condición] } generate

{ sentencias concurrentes; }

end generate;La etiqueta es obligatoria

Ejemplo de generate con for: Descripción de un registro de N bits como instancia múltiple de un biestable o flip-flop tipo D:

entity Registro isgeneric (N : positive:=4);port ( Reloj : in bit:

X : in bit_vector(N-1 downto 0);Z : out bit_vector(N-1 downto 0));

end Registro; -------------------architecture Estructura of Registro iscomponent FF_D is

port(reloj, D: in bit; Q: out bit);end component;

beginGeneraRegistro: for I in 0 to N-1 generate

R: FF_D port map (reloj,X(I),Z(I));end generate;

end Estructura;

Declaración del componente FF_D

La instanciación de FF_D es en este ejemplo la sentencia concurrente de la que se ‘generan’ múltiples copias

Tamaño genérico, que debe particularizarse al instanciarlo

La construcción generic permite definir valores genéricos de parámetros en la entidad y en la declaración de componentes. Estos valores deben concretarse cuando se instancia (con generic map).

El registro de tamaño genérico N que hemos definido en el ejemplo anterior, al instanciarlo debemos concretar su tamaño. Por ejemplo, para un tamaño de 16 bits, una instancia del registro podría tener la forma:

Registro_16 : Registro generic map (16)

port map (Reloj, Entrada, Salida);

En donde Entrada y Salida quedarían como puertos de 16 bits.

Si no se concreta ningún tamaño, tomaría el valor por defecto en la declaración (4 en este ejemplo)

Ejemplo de generate con if: Descripción de sumador para palabras de N bits.Se utilizan tres sentencias generate con if dentro de una generate con for.

La conectividad del primer (I0) y último (IN_1) sumadores de un bit se definen de manera distinta al resto.

Configuración de un diseño (configuration):

Los simuladores “genuinos” de VHDL, así como algunos sintetizadores, requieren

dos etapas (analyze y elaborate) para componer la representación interna de un

diseño completo formado por una o varias entidades.

Con analyze se obtienen representaciones intermedias de todas las arquitecturas asociadas a las distintas entidades; representaciones que se guardan en la biblioteca work.

Elaborate compone el diseño total a partir de los módulos analizados disponibles en work y de otras bibliotecas de diseño visibles, llegando a una expresión del diseño como una red global de procesos interconectados.

La construcción configuration se utiliza para identificar qué arquitectura se debe emplear para cada entidad en el proceso de elaboración del diseño.

No suele ser necesario su uso cuando sólo tenemos definida una arquitectura para la entidad (Prescindimos aquí de detallar la forma de declarar y usar configuraciones).

NOTA: a partir del VHDL-93 se permite instanciar componentes sin haberlos

declarado previamente, especificando en la misma instancia la entidad y la

arquitectura a utilizar: etiqueta_referencia:

entity nombre_entidad[(nombre_arquitectura)]

[generic map (lista _genéricos);]

[port map (lista_puertos);]

Sentencia assert concurrente : equivale a un proceso con un assert secuencial (el

mismo formato), cuya lista de sensibilidad comprende todas las señales que aparecen en su

expresión booleana.

Sentencia block : permite agrupar (e identificar con un nombre) a un conjunto de

sentencias concurrentes. Sintaxis básica:

Etiqueta: block

{declaraciones}

begin

{sentencias concurrentes}

end block [etiqueta];

• La etiqueta es obligatoria.

• Las declaraciones están visibles sólo para

las sentencias del bloque (incluidos sub-bloques)

Llamadas a subprogramas (procedure y function) y su definición :

• Las llamadas son concurrentes cuando se emplean dentro de una arquitectura pero fuera de una sentencia process. El subprograma se ejecuta cada vez que se produzca un evento en alguno de sus parámetros de entrada.

• La sintaxis de llamada es la misma que en las construcciones secuenciales.

• Al sintetizar, los subprogramas producen bloques de hardware combinacional (similar a la instanciación de componentes combinacionales).

La definición de los subprogramas (al igual que ocurre con los componentes y las entidades)

consta de dos partes: declaración y cuerpo de subprograma.

• La declaración define su interfaz (nombre, parámetros y sus tipos, y valor de retorno en el

caso de funciones).

• El cuerpo del subprograma especifica una implementación del algoritmo que lo define.

• Usualmente, cuando se definen subprogramas en paquetes de bibliotecas, sus

declaraciones aparecen en la declaración del paquete, y sus cuerpos en el cuerpo del

paquete.

Funciones (function):

Sólo un valor de retorno, cero o más parámetros de entrada.

Declaración: function nombre_funcion [(declaraciones_de_parámetros)]

return nombre_de_tipo;

Procedimientos (procedure):

Cero o más parámetros de entrada (in), salida (out) o entrada/salida (inout).

Declaración: procedure nombre_proc [(declaraciones_de_parámetros)];

Sintaxis de la declaración de subprogramas:

(Las declaraciones de parámetros tienen una sintaxis similar a las declaraciones de puertos de entidades)

Cuerpo de una función:

function nombre_funcion [(declaraciones_de_parámetros)]

return nombre_de_tipo is

{declaraciones}

begin

{sentencias secuenciales}

end [nombre_función];

Cuerpo de un procedimiento:

procedure nombre_proc [(declaraciones_de_parámetros)] is

{declaraciones}

begin

{sentencias secuenciales}

end [nombre_proc];

Definición del cuerpo de subprogramas:

Funciones de resolución:

•En un diseño VHDL cada señal debe tener un único driver. Cuando haya varios procesos fuente que pueden actuar como drivers de una señal, debe emplearse algún mecanismo que decida qué valores se van a proyectar para la señal.

• Para simulación se emplean funciones de resolución, que devuelven un valor resuelto (resolved) en caso de conflicto. (Ejem.: véase la definición std_logic como subtipo de datos resuelto de std_ulogic, en el paquete std_logic_1164 de la biblioteca IEEE).

EXTRACTO de ...\libraries\ieee\std_1164.vhd

26

-- EJEMPLO1: DISEÑO VHDL QUE PRODUCE UN TRI-ESTADO AL SINTETIZAR-- SI LA SEÑAL DE DESTINO ES UN PORT, DEBE DECLARARSE COMO INOUT-- (en FPLDs será aplicable en aquellas celdas/bloques que admitan -- configuración de salida triestado; normalmente sólo las E/S del chip)

LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;

ENTITY tristate ISPORT( Entrada, Control : IN STD_LOGIC;

Salida : INOUT STD_LOGIC); END tristate;

ARCHITECTURE behavior OF tristate ISBEGIN

Salida <= Entrada WHEN Control = '0' ELSE 'Z';

END behavior;

En cambio, para síntesis deben emplearse construcciones que eviten el posible conflicto en líneas o buses, forzando a que la herramienta de síntesis infiera o elementostriestado o bien multiplexores.

Ejemplos:

27

-- EJEMPLO2: DOS CONSTRUCCIONES QUE SINTETIZAN COMO MULTIPLEXORES--LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;ENTITY multiplexor IS

PORT( X0, X1, S : IN STD_LOGIC;Mux_Out1, Mux_Out2 : OUT STD_LOGIC );

END multiplexer;ARCHITECTURE behavior OF multiplexer ISBEGIN

Mux_Out1 <= X1 WHEN S = '1' ELSE X0;

PROCESS ( X0, X1, S)BEGIN

IF S = '0' THEN Mux_Out2 <= X0;

ELSEMux_Out2 <= X1;

END IF;END PROCESS;

END behavior;