Testbenches Fundamentals

A testbench is a non-synthesizable VHDL model that drives the design under test (DUT) and checks its outputs.

A testbench is a non-synthesizable VHDL model that drives the design under test (DUT) and checks its outputs.

18.1 Structure of a clocked testbench

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.all;

entity counter_tb is
end entity;

architecture sim of counter_tb is
  constant CLK_PERIOD : time := 10 ns;
  signal clk : std_logic := '0';
  signal rst : std_logic := '1';
  signal q   : std_logic_vector(7 downto 0);
begin
  -- Clock generation
  clk <= not clk after CLK_PERIOD / 2;

  -- DUT
  dut : entity work.counter
    generic map (WIDTH => 8, MAX => 255)
    port map (clk => clk, rst => rst, q => q);

  -- Stimulus & checks
  stim : process
  begin
    wait for 3 * CLK_PERIOD;
    rst <= '0';
    wait until rising_edge(clk);
    for i in 1 to 20 loop
      wait until rising_edge(clk);
      wait for 1 ns;                                     -- sample after outputs settle
      assert unsigned(q) = i
        report "Mismatch at cycle " & integer'image(i) &
               ": got " & integer'image(to_integer(unsigned(q)))
        severity error;
    end loop;
    report "Simulation finished OK" severity note;
    finish;                                              -- VHDL-2008 (std.env)
  end process;
end architecture;

18.2 Testbench techniques

Clock: clk <= not clk after T/2; or a process with wait for.

Reset: hold for several cycles, release synchronously.

Stimulus: directed tests, loops over all inputs (exhaustive for small blocks), random (math_real.uniform, OSVVM RandomPkg).

Checking: assert ... report ... severity, compare against a reference model (golden model in VHDL or from files).

Timeouts: watchdog process that fails if simulation runs too long.

Ending: std.env.stop/finish or stop the clock.

Waveforms: dump and inspect; add report messages for traceability.

to_string (VHDL-2008): report "q=" & to_string(q) & " hex=" & to_hstring(q);

18.3 Exhaustive combinational test

process
begin
  for i in 0 to 255 loop
    for j in 0 to 255 loop
      a <= std_logic_vector(to_unsigned(i, 8));
      b <= std_logic_vector(to_unsigned(j, 8));
      wait for 1 ns;
      assert unsigned(sum) = to_unsigned(i + j, 9) report "adder error" severity failure;
    end loop;
  end loop;
  report "All 65536 cases passed";
  wait;
end process;