Search code examples
vhdldelaysimulationxilinxtest-bench

Delay in VHDL process between adjacent statements


I'm experimenting with VHDL and have come across a delay that I can't get rid of.

I'm attempting to program a very simple 3 input AND gate on a testbench that cycles through all the possibly inputs for the AND3 and the subsequent output. I've tied one input high to make its evaluation simpler in the simulation.

I've run the simulation that cycles between the 8 values for the 3 inputs (with the 3rd input ignored) however, between iterating the number and its assignment to an input, despite the fact that these statements are immediately following, there is a 100ns delay - why? A 100ns delay between iterations is understandable as that's intentional, but I dont see why theres a 100 ns delay between the two lines indicated below when they run sequentially?

enter image description here

I've put the definition, testbench below,

Thanks very much!

--ENTITY AND3 (3 input AND gate) --
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity and3 is
    port(
        a, b, c : in  std_logic;
        o       : out std_logic
    );
end entity and3;
architecture RTL of and3 is
begin
    o <= (a and b and c) after 5 ns;
end architecture RTL;

--TESTBENCH FOR AND3 with 3rd input left open (tied high)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity testAnd3 is
end entity testAnd3;                    -- no ports for a test bench

architecture io of testAnd3 is
    component And3 is
        port(x, y, z : in  std_logic:= '1'; --Sets default value if left open; 
             o       : out std_logic
        );
    end component And3;
    signal a, b, c   : std_logic:='0';
   signal iteration : unsigned(2 downto 0):= (others => '0');

begin
    g1 : And3 port map(x => a, y => b, z => open, o => c); --map signals to And ports 
    stim_process : process 
    begin
        iteration <= iteration + 1;     --//100 ns delay between here and next line!?
        a <= iteration(0);
        b <= iteration(1);
        wait for 100 ns;
    end process;

end architecture io;

Solution

  • The problem is the <= assign in:

    iteration <= iteration + 1;
    

    This <= does not update the read value of iteration until after a delta delay, so the a <= iteration(0); does not see the incremented value immediately after, but will first see it in the next iteration, thus after the wait for 100 ns;.

    This can be fixed by either of:

    • moving the assign to a and b outside the process (suggested solution since it matches coding style of synthesizable code)
    • moving iteration <= iteration + 1; to just before the wait for 100 ns;, whereby the wait will "hide" the delay in update of iteration value (waveform will be the same; see comment below)
    • changing iteration to a local variable in the process, since variable assign using := happens immediately.

    Note that the delay in update of signals assigned with <= is a key feature of VHDL, since it ensures that all clocked processes will see the same value, independent of evaluation order. Consider reading this related great answer: Is process in VHDL reentrant?.