Graphical Test Bench Generation

By Donna Mitchell, SynaptiCAD

Published on WWW.TESTBENCH.IN in April 2009

Test bench code is often difficult to understand, even when written using modular programming techniques, because of the large amount of parallel activity occurring in the test bench that is not apparent when just reading through the code. However, when that same parallel activity is displayed as waveforms in a timing diagram the interaction between the signals is obvious from just glancing at the timing diagram. Timing diagrams allow a much clearer and concise description of the interaction of parallel processes and signal activity than can be achieved by writing code. A graphical representation also facilitates the collaboration of many engineers on 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 transactor does, dramatically simplifying test bench maintenance.

There are several tools on the market that can take basic waveforms and generate simple VHDL and Verilog models. This article will discuss the tools offered by SynaptiCAD, because they offer three different levels of test bench generation ranging from simple stimulus test benches, test benches that monitor system reaction during simulation, to full bus-functional models that behaviorally model the outside system. We will show examples of timing diagrams and some of the code that they can generate.

Level 1: Basic Stimulus Generation

The most basic of the graphical testbench generation tools can take drawn waveforms and generate VHDL or Verilog stimulus. This level of test bench generation is great for generating quick small test benches, because the temporal relationships between edges are easier to see in a graphical timing diagram then in raw VHDL or Verilog code. This simple graphical test bench generation can be found in many timing diagram editors and several graphical simulator-debugging environments. SynaptiCAD offers it in their WaveFormer Pro timing diagram editor and in their BugHunter Pro simulation debugging environment.

Below is an image of a simple timing diagram that was drawn in WaveFormer Pro. This shows how different types of signals, buses, and clocks will generate stimulus code.

VHDL Stimulus from Timing Diagrm

Once a timing diagram is finished, the test bench code can be generated via a simple file save operation. WaveFormer generates either a Verilog module or a VHDL entity/architecture model for the stimulus test bench. This test bench model can then be instantiated 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.

-- 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
  -- clock and status setup code
  -- Clock Process
  CLK0_process : process
    variable CLK0_low : real;
    variable CLK0_high : real;
    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
    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
  end process;

In the generated code, notice that the clock is a parameterized process. Not all tools generate clock signals this way, but it makes it easy for the user to modify the operation of the test bench by changing the values of the clock variables.

WaveFormer also supports complex data types and user-defined types. 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 as demonstrated by the SIG3 signal.

For larger test benches, the waveform data can be imported from an outside source like a logic analyzer, simulator, or spreadsheet. For example, if you are designing a new ASIC to upgrade an existing communications system, then you can use a logic analyzer to capture stimulus vectors from the communications system and use WaveFormer to translate the data into a VHDL test bench to test the new ASIC design. It is important to investigate whether the test bench tool you are using can read the type of files that your waveform data is in.

Level 2: Reactive Test Bench Generation

The next level up in graphical test bench generation is to add elements to the timing diagram that will generate code to check the behavior of the model under test (MUT) during simulation. In the SynaptiCAD tool line, you can add the Reactive Test Bench Option to any of the tools that support basic stimulus generation.

In the timing diagram, the user draws both the stimulus waveforms (black) and the expected output of the model under test (blue waveforms). Samples are added to the blue expected waveforms to generate specific tests at those points in the diagram. During simulation if the actual value is different from the expected value at the sample point, then a report will be generated that describes the discrepancy between the expected and actual value from the model under test.

Timing Diagram that will generate a reactive test bench

Below is a picture of the generated code for the sample that is used to check the output of the read cycle.

Reactive Test Bench code generated from a timing diagram

Often reactive test bench tools include a method for repeating sections of the waveforms. With SynaptiCAD´┐Żs tools the user places marker lines on the diagram to define the beginning and ending of loops. Loops can also depend on the sampled values of expected output from the model under test. This way the test bench can be made to "react" to the behavior of the model under test during simulation.

Timing Diagram with loop markers that generate test bench code

Reactive test bench generation often allows the option of creating "clock-based" test benches as well as the "time-based" test benches currently supported by the stimulus based generation models. Clock-based test benches delay in clock cycles instead of times, allowing the user to change his clock frequency without needing to change his timing diagram. Clock-based test benches are also required when testing using high-speed "cycle-based" simulators.

Level 3: Bus-Functional Model (BFM) Generation

As your test benches become more and more complicated, it will become more difficult to model them using a single timing diagram as described in the previous two levels. SynaptiCAD offers TestBencher Pro to overcome this problem. At the time of this writing TestBencher is the only graphical test bench generator that can take multiple timing diagrams and generate a complete bus functional model from them.

Test Bencher generates bus functional models from timing diagrams and a sequencer process

TestBencher generates a transactor for each timing diagram in the project. A transactor represents a reusable interface specification of the bus-functional model that you are creating (e.g., read cycle, write cycle, interrupt cycle). These transactors are modules for Verilog, entity/architecture pairs for VHDL and classes for TestBuilder. Regardless of the language, the transactors use the same general architecture.

Test Bencher generates transactions from graphical timing diagrams

Once the transactions are defined, the user writes a sequencer process to apply the timing diagrams to the model under test. Inside the sequencer process the user can write behavioral VHDL or Verilog code to pass in variables and process information to the transactions. TestBencher also has a graphical interface for assisting the user in writing the apply calls. Below is an example of a sequencer process that repetitively applies a write transaction followed by a read transaction. Each time the loop is performed the delay value is changed so that model is tested over different delay times.

   // Sequencer Process
   real delay0; // delay0 will serve as the index and the delay value
      for (delay0 = 32.0; delay0 > 5.0; delay0 = delay0 - 5.0)
         // Apply_Tbwrite( addr , data , $realtobits(delay0_min) );
         Apply_Tbwrite( 'hF0 , 'hAE , $realtobits(delay0) );
         // Apply_tbread( addr , data , $realtobits(delay0_min) );
         Apply_tbread( 'hF0 , 'hAE , $realtobits(delay0));

TestBencher Pro also supports hierarchical BFM design by allowing projects to be instantiated inside other projects. This lets you develop and verify complex test benches in an incremental manor. For example, if you are designing a test bench for an ATM switch, you can develop a project that can transmit an ATM cell to an interface port on the ATM switch. After you have tested your transmitter project, you can make it a sub-project and instantiate a copy of it for each different port of the ATM switch.

Summary of Graphical Test Bench Generation

You can free yourself from the time-consuming process of writing Verilog and VHDL test benches by hand and instead generate them graphically from timing diagrams using a timing diagram editor. By using timing diagrams, the engineer can work at a higher level abstraction, free from the tedious details of the underlying code. This graphical representation facilitates the collaboration of many engineers on a single test bench by removing the need to interpret HDL 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. The first step in choosing a test bench generator is to determine the complexity of your expected test bench and then to pick a tool that can generate that code. This article described the functionality of test bench tools offered by SynaptiCAD. If you would like to experiment with these tools you can find more information on the page of the SynaptiCAD web site.

About the author
Donna Mitchell is Vice President of Marketing and Co-Founder of SynaptiCAD Sales Inc. Mitchell's industry experience includes 20 years of hardware and software development.

Back to Technical Papers page