VHDL language is simulators and synthesizers. Sometimes they are not actually downloading behaviour on the chip instead they are generating patterns called VHDL testbenches.
A testbench is a VHDL code that is used to check the functionality of a design. Also, outputs can be checked for correct behaviour.
The design which allows to verify the functionality of design at each step in VHDL synthesis-based methodology is known as testbench.
- Testbench have empty entity and architecture containing the circuit under test.
- In testbench main module acts as a component within architecture.
- Signals are used to connect every port of circuit under test with same name and type.
- In the testbench, process statement is used to generate clock signals for the module.
When the designer makes a small change to fix an error, the changes can be tested to make sure that it did not affect the other parts of the design. The testbench is the highest level in the hierarchy of the design.
The testbench initiates the design under test (DUT). The test bench also provides necessary stimulus to the DUT and examines the output from the DUT.
The DUT responds to the input signals and produces output results from the DUT against those good results and reports the discrepancies. This is the basic function of the testbenches.
Applications of VHDL Testbench
- It is useful to generate stimulus for simulation.
- It is used to analyse the design.
- To compare the results of two simulations.
Verification Using Testbenches
A testbench provides input stimulus to design under test (DUT) and assess the output from DUT.
The stimulus driver drives input to the DUT. DUT responds to the input signals and produces output. Finally, it compares the output results from DUT with the expected values and reports any discrepancies.
The elements of a testbench are
- The entity has no ports.
- Relationship between DUT and Testbench is specified through component instantiation.
Stimuli is a set of signals that are declared internally in the Testbench architecture and assigned to DUTS port in its instantiation.
A Typical Testbench Format
entity test_bench is
architecture tb_bahav of test_bench is
port (list of ports)
local signal declaration;
Apply to DUT;
DUT : device_under_test port map (ports) Monitor values and compare with expected values end tb_behav;
The stimulus is automatically applied to the device under test.
There are two main approaches in generating stimulus values.
- Create waveforms and apply stimulus at certain discrete time intervals.
- Generate stimulus based on state of the entity, that is based on output response of the entity.
A repetitive pattern with a constant on off delay can be created using a concurrent signal assignment statement.
CLK <= not CLK after 100 ns;
The waveform created is as shown in Figure 2.
A waveform with a constant ON-OFF delay can be created using a concurrent signal assignment statement as follows.
constant on_time: time := 30 ns;
constant off_time: time:= 20 ns;
wait for on_time;
wait for off_time;
A problem with both of these approaches is that if the host environment provides no control on the amount of time simulation is to be performed, simulation would continue until time is equal to time high.
One way to avoid this problem is to use an assertion statement in the process that will cause the assertion to fail after a specific time.
assert Boolean expression;
assert NOW <= 1000ns
report “Simulation completed”
Assertion would fail when simulation time exceeds 1000 ns and simulation would stop i.e. if the value of the Boolean expression is false, the report message is printed along with the severity level.
Proper use of assertion statement prevents frequent viewing of the waveform window and atomizes the simulation process.
Severity level parameter are
NOTE, WARNING, ERROR, FAILURE
After displaying the reporting string message, in case of NOTE and WARNING, simulator continues with the simulation process but in case of ERROR and FAILURE simulator stops the process.
Another way to stop the process from generating more events is by using a ‘wait’ statement.
if NOW> 1000 ns then