courses:system_design:simulation:testbenches

Testbenches

Example of a testbench

Example of a testbench

  • Stimuli transmitter to DUT (testvectors)
  • Needs not to be synthesizable
  • No ports to the outside
  • Environment for DUT
  • Verification and validation of the design
  • Several output methods
  • Several input methods

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.

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);
...
  • Declaration part of the architecture
    • Component
    • Internal signals
    • Subprograms
    • Constants
  • Instantiation of the DUT
  • Connecting internal signals with the module ports
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.

  • Simple signal assignment
    • Endless loop
    • W_CLK must be initialized to ’0’ or ’1’ (not ’u’ = ’u’)
    • Symmetric clock, only
W_CLK <= not W_CLK after PERIOD/2;
  • Conditional signal assignment
    • Complex clocking schemes
  • Realization as process introduces huge overhead
-- complex version
W_CLK <=0after PERIOD/4 when W_CLK=1else1after 3*PERIOD/4 when W_CLK=0else0;
  • Reset generation
W_RESET <=0’,
           ’1after 20 ns,
           ’0after 40 ns
  • Simulation termination via assert
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.

  • Simple 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;
...
  • Dynamically generated stimuli from DUT response
...
  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.

  • Assertion with severity level
    • Note
    • Warning
    • Error (default)
    • Failure
...
  process(W_C)
  begin
  assert W_C > 5 -- message, if false
  report "WRONG RESULT!!"
  severity ERROR;
end process;
...
  • Additional attributes in VHDL’93
    • ’path_name
    • ’inst_name
    • ’image
...
process(W_C)
begin
  assert W_C > 5
  report "WRONG RESULT in " &
            W_C’path_name &
         "Value: " &
            integer’image(W_C)
  severity error;
  • Unordered List ItemReport in simulator
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.


Chapters of System Design > Simulation