Computer Engineering 465 / Electrical Engineering 543
DIGITAL VLSI SYSTEMS
Writing
Testbenches
This page
introduces the concept of writing testbenches to verify the work of a
modeled
digital system. The elements and programming techniques used for this
purpose
are explained in detail. For each of the VHDL labs/projects, you
will be asked to write a testbench for the lab/project that you are
designing.
Introduction
After writing the VHDL code for a
certain
system and before processing the design, however, we should take the
time
to verify that the code actually does what it is intended to do, by
running
a simulation. VHDL is powerful as a test stimulus language.
One of the most important
applications
of VHDL is to capture the performance specification for a system, in
the
form of what is commonly referred to as a testbench. Testbenches are
VHDL
descriptions of circuit stimuli and corresponding expected outputs that
verify the behavior of a circuit over time. They should be an integral
part of any VHDL project and should be created together with other
description
of the system.
The easiest way to understand the
concept of a testbench is to think of it as a virtual circuit tester.
This
tester, which you will describe in VHDL, applies stimulus to your
design
description and (optionally) verifies that the simulated circuit does
what
is intended to do.
After creating one or more
testbenches
as part of your design specification, you will need to use a simulator
to apply the testbench to your design as it was originally written.
This
simulation will ensure that the design operates as expected. This type
of simulation is called functional simulation, which will uncover most
logical errors in the design.
Testbench
Structure
When writing testbenches, you will most likely use a broader range of
language
features. The simplest testbenches
are
those that apply some sequence of inputs to the circuit under test
(CUT)
so that its operation can be observed in simulation. Such a testbench
must
consist of a declaration for a test component. In what follows, we will
discuss the main structure and features of this test component:
-
Empty entity declaration.
The
entity declaration of the test component does not generally include an
interface (port) list, as they are the highest level design unit when
simulated.
-
Local
signals. The
architecture
of the test component has declarations for local signals. These signals
are used to apply inputs to the CUT and observe the behavior or the
output
during simulation.
-
DUT
instantiation
. The
architecture for the testbench should use the structural level of
abstraction
(in the form of port mapping statements) to connect the low-level
(previously
top level) design description to the other parts of the testbench
(including
signals and components). It is worth noticing that to the simulator,
there
is no distinction between those parts of the design that are being
tested
and the test bench itself.
-
Test inputs.
A sequence
of test inputs are applied over time to the DUT, with a predefined time
value (or external triggering event) defined as the condition for
process
reactivation.
-
Process
statement.
To
apply stimulus to the design, your testbench you will probably be
written
using one or more sequential process. A process that is intended for
testing
will normally have no sensitivity list. Instead it will have a series
of
signal assignments wait statements. The
wait statements provide
a specific amount of delay between each new combination of inputs for
the DUT to stabilize between the assignments of test inputs. This
process statement
will be used to apply a sequence of input values (the actual stimulus)
to a low-level circuit and (if desired) check the state ot that
circuit's
outputs at various points in time.
-
Transport
statements.
There
are two ways to write stimulus vectors: using wait statement
(as
just explained) or using transport statements. Transport-based
test benches are smaller and easier to read than wait-based
test-benches,
but wait-based test benches are easier to understand when
single
stepped through simulation to debug it.
-
Assert statements.
Assert
statements are used to verify that the DUT is operating correctly for
each
combination of inputs. In case of fallacy operation, the text you have
specified in the optional report statement clause is displayed
on
your simulator's window.
-
Indefinite
wait statement.
A wait statement without any condition expression is used to
suspend
simulation indefinitely after the desired inputs have been applied.
-
Multiple
processes. Separate
processes running in the background can be used to generate some useful
signals like clocks.
-
Loop
statement. You
will
probably use VHDL's looping features to simplify the description of
repetitive
stimulus (such as the system clock). Loops can be used to apply inputs
and monitor outputs over potentially long periods of time.
-
Using
file I/O. Storing
the test data in files can reduce the time required to add or modify
test
data. In this case, the testbench does not have to be recompiled when
test
stimulus is added or modified. You should plan to create
testbenches
that are re-usable, by developing a master testbench that reads test
data
from a file. You may also need to write the simulation results to a
disk
file for later analysis
-
Advanced
data structures. You
may use records and multideminsional arrays to describe test stimuli in
the form of test vectors.
-
Subprograms.
Create subprograms
to simplify repetitive actions.