|
|
 |
VHDL and Verilog Test Bench Synthesis
Free yourself from the time-consuming process of writing Verilog and VHDL test benches by hand. Generate
them graphically from timing diagrams using SynaptiCAD's WaveFormer Pro, VeriLogger Pro, or TestBencher
Pro software packages. SynaptiCAD provides 3 levels of test bench generation to meet all your design
needs:
- WaveFormer Pro provides single timing diagram stimulus
generation for use with external VHDL and Verilog simulators
- VeriLogger Pro generates an interactive test bench for
quick testing of models simulated with the internal Verilog simulator.
- TestBencher Pro generates multi-diagram, self-testing, reactive
testbenches. Perfect for building bus-functional models of microprocessor and bus interfaces. Code can
be used with external or internal VHDL and Verilog simulators.
Using SynaptiCAD's WaveFormer Pro, VeriLogger Pro, or TestBencher Pro packages the user draws or imports
the stimulus vectors and then the programs automatically generate VHDL and Verilog test benches. With
3 levels of test bench generation you can choose the product that meets the type and complexity of your
testing needs. At the simplest end, WaveFormer can import waveform data from just about anywhere and
generate stimulus vector test benches in a matter of minutes. In the middle, VeriLogger provides users
with an extremely fast, and interactive unit-level testing environment. And for the most complex testing
needs, TestBencher Pro can generate test benches that are complete bus-functional models that monitor
and react during runtime simulations.
In the following examples we will show you how some of our customers have used each of these products.
We will also show some code samples so you can get an idea of exactly what type of code is generated
for each product.
WaveFormer Example - Stimulus Based Test Benches
WaveFormer can generate VHDL and Verilog stimulus models from waveforms that are displayed in the timing
diagram window. For generating quick and small test benches the drawing environment can be used to develop
the stimulus vectors. This is much faster and accurate then attempting to hand code a small test bench,
because the temporal relationships between edges are easier to see in the graphical timing diagram then
in the raw VHDL or Verilog code.
For large test benches, the waveform data can be imported from an outside source like a logic analyzer,
simulator, or spreadsheet. For example, one of our customers designed an ASIC for use in an existing
communications system. He used a logic analyzer to capture stimulus vectors from the communications
system, then used WaveFormer to translate the data into a VHDL test bench which he used to test the
ASIC design.
WaveFormer generates either a Verilog model, or a VHDL entity - architecture model for the stimulus
test bench. This test bench model can then be instainated in a user's project and compiled and simulated
with the rest of the design. Below is an example of a timing diagram and some of the VHDL code that
was generated from the timing diagram. WaveFormer supports complex data types (like integers) and user-defined
types. Once a timing diagram is finished, code generation is simply a file save operation using the
Export > Export Timing Diagram menu option.
In the generated code, notice that clock is a parameterized process. During simulation a user and easily
modify the operation of the test bench by changing the values of the clock variables. Also notice that
SIG1 has a VHDL type of integer. In WaveFormer, the VHDL and Verilog types of signals can be changed
using the Signals Properties dialog. VHDL user defined types can also be entered through the same interface.

-- Generated by WaveFormer Pro Version
library ieee, std;
use ieee.std_logic_1164.all;
entity stimulus is
port (
SIG0 : out std_logic := 'Z';
SIG1 : out std_logic_vector(3 downto 0) := "ZZZZ";
SIG2 : out integer;
SIG3 : out MyColor;
CLK0 : out std_logic := 'Z');
-- more entity code
end stimulus;
architecture STIMULATOR of stimulus is
-- some signal and parameter declarations
begin
-- clock and status setup code
-- Clock Process
CLK0_process : process
variable CLK0_low : real;
variable CLK0_high : real;
begin
tb_mainloop : loop
wait until (tb_status = TB_ONCE)
or (tb_status = TB_LOOPING);
CLK0_high := CLK0_Period * CLK0_Duty / 100.0;
CLK0_low := CLK0_Period - CLK0_high;
-- more clock code
end loop;
end process;
-- Sequence: Unclocked
Unclocked : process
begin
SIG0_driver <= '0';
SIG1_driver <= x"3";
SIG2_driver <= 1;
SIG3_driver <= Yellow;
wait for 45.0 ns;
SIG1_driver <= x"F";
wait for 5.0 ns;
-- more signal statements
wait;
end process;
end STIMULATOR;
VeriLogger Pro - Fast Unit-Level Testing
VeriLogger Pro is primarily used as a Verilog simulator. It is unique in that we have integrated our
test bench generation features very closely with the simulator engine. Model testing is so fast in VeriLogger
Pro that you can perform true bottom-up testing of every model in your design, a critical step often
skipped in the race to market.
Once finish writing a Verilog model for your design, VeriLogger Pro will extract the signals or the
ports in the top-level module and automatically add them to the Diagram window. The output ports are
displayed as purple (simulated) signals and input ports are displayed as black signals. Input signals
can be graphically drawn, generated by equations, or copied from existing signals. When a simulation
is requested, VeriLogger automatically wraps a test bench around the top-level module and creates signals
in that test bench to drive and watch the top-level module.
VeriLogger can also be put into an interactive simulation mode, so that each time an input signal is
changed a new test bench is generated and a simulation is performed. This makes it easy to quickly test
small parts of a design before the design is complete. It also allows you to quickly test ideas without
being forced to generate a comprehensive test bench.
In the below example, we have hand coded a 4-bit Adder model and we wish to quickly test the model.
First we put the "add4.v" file into the Project window and press the yellow build button. VeriLogger
then scans the model and checks for syntax errors and inserts the top-level ports into the timing diagram
window. At this point, the user can begin to draw waveforms on the black input signals. Since VeriLogger
is in the "Sim Diagram & Project" mode, when the user presses the green run button, VeriLogger will
generate the test bench and perform the simulation. In the interactive simulation mode the user will
be able to drag-and-drop a signal edge and cause a re-simulation. If the user wants to archive off the
testbench all he has to do is save the timing diagram file and reload it at a later date. The completed
test bench and wrapper code can be viewed in the report window.
|
VeriLogger's automatic test bench generation features are perfectly suited for testing small models.
As a design grows in complexity, more complex test benches are needed to ensure the functionality of
the design. This where the user will either start generating test bench models using the WaveFormer
like features or move up to the TestBencher Pro bus-functional model approach.
TestBencher Pro - Advanced Bus-Functional Models
TestBencher Pro generates VHDL and Verilog test benches directly from timing diagrams using a bus functional
approach to test bench designs. It is used to model complex test benches like a microprocessor or bus
interface. With TestBencher users can generate a test bench in a few hours that would normally take
several weeks to test and code by hand.
Bus-functional models execute faster than complete functional models and can be created from data contained
in data sheets. A bus-functional model is also easier to maintain and debug than raw test vector data.
The code that is generated for each project is native VHDL or Verilog. This allows the generated code
to be compiled with the model under test and simulated using all major VHDL and Verilog simulators.
Debugging the resulting system is easy since the test bench is structured into transactions and all
of the generated code uses the same language.
Graphical Representation of Transactions
TestBencher Pro uses timing diagrams to represent the timing transactions of the test bench. By using
timing diagrams, the engineer can work with a higher level abstraction, free from the tedious details
of the underlying code. This graphical representation facilitates the collaboration of many engineers
for a single test bench by removing the need to interpret source code. Any engineer familiar with the
design specifications is able to look at a given timing diagram and have an immediate understanding
of what the transaction is doing. This level of abstraction also provides a great aid in terms of maintainability.
In the example below we have hand-coded a very simple timing transaction to show how difficult it is
to understand even a small segment of code. Also shown is the timing diagram that can be used to generate
this transaction. A glance at the timing diagram communicates the temporal relationships between the
edges of the signals. The code segment has to be studied and possibly drawn out by hand to figure out
the temporal relationships of the signals.
module testbench;
...
task write(addr,data,csb2dbus);
input [7:0] addr;
input [15:0] data;
input [1:0] csb2dbus;
begin
ABUS = addr;
@(posedge CLK0) //required abus2csb setup
CSB = 1'b0;
repeat (csb2dbus) @CLK0;
DBUS = data;
@(posedge CLK0)
CSB = 1'b1;
DBUS = 'hz;
ABUS = 'hz;
end
endtask
...
endmodule

The code complexity greatly increases when response checking code and parallel execution blocks are
added to the transaction. In the previous example only one process block is needed to represent the
transaction. However, if you wanted the transaction to sample the first edge transition of CSB then
do a conditional delay of the csb2dus, the transaction has to be coded like a finite state-machine.
This type of coding is very difficult to read, however the timing diagram is still easy to interpret.
Automatic Tracking of Signal and Port Code
One of the most tedious aspects of working with HDL languages is maintaining the signal and port information
between the test bench and the model under test. Signal information is repeated at several levels of
the test bench so that a change in the signal information requires a tedious rewriting of the test bench
code. Test bench code is more difficult to maintain then a regular design model because the code is
not broken apart into simple units. Each timing transaction usually drives and monitors most of the
input/output port signals of the model under test. TestBencher solves this problem by maintaining the
signal and port information for all the timing transactions and the model under test. With TestBencher
Pro a signal change is made in one place and then automatically propagated to all the places where that
code needs to be represented. Without this capability, port-connection errors can easily arise leading
to subtle, difficult to debug errors, similar to the problems that arise when pins are miss-connected
on a circuit board.
Conceptual Modeling Constructs
TestBencher is easy to use because we have taken great care to keep the number of constructs down to
a minimum. There are 5 basic constructs that are used to create a transaction. It is easier to learn
the functionality of these 5 graphical constructs then it is to figure out how to out how to code them
into a timing transaction.
- Drawn Waveforms - describes stimulus and expected response
- State Variables - parameterize state values
- Delays - parameterize time delays
- Samples - verify and react to output from model under test
- Markers - models looping contructs or to insert native HDL subroutine calls
These graphical constructs look and act the way that you expect a timing diagram to work, making it
very easy to create a timing diagram that generates code that you expect to be generated. Normally an
engineer must manually perform this conversion from data sheet timing diagrams to HDL code.
Easier to Maintain Test Benches
TestBencher Pro's test benches are easier to maintain than hand coded test benches for several reasons:
- Graphical representation of transactions facilitates the ability of a non-author to understand
the basic operation of the test bench.
- A project window contains all of the related test bench and model under test files so
that an engineer can quickly move through the test bench and MUT code.
- Limited number of files generated (1+N transactions). One file is generated for the top-level
test bench, and one file is generated for each timing transaction.
- Fast genereation of code - each time a transaction is saved, the code for that transaction
is re-generated so that you can immediately assess the effects of changes in the timing diagram.
- Generation of optimized test bench code for fast test bench execution.
- All generated code is well documented - both in comments and in naming constructs, making
the generated code easier to understand.
- The use of generated code guarentee's consistent code architecture. This provides readability
from one transaction to the next, and from one project to the next.
- GUI environment isolates key parameters of the test bench.
- Generated code automates the checking of simulation results, freeing the engineer from
needing to manually view waveform results to ensure proper operation of his design.
TestBencher Pro abstracts coding details away from the user, and by doing so reduces the amount of time
needed for test bench generation. By automating the most tedious aspects of test bench development,
high paid engineers can focus on the design and operation of the test bench rather than the painstaking
aspects of code development.
Summary
SynaptiCAD offers 3-levels of test bench generation to fit your design and verification needs. WaveFormer
for producing stimulus based test benches. VeriLogger for fast unit-level testing. TestBencher for producing
complex bus-functional models to represent complex, reactive interfaces. SynaptiCAD's test bench products
will save you time.
|