|   JHDL Home Page   |   Configurable Computing Lab   |   User's Manual (TOC)   | Search

Using the Dynamic Test Bench

Overview of the Dynamic Test Bench

The Dynamic Test Bench (DTB) is a tool which creates a Testbench to dynamically load in your JHDL design. That is, with the DTB, you don't have to write and compile a Testbench that specifically loads in your design as a child. (Still, the JHDL Simulator/HWSystem must have a Testbench as its child, and the DTB fulfills this requirement.) This is a time saving feature, especially for smaller designs that may not require sophisticated Testbench tests involving complex puts and tests on the outputs. The DTB is a means of quickly loading your circuit, viewing the schematics and performing simple interactive simulations (using the Stimulator class).

This tutorial describes how to the use the DTB in JHDL. There are two simple steps to using the Dynamic Test Bench:

  1. Create/invoke the DynamicTestBench
  2. Interact with the DynamicTestBench

Creating A DynamicTestBench

To load your compiled JHDL design into a new DynamicTestBench, simply execute the following (where my_design_class_name is the name of the class file of your design):

            java byucc.jhdl.apps.dtb.DynamicTestBench my_design_class_name

The name of the design class may include or omit the .class extension. Alternatively, you may use the shorthand helper class as follows:

            java dtb my_design_class_name

This will create a new DynamicTestBench that will have your JHDL design as a child. Any Wires required by the constructor/cell_interface will be created. These wires will have the names specified in cell_interface. All IN port wires and all INOUT port wires will also be wired to a new Stimulator object to allow you to perform interactive simulation as described in the Stimulator documentation. Invoking a DynamicTestBench also creates a circuit visualization tool to view and interact with your design, as well as with the DynamicTestBench itself.

For a view of the command line parameters that you can give the DynamicTestBench, run the following:

            java dtb --help

The following describes some of the command line options available from DynamicTestBench:

-a (t|f)
With this option you can determine whether DynamicTestBench will automatically build the design as soon as it has all of the constructor parameters defined. The default behavior is to automatically build the circuit. This option is useful if the first constructor in your design happens to only have Wire parameters that match your cell_interface. With such a constructor, the design would be built before you have a chance to select an alternate constructor.
-c <constructor_index>
This option allows you to indicate a specific constructor to use in instantiating your design. It is not uncommon for JHDL designs to have multiple constructors, allowing the user to configure the design according to the differing parameters of the constructors. Using the -c option allows you to specify which of the public constructors in the design to use in building it. Note that the index you give should be the number of the constructor as it appears in order in your .java design file. The first constructor is constructor zero, which is also the default constructor to use with the design.
-cd <clock_schedul>
This option allows you to indicate desired clock schedule for the main default system clock in JHDL. The given clock schedule string must contain only ones and zeros (no spaces). This option is useful for specifying a unique duty cycle for the main clock. Using this option is usually necessary if your design contains user-defined or explicit clocks. In cases of explicit clock wires, it may be necessary to set the test-bench-level clock schedule with this option as well as using a put command to set the clock schedule for the clock wire in the design.
-s <script_file>
You may use this argument (multiple times if desired) to specify the name(s) of scripts to execute once the DynamicTestBench is up and running. You might use this option to run scripts that will automatically set the parameters for your design, cause the design to be built and even execute simulation commands.
-t <technology> [-tme (t|f)]
The technology option allows you to specify a target technology library other than the default (currently Virtex). You may use this option to target any one of XC4000, Virtex, or Virtex2. Or you may name your own TechMapper class, with its fully-qualified package and class name. The -tme option may also be used to indicate if techmapping hints (e.g. RLOC, etc.) will be added to the design library elements. What this will do is cause DynamicTestBench to pass in either a true or false boolean value to the constructor of the new TechMapper.
If you use this argument, any other arguments following it will not be considered arguments for the DynamicTestBench. Instead, they will be stored and made available to the user's design through the method DynamicTestBench.getAdditionalArguments(). This may be helpful if your design happens to need extra information to help it build itself or for other purposes relevant to your design and simulation.


The DynamicTestBench is limited in its ability to dynamically load a JHDL design. The dynamic loading is made possible by using the reflection features of the Java environment. However, reflection in Java does not give a complete view of the original .java source code for your design. Therefore, information such as the names of parameters of the constructors is lost. Because of such limitations, the DynamicTestBench must enforce fairly strict restrictions on your design.

Your design's constructor(s) must only have one argument that is assignable from the byucc.jhdl.apps.dtb.DynamicTestBench class. This argument should be the parent node of the design. The parent node will be the DynamicTestBench itself. The limit of just one Node allows you to place this parameter anywhere in the constructor. Please note that Cell, Structural, LogicGates, and Logic are examples of classes that are assignable from DynamicTestBench, so your constructor may only have one of any of these types as arguments to its constructor.

(JHDL Development Team Note: If this becomes too restrictive, we may change it to allow multiple Node elements in the constructor. However, this would require a tighter specification for where the parent argument is found in the constructor. Specifically, we would probably require that the parent Node be the first Node (i.e. parameter assignable from DynamicTestBench) argument found in the constructor. Because of this, we recommend that you always have the parent argument to your constructor be the first argument. )

If the constructor for your design requires Wire parameters, your design must have a public static array of CellInterface elements called cell_interface. (This is already a design standard of JHDL in general.) Any ports in your cell_interface, must coincide exactly with any Wire parameters of the constructor for your design. That is because the cell_interface is the only source of information about wire widths and other parameters that will affect the way the wires should be built to pass to the constructor. The following is an example of how this should work

    public class MyDesign extends Logic {
         public static CellInterface cell_interface = {
           in( "inA", "widthA" ),
           in( "inB", "widthB" ),
           out( "outWire", "widthOut" ),
           param( "widthA", INTEGER ),
           param( "widthB", INTEGER ),
           param( "widthOut", INTEGER ),

         public MyDesign( Node parent, Wire a, Wire b, Wire out ) {
           super( node );
           /* circuit initialization here */

Notice that in this example, the parameter names in the constructor don't exactly match the names of the ports declared in cell_interface. They could match (and for full clarity the probably ought to) but it doesn't matter since that information is thrown away once the class is compiled to Java byte code anyway. Nevertheless, this example makes it very obvious that the first port in cell_interface coincides with the first Wire parameter of the constructor, the second port with the second Wire, etc.

What You Can Do:

The DynamicTestBench does allow a fair number of extras in both your cell_interface and in your constructor. The cell_interface may include any of the supported CellInterface types available and supported by JHDL. The constructor may also include any non-Wire and non-Node (other than the parent) parameters. The only restriction on those parameters is that they must be able to be instantiated with either just a String or with no arguments. This allows you to have int, long, boolean, and other primitive Java types (which can be instantiated through classes such as Integer, Long, Boolean, etc. which can take String parameters in the constructor) or even custom classes in your constructor. As long as you can instantiate that class with just a String or with no argument, you can have it in the constructor.

The port elements in cell_interface may also be parameterized (as in the above example). If your design contains such parameters, the circuit will not be built right away. You must first specify the parameter values using the command line or the parameter GUI as described below.

Your constructor arguments can be in any order, provided that the relative order of all Wire arguments matches the relative order of coinciding elements of cell_interface. It is still recommended that you place the parent Node first.

There is no limit to the number of constructors permitted. However, only constructors that have Wire parameters that match the cell_interface will work with DynamicTestBench. You can select which constructor to use when you start up DynamicTestBench, or interactively as explained below.

Interacting with the Dynamic Test Bench

Since the main purpose of the DynamicTestBench is to simply build your design, with itself as the parent, the only interactions with DTB involve setting build parameters to prepare your circuit to be built. The following is the set of CLICommands you can use to interact with DynamicTestBench in this process. To see the syntax or to get more information about any of these commands, type help and then the name of the command in a JHDL command line text field.

Use this command to control whether or not DynamicTestBench will automatically build the design once all of the constructor parameters are set, or if the user must use the build command
Use this command to tell DynamicTestBench to build the circuit, even if some of the constructor parameters are not set. NOTE: you still must set all of the wire parameters of the constructor.
Use this command to indicate to DynamicTestBench which constructor of your design to use.
Use this command to set a parameter of the constructor of your design.
Use this command to display a GUI that may be used instead of the command line to set the various parameters of your constructor. This GUI will allow you to do any of the DynamicTestBench CLI commands from the GUI.
Use this command to set the width of a parameter used to bind ports in your cell_interface.
Use this command to tell DynamicTestBench to use a different TechMapper to build the design.

An Example Using the Dynamic Test Bench

The following files contain a full JHDL example that can be used with the DynamicTest. Download the two files, then, with the JHDL classes or JHDL.jar in your classpath, compile GateNReg_NBit.java, then invoke the DTB as follows.

       javac GateNReg_NBit.java
       java dtb GateNReg_NBit -s gatenreg.script

GateNReg_NBit.java A JHDL design that has both port width parameters and non-Wire constructor parameters
gatenreg.script A script that can be run to invoke the DynamicTestBench commands to set the parameters for building the GateNReg_NBit design

|   JHDL Home Page   |   Configurable Computing Lab   |   Prev (CVT)   |   Next (Simulator)   |

JHDL 0.3.45