Table of Contents

Testbenches

Fundamentals

Example of a testbench

Example of a testbench

Notes

A testbench is used to verify the specified functionality of a design.

It provides the stimuli for the Device Under Test (DUT) and analyses the DUT’s responses or stores them in a file.

Information necessary for generating the stimuli can be integrated directly in the testbench or can be loaded from an external file.

Simulation tools visualize signals by means of a waveform which the designer compares with the expected response.

In case the waveform does not match the expected response, the designer has to correct the source code.

When dealing with bigger designs, this way of verification is very time consuming and will likely become a source of errors.

Example

entity TB_TEST is
end TB_TEST;
architecture BEH of TB_TEST is
  component TEST
   port(CLK, RESET : in std_logic;
       A     : in integer range 0 to 15;
       B     : in std_logic;
       C     : out integer range 0 to 15);
  end component;
  constant PERIOD : time := 10 ns;
  signal W_CLK : std_logic :=0;
  signal W_A, W_C : integer range 0 to 15;
  signal W_B : std_logic;
  signal W_RESET : std_logic;
begin
  DUT : TEST
   port map(CLK    => W_CLK,
            RESET  => W_RESET,
            A      => W_A,
            B      => W_B,
            C      => W_C);
...
Initial clock signal value set to ’0’

Notes

The example shows a VHDL testbench for the design TEST.

The design is declared as component in the declaration part of the architecture BEH.

A constant PERIOD is defined to set the clock period. Internal signals that are needed as connections to the DUT are also declared. It is important to initialize the clock signal either to ’0’ or ’1’ instead of its default value ’u’ because of the clock generation construct that is used later on.

Clock and Reset Generation

W_CLK <= not W_CLK after PERIOD/2;
-- complex version
W_CLK <=0after PERIOD/4 when W_CLK=1else1after 3*PERIOD/4 when W_CLK=0else0;
W_RESET <=0’,
           ’1after 20 ns,
           ’0after 40 ns
assert now<100*PERIOD
   report "End of simulation"
   severity failure;

Notes

The clock stimulus is the most important one for synchronous designs.

It can be created either with a concurrent signal assignment or within a clock generation process. As a process requires a lot of “overhead” when compared to the implemented functionality, the concurrent version is recommended.

In the most simple form shown on top, the clock runs forever and is symmetric. As the signal value is inverted after half of the clock period, the initial signal value must not be ’u’, i.e. its start value has to be explicitly declared.

The more complex example below shows the generation of an asymmetric clock with 25% duty cycle via conditional signal assignments. Please note that the default signal value needs not to be specified because of the unconditional else path that is required by the conditional signal assignment.

The complete simulation is stopped after 100 clock cycles via the ASSERT statement. Of course, the time check can be included in a conditional signal assignment as well. Clocks with a fixed phase relationship are modelled best with the ’delayed’ attribute similar to the following VHDL statement: “CLK_DELAYED ⇐ W_CLK’delayed(5 ns);”.

The reset realization is straight forward: It is initialized with ’0’ at the beginning of the simulation, activated, i.e. set to ’1’, after 20 ns and returns to ’0’ (inactive) after an additional 20 ns for the remainder of the simulation.

Stimuli Generation

...
  STIMULI : process
  begin
    W_A <= 10;
    W_B <=0;
    wait for 5*PERIOD;
    W_B <=1;
    wait for PERIOD;
    ...
    wait;
  end process STIMULI;
...
...
  process(W_C)
  begin
    case W_C is
      when 3 =>
          W_B <=1after 10 ns;
      when others =>
          W_B <=0after 10 ns;
      end case;
  end process;
...

Notes

All other DUT inputs can be stimulated the same way. The pattern generation via processes is usually preferred because of its sequential nature.

Please note that a wait statement is required to suspend a process as otherwise it would restart.

More complex testbenches will show dynamic behavior, i.e. the input stimuli will react upon DUT behavior. This may lead eventually to a complete behavioral model of the DUT environment.

Response Analysis

...
  process(W_C)
  begin
  assert W_C > 5 -- message, if false
  report "WRONG RESULT!!"
  severity ERROR;
end process;
...
...
process(W_C)
begin
  assert W_C > 5
  report "WRONG RESULT in " &
            W_C’path_name &
         "Value: " &
            integer’image(W_C)
  severity error;
WRONG RESULT in TB_TEST:W_C Value: 2
VHDL’93: Additional attributes for debugging purposes
VHDL’93: Report without assert statement

Notes

The ’assert’ statement is suited best for performing automatic response analysis.

An assertion checks a condition and will report a message, if the condition is false.

Depending on the chosen severity level and the settings in the simulation tool, the simulation either resumes (e.g. note, warning) or stops (e.g. error, failure) after reporting that the assertion fails.

The default severity level is ’error’. The message that is reported is defined by the designer.

To get reports that offer more detailed debugging information in case of errors several new attributes were defined in VHDL’93. They provide additional information about the circumstances that lead to the failing assertion: ’instance_name’ and ’path_name’ may be used to locate the erroneous module.

The path information is necessary when one component is instantiated at various places within a complex design.

The ’image’ attribute looks like a function call. Its argument is returned as string representation and the data type is the prefix of the attribute.

As a report is generated whenever the assertion condition evaluates to ’false’, it can be forced by setting this condition to the fixed value ’false’. This construction is no longer necessary in VHDL’93, i.e. the ’report’ keyword may be used without a preceding assertion.