Let's say I have a circuit that performs a function which takes 100 clock cycles to complete. My testbench feeds inputs into the circuit and then checks whether the output is correct.

I'm unsure how to put the 100 cycles delay in the testbench. Could I somehow pipeline it or should I feed input, wait 100 cycles, check output, repeat? I thought about using "wait for ns" statements, but this would stall all activity, which means the circuit will not be clocked the 100 times it needs to be.

  • \$\begingroup\$ If the design is pipelined - say, 100 cycle latency but 1 cycle throughput - pipeline the testbench too. \$\endgroup\$ – Brian Drummond Jan 3 '17 at 15:52
  • \$\begingroup\$ How to design the testbench in such a way that it checks the received values against the correct inputs (because of the pipeline delay)? \$\endgroup\$ – gilianzz Jan 3 '17 at 16:00
  • 2
    \$\begingroup\$ 1) Generate inputs and expected output at the same time. (2) put expected output (and some tag, like the test number) in a pipeline. 3) Compare output with what came out of that pipeline. 4) If error, report expected, actual, and tag. \$\endgroup\$ – Brian Drummond Jan 3 '17 at 16:04
  • \$\begingroup\$ You could always set a flag outside of a process in your testbench using "flag <= '1' after PIPELINE_DELAY*PERIOD ns;" and just initialized flag to '0'. Then, once flag='1' start comparing the output to expected. \$\endgroup\$ – ks0ze Jan 3 '17 at 17:08
  • \$\begingroup\$ Put the wait until rising_edge(clk) in a loop, see my answer. \$\endgroup\$ – Jason Morgan Jan 16 '17 at 9:32

This is a bench pattern that will do as you want.

The procedure is not necessary, just there as an illustration.

You can fill in the procedure body, code and signal list as required.

You'll need to change do_test1 to match the edge of the clock you want to examine.

If you are using VHDL2008, you can use the sub-module 'External Names' signal access syntax to make the test run on some buried clock, as shown in the example.

library IEEE;
use IEEE.std_logic_1164.all;

package tests is
  procedure other_tests(sigs : types....);
end package;

package body tests is
  procedure other_tests(sigs : types....) is
  end procedure;      
endd package body;

library IEEE;
use IEEE.std_logic_1164.all;

entity TB is
end entity;

architecture bench of TB is

component some_entity is
  port (
    clk : in std_logic;
    op  : out std_logic
end component;

signal op : std_logic;
alias clk is << signal.tb.uut1.clk : std_logic >>;


  do_test1 : process
    for n in 1 to 100 loop
      wait until rising_edge(clk);
    end loop;


  end process;  

  UUT1 : some_entity port map (clk => clk, op => op);

end architecture;
| improve this answer | |

This what I would do.

Initialize counter at same time as function then interrupt when done. I believe in Script language, this is the UNTIL function. ( from past test experience)

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.