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.