Asignaciones con después y señales

1

Estoy tratando de entender cómo funcionan las asignaciones con 'after foo', así que leí sobre el modelo de demora y simulé el siguiente código:

library IEEE;
use ieee.std_logic_1164.all;

entity test is
    port (
          goes_in, goes_out : out std_logic := 'U'
         );
end entity;

architecture a of test is
signal temp  : std_logic := 'U';
signal input : std_logic := 'Z';

begin
    goes_in <= input;
process (input)
    begin
    temp <= input;
    goes_out <= temp after 10ns; -- (*)
    end process;

--Removing the line with the (*) and uncommenting the following snippet solves the problem.
--process (temp)
--    begin
--    goes_out <= temp after 10ns;
--    end process;    
process
    begin
    input <= '0';
    wait for 15 ns;
    input <= '1';
    wait;
    end process;    
end a;

En Vivaldo de Xilinx, obtengo el siguiente resultado:

time(ns) :            10      15      20      25
                              _________   ________________________  ...  
goes_in  : _______'0'________/         '1'

goes_out : ----'U'-----|---------'Z'----------\_____'0'___________  ...

Cuando lo que esperaba era simplemente un retraso de 10 ns. ¿Alguien puede explicar lo que está pasando aquí?

EDITAR: Para ser claro, lo que quiero decir aquí es que, si el comportamiento que estoy describiendo es por defecto, suena como una terrible filtración de abstracción: cuando escribo

goes_out <= temp after 10ns;

el comportamiento que espero sea uno que simule un pestillo que se está activando (temp es la entrada, goes_out es la salida), por lo que tendría que mantener su nuevo valor durante 10 n para activar correctamente el pestillo (de ahí la modelo de "retraso inercial").

Ahora, si este fuera el caso, el comportamiento adecuado para mi circuito sería no hacer nada, ya que intento escribir una 'Z' a go_out e inmediatamente después de eso, esa 'Z' se sobrescribe con un '1 '- por lo tanto, el valor de la temperatura de activación del pestillo no se mantiene, y falla la conducción de go_out. (obviamente no puedes manejar los pestillos con 'Z', pensé que podría usar '0' y '1' y mi punto se mantendría)

Entonces, mi pregunta es: ¿hay alguna buena razón para este extraño comportamiento? Para mí, parece trivial "hacer las cosas bien": el algoritmo que simula el retraso inercial podría verificar los cambios en el valor de temp en el ciclo delta al que se asigna goes_out, y cancelar la asignación si algo está sucediendo, en lugar de eso de solo cancelar la asignación si el NUEVO valor de temp no cambia.

    
pregunta FrancoVS

2 respuestas

1

La clave aquí es su uso de <= , lo que hace que las asignaciones se realicen en paralelo.

Considere la asignación de 1 a input . Eso dispara el process(input) . La primera línea temp <= input; pone en cola la asignación de 1 a temp inmediatamente después del paso de tiempo actual . temp retiene el valor de 0 para la ejecución de la siguiente línea, que se interpreta como "poner en cola la asignación del valor que temp tenía al inicio de este proceso para ser asignado a goes_out en 10 ns tiempo".

Si lo contraes en goes_out <= input after 10ns; y eliminas temp por completo, parece un poco más intuitivo. O vea los valores de temperatura y entrada en su simulador.

    
respondido por el pjc50
1
process
begin
    temp <= input;
    goes_out <= temp after 10ns; -- (*)
end process;

temp no ha cambiado en el momento en que lo lees para asignarlo a goes_out . Hasta que pase algún tiempo (es decir, todos los procesos activados durante este ciclo delta se hayan completado), las asignaciones realizadas en esos procesos simplemente se programarán en el próximo paso de tiempo.

Podrías hacer:

process
begin
    wait until input'event;
    temp <= input;
    wait for 0 ps;
    goes_out <= temp after 10ns;
end process;

El wait for 0 ps; obliga a pasar un tiempo (0ps cuenta como forzando los ciclos delta para finalizar)

    
respondido por el Martin Thompson

Lea otras preguntas en las etiquetas