Asignaciones con after y señales

Estoy tratando de entender cómo funcionan las asignaciones con 'después de foo', así que leí sobre el modelo de retraso 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 qué está pasando aquí?


EDITAR: para ser claros, mi problema aquí es que, si el comportamiento que estoy describiendo es realmente predeterminado, suena como una terrible fuga de abstracción: cuando escribo

goes_out <= temp after 10ns;

el comportamiento que espero sería uno que simule la activación de un pestillo (la temperatura es la entrada, la salida es la salida), por lo que la temperatura tendría que mantener su nuevo valor durante 10 ns para accionar correctamente el pestillo (de ahí el "retraso inercial " modelo).

Ahora, si este fuera realmente el caso, el comportamiento adecuado para mi circuito sería no hacer nada, ya que intento escribir una 'Z' en going_out e inmediatamente después de eso, esa 'Z' se sobrescribe con un '1', por lo tanto , el valor de temp que acciona el pestillo no se conserva y no se puede accionar does_out. (Obviamente, no puede manejar pestillos con 'Z', pensé que podría usar '0' y '1' y mi punto se mantendría)

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

Respuestas (2)

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 desencadena el process(input). La primera línea temp <= input;pone en cola la asignación de 1 temp inmediatamente después del paso de tiempo actual . tempconserva el valor de 0 para la ejecución de la siguiente línea, lo que se interpreta como "poner en cola la asignación del valor que temptenía al inicio de este proceso para ser asignado goes_outen 10ns de tiempo".

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

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

tempno ha cambiado en el momento en que lo lee para asignarlo a goes_out. Hasta que pase algún tiempo (es decir, todos los procesos desencadenados durante este ciclo delta se hayan completado), las asignaciones realizadas en esos procesos simplemente se programan para que sucedan en el siguiente paso de tiempo.

Podrías hacerlo:

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

Las wait for 0 ps;fuerzas para que pase algún tiempo (0ps cuenta como forzar la finalización de los ciclos delta)

No funcionó. El compilador dice: "el proceso no puede tener una declaración de espera y una lista de sensibilidad".
Sí, no puse un proceso completo, fue solo para mostrar cómo hacer que el tiempo pase. Consulte la actualización del código que muestra todo el proceso.