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

I/O Circuitry Insertion and Advanced Netlisting Using Test Benches


Inserting I/O Circuitry Manually

As described earlier in this user's manual, it is possible to have JHDL automagically insert I/O circuitry (pads and I/O buffers) for the top-level ports in a JHDL design. This makes it possible to quickly generate an EDIF file. However, it is only suitable for simple designs since it cannot handle bidirectional top-level ports and user-defined clocking. In this section you will learn the mechanisms available to you to insert the required I/O circuitry into your design prior to netlisting.

Instancing Library Primitives for I/O Circuitry

As mentioned previously, the primitive library for each technology supported is available for manual insertion in JHDL. In this section, manual insertion of buffers for Xilinx technology is covered. From this, users should be able to determine how this would be done in other technologies supported by JHDL. In Xilinx, inserting an IBUF primitive between the port and your user circuitry is all that must be done:

    new ibuf(this, portWire, userCircuitryWire);

Once this is done, you do put commands on portWire like any other wire. That is, the IBUF simulates just fine. Similarly, for outputs:

    new obuf(this, userCircuitryWire, portWire);

Inout ports have the added need for a select wire to enable the tri-state output buffer. Here is the code:

    new ibuf(this, portWire, userCircuitryWire);
    new obuft(this, userCircuitryWire, enableWire, portWire);

Note that in these examples, no actual pad cells are inserted - just buffers. This is because in Xilinx the pad cells are not needed. Also, some users have reported problems when inserting pad cells for some Xilinx technologies.

Beyond these examples, the user can look in the library documentation for the technology of interest to see how to insert other kinds of buffers and clocking circuitry such as CLKDLL's, IBUFG cells, and BUFG cells.

Pad Insertion Methods in Logic

The Logic class contains convenience functions for inserting pads and buffers as well. These include: The Xilinx library, for example, contains many, many different I/O drivers. The JHDL library contains most of them. Consult the API documentation to see how to instance these.

Accessing the Default Global Clock When Manually Inserting Pads

There is one situation not covered by the above discussion. That is when your design uses default clocking, the question arises: how do you get hold of the default global clock wire and use it to manually instance pads? This code fragment will do so:

      Wire CLK = getGlobalClock(getSystem()); 
      new ibufg(this, CLK, userCircuitryClock);

Once again, consult your vendor's documentation on precisely what cells are required on a clock input (DLL's, DCM's, BUFG's, etc).

I/O Insertion Strategies

Usually, adding I/O circuitry is the last thing you do prior to netlisting. A strategy which has proven useful to other users of JHDL is this: simulate and verify your design without any I/O circuitry included. When you are ready to netlist, make a new cell which is just a wrapper around your own design and which inserts the needed I/O circuitry and then do a final simulation on that prior to netlisting.

Inserting Drop-Ins and Other Circuitry

Regardless of whether you let JHDL do some of the work of inserting pads for you, there are cases where you will need to insert additional pads, drivers, and drop-ins. Here are a few examples for Virtex:
  1. The Virtex library contains a "startup_virtex" block. Wiring an input from a pad to its GSR port provides a system-wide asynchronous reset capability. Wiring an input from a pad to its GTS port allows an outside signal to tri-state all output pins on the FPGA. Consult the Xilinx Library Guide for further information. Note that JHDL will NOT simulate these functionalities. Nevertheless you may want to include them for proper hardware execution.
  2. Xilinx FPGA's provide a readback capability which is accessed via a readback drop-in circuit and specific pins. Consult the Xilinx Library Guide for further information.
  3. Many FPGA boards require special memory or FIFO drop-ins for proper operation. Consult the board documentation for information on what needs to be inserted.
NOTE: the JHDL libraries for Xilinx 4K, Virtex, and Virtex2 are relatively complete. However, some cells (such as the startup and readback blocks) are there for completeness for netlisting and for importing external EDIF designs into JHDL and do NOT contain simulation models. Thus, do not be surprised if simulations of blocks like startup_virtex don't reflect their real behavior. This is another case where you may choose to do the majority of simulation without any off these things inserted and only include them in the wrapper design you create for the I/O circuitry.


Netlisting can be as simple as executing the following in your testbench:

    tm.netlist( my_chip, "chip.edn" );

where my_chip is a pointer to the top-level cell you want netlisted. However, where does tm come from? Remember back in the section on test benches where you had to create a TechMapper before you built your circuit? That is what tm is. Here is the code to remind you how to do it:

    VirtexTechMapper tm = (new VirtexTechMapper(true));
    tm.netlist(my_chip, "chip.edn");

However, there are a collection of options that should be set to get just the behavior you want. Here is the first:

      tm.setInsertPads(boolean flg);  // flg=false means don't insert pads.

This allows you to control whether JHDL will automatically insert pads on your top level ports when you call the netlister. There are 2 cases where you would set this to false. First, you may want to insert the pads yourself. Second, you may want to generate a black box netlist of your design. That is, you don't want any pads on the design since you are going to take the netlist that JHDL generates and use it in another CAD tool as a black box.

The second option to set is:

    tm.setInsertTopLevelPorts(boolean flg);  

This allows you to control whether a port interface is emitted for your top level design. Usually (when generating EDIF for a whole chip) you want this to be false. However, you would want to set this to true for generating a black box netlist.

Here is a code snippet showing the first part of a test bench which does netlisting:

import byucc.jhdl.base.*;
import byucc.jhdl.Logic.*;
import byucc.jhdl.Xilinx.Virtex.*;
public class tb_cnt extends Logic implements TestBench {
  static VirtexTechMapper tm;
  static Cell mycnt;

  static HWSystem hw;
  public static void main(String argv[]) {
    hw = new HWSystem();
    tb_cnt tb = new tb_cnt(hw);
    tm.netlist(mycnt, "c.edn");
    System.out.println("Netlisting done.");

  public tb_cnt(Node parent) {

    tm = new VirtexTechMapper(true);

    clr = wire(1, "clr");
    q = wire(4, "q");

    mycnt = new cnt(this, clr, q);


To summarize, here is a discussion of the four possible uses of these two flags:

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

JHDL 0.3.45