Alex
Alex

Reputation: 43

Unexpected behavior of simple VHDL circuit

What the cause of different delays of signals Q_VLD1 and Q_VLD2 in simulator? Result of simulation. Is it expected behaviour of simulator or not?

I use Xilinx Isim. There is the code and testbench for it:

entity assign_test is
    port(CLK   : in  STD_LOGIC;
         D_VLD : in  STD_LOGIC;
         Q_VLD1 : out STD_LOGIC;
         Q_VLD2 : out STD_LOGIC
    );
end assign_test;

architecture Behavioral of assign_test is
    signal D_VLD_i : std_logic;
    signal d_vld_dly1 : std_logic;
    signal d_vld_dly2 : std_logic;
begin
    D_VLD_i <= D_VLD;

    process (clk) is
    begin
        if rising_edge(clk) then
            d_vld_dly1 <= D_VLD;
            d_vld_dly2 <= D_VLD_i;
        end if;
    end process ;

    Q_VLD1 <= d_vld_dly1;
    Q_VLD2 <= d_vld_dly2;
end Behavioral;


ENTITY tb_assign_test IS
END tb_assign_test;
ARCHITECTURE behavior OF tb_assign_test IS 

    COMPONENT assign_test
    PORT(
         CLK : IN  std_logic;
         D_VLD : IN  std_logic;
         Q_VLD1 : OUT  std_logic;
         Q_VLD2 : OUT  std_logic
        );
    END COMPONENT;

   --Inputs
   signal CLK : std_logic := '0';
   signal D_VLD : std_logic := '0';
    --Outputs
   signal Q_VLD1 : std_logic;
   signal Q_VLD2 : std_logic;
   constant CLK_period : time := 10 ns;

BEGIN 
   uut: assign_test PORT MAP (
          CLK => CLK,
          D_VLD => D_VLD,
          Q_VLD1 => Q_VLD1,
          Q_VLD2 => Q_VLD2
        );

   CLK_process :process
   begin
        CLK <= '0';
        wait for CLK_period/2;
        CLK <= '1';
        wait for CLK_period/2;
   end process;

   stim_proc: process
   begin        
      wait for 100 ns;  
      wait for 5 ns;    
      wait for CLK_period*10;
      D_VLD <= '1';
      wait for CLK_period*3;
      D_VLD <= '0';
      wait;
   end process;
END;

Upvotes: 4

Views: 125

Answers (1)

Morten Zilmer
Morten Zilmer

Reputation: 15924

So if you look at the internal signals in the assign_test module, based on simulation time only, it may look as in figure below (d_vld_dly* is before assign to Q_VLD*).

enter image description here

But the figure is misleading, since that figure does not show the VHDL concept of delta delay. If the waveform is expanded to show delta delays (using ModelSim in this case), it looks like below.

enter image description here

So this reveals that the D_VLD_i <= D_VLD; in the assign_test actually delays the D_VLD_i a delta delay, whereby the new value is not seen at the clock until next rising clock edge.

The reason for this problem, is that the test bench does not generate input data as a cause of the clock, which would make data one delta delay after the clock, but independently and at the same simulation time and same delta delay as the clock.

The test bench can be updated to generate data as a cause of the clock, if wait for clock is changed from:

wait for CLK_period*10;

to:

for i in 1 to 10 loop
  wait until rising_edge(CLK);
end loop;

which will then give a waveform as:

enter image description here

So based on this, a rule for good test bench design is to generate stimuli the same way as generating data in synthesized modules, so the stimuli from the test bench is like data between modules in general, in order to get expected and reliable and test bench behavior.

Upvotes: 5

Related Questions