TestBencher Code Generation Architecture
TestBencher creates bus-functional models by using a combination of graphical timing diagrams and top-level
template files. The graphical timing diagrams are used to define the reusable timing transactions like
a PCI bus read cycle or write cycle. The top-level template file defines the sequence in which the timing
transactions will be applied to the model under test.
The code generation process in TestBencher is an interactive process so it is easy to experiment with
different test bench functionality. Each time a timing diagram is saved the code for that transaction
is re-generated, so you can watch how the low-level code changes when you add a new graphical element
like a sample or a loop.
The top-level test bench controls the execution sequence and monitors the status of each timing transaction
in the project. It is also the place where the model under test is instantiated and connected to the
test bench model. The Make TB button generates the completed test bench model and updates any
timing transactions that need it. During code generation TestBencher only changes the code blocks that
appear between the macro begin and end statements. Any code that outside the macro blocks is preserved
during code generation.
The Sequencer Process
The sequencer process is the place in the top-level test bench that defines the order in which the timing
transactions are applied to the model under test. The sequencer process controls and monitors the execution
of the timing transactions.
Several tasks are generated for each timing transaction, each with a different execution mode. These
tasks are then called from the sequencer process. The task calls are placed sequentially in the order
that you wish to have them applied to the model under test.
In addition to these task calls, you can also place HDL code in the sequencer. One example where this
would be useful is if you wish to place conditions on whether or not a timing transaction is called,
or on the parameter values that you wish to have applied.
Executing Concurrent Timing Transactions In addition to ordering the timing transactions, the
sequencer process is also used to specify the manner in which the timing transactions are applied. Tasks
can run in a continuous looping mode or in a run once mode. Also each task can run in either a blocking
or a concurrent mode. Generally master bus cycles run once in a blocking mode while global clocks and
slave transactions run in a continuous and looping mode.
Multiple Test Bench Components
TestBencher Pro uses a project file to organize the timing diagram files and top-level template files.
These project files have all the information needed to generate an entire bus-functional model. Projects
can be included hierarchically in other projects. This allows TestBencher to support multiple test bench
component instantiation. Once a test bench has been completed the entire bus functional model that it
represents, or project component, can be instantiated in another project.
A project that defines a bus-functional model of an SRAM, for example, could be instantiated several
times in a higher-level project that is being developed for a microprocessor. The completed microprocessor
model could then be instantiated in a project for a video card. This is one way in which TestBencher
allows the re-use of test bench components.
Verification of devices with multiple ports can also be accomplished using multiple test bench component
instantiation. The transactions that would connect to the ports would be instantiated as many times
as needed in the higher level test bench.
This methodology allows a large test bench to be broken into smaller, self-contained components. Each
sub-project can be modified at any time, either stand-alone or while developing the owning project.
The properties of the project are always maintained.