Since VHDL-2008, it's possible to specify a different rejection time compared to the delay time if the delay model is inertial.
Inertial delay (default delay mechanism). All three signal assignments are synonymous:
S2 <= S1 after 100 ns;
S2 <= inertial S1 after 100 ns;
S2 <= reject 100 ns inertial S1 after 100 ns;
The transport delay mechanism. All three signal assignments are synonymous:
S3 <= transport S1 after 100 ns;
S3 <= reject 0 ns inertial S1 after 100 ns;
S3 <= S1'delayed(100 ns);
Why does the inertial delay do?
Commonly spoken: All projected waveform assignments of signal spikes shorter than the rejection limit are canceled. This is called pulse rejection.
Let's investigate inertial delays with different rejection times:
S1 <= '1' after 10 ns, '0' after 20 ns;
S4_inertial_5 <= reject 5 ns inertial S1 after 100 ns; -- not filtered
S4_inertial10 <= reject 10 ns inertial S1 after 100 ns; -- under investigation
S4_inertial20 <= reject 20 ns inertial S1 after 100 ns; -- filtered
It's obvious that the 10 ns pulse is delayed to S4_inertial_5 after 100 ns, because it filters only pulses up to 5 ns. The signal S4_inertial20 has no events, because it gets filtered. For S4_inertial_5, the rejection limit is greater than the pulse width.
So lets have a closer look at:
S5_inertial10_after_10 <= reject 10 ns inertial S1 after 10 ns; -- not filtered
S5_inertial10_after100 <= reject 10 ns inertial S1 after 100 ns; -- filtered
Now, we see a different behavior if the delay is longer. If the delay is the same as the rejection time, the pulse gets delayed, otherwise canceled.
I tested: GHDL, ModelSim and Riviera-PRO. All show the same behavior.
My question is:
Why does pulse rejection behave differently for the same rejection limit, but for different delays? Or in other words: Is rejection an inclusive or exclusive operation and why changes xxclusiveness based on the total delay?
Here is a working testbench for own experiments:
entity E is
end entity;
architecture A of E is
signal S1 : bit := '0';
signal S2_inertial : bit;
signal S2_reject1 : bit;
signal S2_reject2 : bit;
constant LEVEL : severity_level := ERROR; -- FAILURE;
begin
S1 <= '1' after 10 ns, '0' after 20 ns;
S2_inertial <= inertial S1 after 100 ns;
S2_reject1 <= reject 10 ns inertial S1 after 100 ns;
S2_reject2 <= reject 10 ns inertial S1 after 10 ns;
CheckInertial: process
begin
wait until S2_inertial = '1' for 200 ns;
assert (S2_inertial = '0') report "CheckInertial: Pulse was not rejected!" severity LEVEL;
wait;
end process;
CheckReject1: process
begin
wait until S2_reject1 = '1' for 115 ns;
assert (S2_reject1 = '1') report "CheckReject1: Pulse has not passed rejection limit!" severity LEVEL;
assert (now = 110 ns) report "CheckReject1: Delayed pulse with rejection was not received at 110 ns!" severity LEVEL;
wait;
end process;
CheckReject2: process
begin
wait until S2_reject2 = '1' for 200 ns;
assert (S2_reject2 = '1') report "CheckReject2: Pulse has not passed rejection limit!" severity LEVEL;
assert (now = 20 ns) report "CheckReject2: Delayed pulse with rejection was not received at 20 ns!" severity LEVEL;
wait;
end process;
end architecture;
Edit 1: Added waveform
The following waveform shows, that S2_reject1 (name from the testbench - equal to S5_inertial10_after100 in the question test) has no pulse.
My expectation would be to see a delayed pulse for both signals, irrespectively of the delay length.
