Puesto que los dispositivos y las conexiones entre los dispositivos tienen retardos asociados, para simular de manera precisa el comportamiento de los circuitos es necesario modelar adecuadamente su retardo. De hecho, hay circuitos que no funcionan adecuadamente cuando son simulados si no se toman en consideraci´on los retardos que se producen en ellos.
Una recomendaci´on cuando se modelan circuitos digitales es asignar alg´un retardo (incluso un retardo arbitrario, como 1 ns) a todas las operaciones al nivel de transferencia entre registros usadas en el c´odigo VHDL que describe el circuito. Obs´ervese, no obstante, que esos retardos no son soportados al realizar la s´ıntesis: algunas herramientas de s´ıntesis simplemente los ignoran, mientras que otras obligan al dise˜nador a poner esos retardos a cero o a eliminarlos del c´odigo. Los retardos pueden ser modelados mediante varios m´etodos. A continuaci´on se describen algunos de ellos.
2.7.1 Sentencia wait
El m´etodo m´as sencillo de modelar un retardo es emplear la sentencia wait, indicando el n´umero de unidades de tiempo que debe durar la espera. Por ejemplo, la sentencia:
wait for 10 ns;
dentro de un bloque process, hace que la ejecuci´on del bloque se detenga durante 10 nanosegundos.
Pueden usarse otras formas de la sentencia wait. Por ejemplo, la sentencia:
wait;
dentro de un bloque process, hace que ´este se quede esperando indefinidamente, con lo cual se detiene la ejecuci´on del bloque.
Asimismo, las construcciones:
wait until <condici´on>;
wait until <lista de se~nales>;
dentro de un bloque process, detienen la ejecuci´on del bloque hasta que la condici´on booleana se haga verdadera, o hasta que alguna de las se˜nales de la lista cambie de valor, respectivamente.
Si la sentencia:
wait until <lista de se~nales>;
es la primera sentencia de un bloque process (esta en concreto es la ´unica forma de uso de la sentencia wait permitida para s´ıntesis), entonces es equivalente a usar<lista de se~nales> como la lista de se˜nales a las que el bloque process es sensible.
2.7.2 Retardos en la asignación a señales
Pueden especificarse retardos en las asignaciones a se˜nales usando la palabra reservada after. Por ejemplo, puede modelarse el comportamiento de una puerta NAND con un retardo de propagaci´on de 2 ns mediante la sentencia:
y <= x0 nand x1 after 2 ns;
Cuando se encuentra esta sentencia en la simulaci´on, se emplean los valores actuales de x0 y x1 para calcular el resultado de la operaci´on x0 nand x1. Este resultado no se asigna a y hasta transcurridos 2 ns.
Sin embargo, esto no implica que la siguiente sentencia no sea ejecutada hasta que transcurran los 2 ns. Al contrario, la siguiente sentencia es ejecutada inmediatamente, aun cuando estas sentencias sean parte de un bloque process. As´ı pues, el cambio en la se˜nal y no habr´a ocurrido en el instante en el cual se ejecute la siguiente sentencia.
Para especificar que la simulaci´on se detenga durante un periodo de tiempo antes de que la siguiente sentencia sea ejecutada, debe usarse el comando wait.
2.7.3 Retardo inercial y de transporte
Cuando se realiza una descripci´on jer´arquica del circuito, cobran importancia los conceptos de retardo inercial y retardo de transporte.
Un dispositivo l´ogico real tiene la propiedad de que un glitch en un puerto de entrada, con una duraci´on inferior al retardo de propagaci´on del dispositivo, no tiene efecto sobre la salida del dispositivo. Se denomina glitch a un cambio temporal (un pico de subida o bajada) e inesperado en el voltaje.
Por ejemplo, si una puerta NAND tiene un retardo de propagaci´on de 1 ns, entonces un glitch de 0.5 ns (un 0 ´o 1 temporal, de duraci´on 0.5 ns) en una de sus entradas no produce ning´un cambio en su salida.
Este tipo de comportamiento del retardo se denomina retardo inercial y es el modelo del retardo usado por defecto para todos los dispositivos en VHDL.
Otro tipo alternativo de modelo del retardo, en el cual todos los glitches a la entrada se manifiestan en la salida, se denomina retardo de transporte. Este tipo de comportamiento se modela usando la palabra clave transport tras el operador de asignaci´on (<=).
El modo recomendado de modelar el retardo en el c´odigo VHDL sintetizable es el retardo inercial.
2.7.4 Retardo delta
Es importante tener en cuenta que todas las operaciones que involucran se˜nales poseen un retardo, dado que todas las se˜nales en los circuitos f´ısicos experimentan retardos cuando pasan a trav´es de los dispositivos y las conexiones.
En vista de ello, aunque no se especifique de manera expl´ıcita en el c´odigo VHDL el retardo, todas las se˜nales son simuladas someti´endolas a un retardo en cada operaci´on de asignaci´on o instanciaci´on de un subcircuito.
As´ı pues, cuando se ejecuta una sentencia en la que se asigna un nuevo valor a una se˜nal, se aplica por defecto un retardo de valor delta. Es decir, un retardo infinitesimal, inferior al incremento de tiempo m´as peque˜no que puede ser especificado en VHDL, que es un femtosegundo (1 fs = 10−15s).
Como consecuencia de este m´etodo de retardo delta empleado en la simula- ci´on, cuando se asigna un valor a una se˜nal en VHDL, hay dos eventos de inter´es:
1. Se calcula el nuevo valor y se planifica el cambio en la se˜nal. 2. Transcurrido un tiempo delta, se asigna a la se˜nal su nuevo valor.
Este comportamiento no tiene un efecto apreciable para las sentencias de asignaci´on que est´an fuera de bloques process, que en cualquier caso se ejecutan concurrentemente.
Sin embargo, tiene un efecto importante en las asignaciones a se˜nales que est´an dentro de bloques process:
1. Se planifica el cambio en la se˜nal antes de que se ejecute la siguiente sentencia.
2. El cambio en el valor de la se˜nal debido a la primera sentencia ocurre despu´es de que se haya planificado el cambio debido a la siguiente sentencia, para lo cual se usan los valores de las se˜nales en el instante actual.
As´ı pues, una cadena de asignaciones a se˜nales contenida en un bloque pro- cess se comporta de manera diferente a un conjunto de sentencias en un lenguaje de programaci´on. Por ejemplo, suponga el siguiente fragmento de c´odigo VHDL:
process (clk) is begin
if rising_edge(clk) then b <= a;
c <= b; ...
Puesto que b y c son se˜nales, existe un retardo delta antes de que se produzca la asignaci´on del nuevo valor a b. Antes de que transcurra este retardo, se calcula el nuevo valor de la variable c, us´andose para ello el valor “antiguo” de b. En este ejemplo, la se˜nal c adquiere el valor que ten´ıa la se˜nal b en el anterior ciclo de reloj, dado que el proceso es activado ´unicamente en los flancos de subida de la se˜nal de reloj.
La discusi´on anterior acerca del retardo delta no aplica a las asignaciones a variables. De hecho, ni siquiera es posible asociar un retardo a una asignaci´on a una variable (no pueden usarse sentencias de la forma a := b after c ns;). Las asignaciones a variables ocurren inmediatamente, sin retardos delta, lo cual es razonable considerando que las variables en VHDL est´an ideadas para ser usadas como las variables de los programas de los lenguajes de programaci´on.
As´ı pues, dada una cadena de asignaciones a variables contenida dentro de un bloque process, estas asignaciones a variables se realizan de manera estric- tamente secuencial (de la misma forma que se ejecutan las sentencias en C o en Fortran).
2.7.5 Caso práctico
El modelo mostrado a continuaci´on pretende ilustrar los conceptos relacionados con el retardo expuestos en esta secci´on, as´ı como la diferencia entre las se˜nales y las variables en lo que respecta al retardo.
En primer lugar, se muestra el c´odigo de una puerta NAND con un retardo inercial del 2 ns, y a continuaci´on el c´odigo del banco de pruebas.
--- -- Puerta NAND con retardo inercial
library IEEE;
use IEEE.std_logic_1164.all;
entity nand2 is port
( y0 : out std_logic; x0, x1 : in std_logic);
end entity nand2;
architecture nand2 of nand2 is begin
y0 <= x0 nand x1 after 2 ns; -- Retardo inercial de 2 ns
end architecture nand2;
--- -- Banco de pruebas de diferentes retardos
library IEEE;
use IEEE.std_logic_1164.all;
entity retardo_bp is end entity retardo_bp;
architecture retardo_bp of retardo_bp is signal s1, s2, s3, s4 : std_logic;
signal in1, in2 : std_logic;
component nand2 is port
( y0 : out std_logic; x0, x1 : in std_logic);
end component nand2;
begin
-- Crear el UUT para el test
g0 : component nand2 port map (s1, in1, in2);
s2 <= in1 nand in2 after 2 ns; -- Misma forma de onda que s1
process is
variable var1, var2 : std_logic;
begin
for i in 0 to 4 loop -- Itera 5 veces
var1 := in1 nand in2;
var2 := var1; -- var2 debe ser igual a var1
s3 <= in1 nand in2;
s4 <= s3; -- s4 debe ser igual al valor -- antiguo de s3
wait for 10 ns; -- Repetir para 0, 10, 20, 30 y 40 ns
end loop;
wait; -- Detiene el proceso
end process;
-- Crear los vectores de test
in1 <= ’1’;
in2 <= ’0’, -- in2 comienza a 0 ’1’ after 10 ns, ’0’ after 11 ns, -- Pulso de 1 ns
-- en el instante 10 ns ’1’ after 20 ns, ’0’ after 22 ns, -- Pulso de 2 ns
-- en el instante 20 ns ’1’ after 26 ns, ’0’ after 29 ns; -- Pulso en el instante 26 ns
end architecture retardo_bp;
Las formas de onda obtenidas de la simulaci´on se muestran en la Figura 2.5. La se˜nal in2 comienza con el valor 0 y tiene pulsos en los instantes 10, 20 y 26 ns. Sin embargo, el pulso en el instante 10 ns es m´as corto que el retardo de propagaci´on de la puerta NAND y de la asignaci´on a la se˜nal s2. Por ello, las se˜nales s1 y s2 ignoran ese pulso.
Figura 2.5:Formas de onda obtenidas de simular el banco de pruebas.
Debido al retardo de 2 ns, el valor de las se˜nales s1 y s2 no est´a definido hasta el instante 2 ns. Por ello, estas se˜nales inicialmente tienen el valor U.
Inicialmente, la se˜nal s3 est´a indefinida. Toma el valor 0 en el instante 10 + ∆ ns, puesto que in1 e in2 valen 1 en el instante 10 ns. Finalmente, cambia al valor 1 en el instante 30 + ∆ ns.
La se˜nal s4 va un ciclo retrasada respecto a s3.
La variable var1 toma los mismos valores que s3, excepto que la variable var1 no tiene el retardo delta (∆) de la variable s3.
La variable var2 toma los mismos valores que la variable var1.