Overview

There are four levels of design which can be mixed and matched to create your
circuit. This section briefly introduces each.
As mentioned in the introduction to the JHDL documentation and in the
JHDL Getting Started guide, JHDL is a circuit
design system based on object-oriented principles. What that means is that
all circuit elements (gates and wires) are objects. The paradigm is that by
creating new objects in Java and linking them together you are
creating a circuit.

Creating a new circuit module consists of two major parts:

You declare your circuit module as a Java class, specify its
input/output ports, and declare a constructor routine which you can
then call to create that circuit module.

You fill in the body of the constructor routine with
build that actually builds your circuit module out of gates or other
modules.

Creating Circuit Modules in JHDL

In the JHDL Getting Started guide you saw how
to declare a new circuit module as a Java class, how to define its port
interface, and how to create a constructor for it. As you recall, in the
body of the constructor we then declared the logic making up the body of
the circuit module. For instance, the first example we saw was the
creation of a 1-bit adder circuit out of logic gates. We then built an
n-bit adder out of our 1-bit adder circuit and so on. Consult
JHDL Cells and Wires for a complete discussion
of cells, ports, and wires and how to declare and create them.

Creating Logic In The Body Of A Circuit Constructor

In the body of the constructor for the 1-bit adder example we built
the adder logic using a collection of
subroutine calls like this:

It turns out that this is not the only way to specify logic in JHDL.
An alternative would have been to instantiate FPGA library primitive components
(AND and OR gates) using the new keyword. This would be
similar to how we built our NBitAdder from 1-bit adders in the
Getting Started Guide.

A key feature of JHDL is that it supports design at a number of levels
of abstraction
ranging from low-level design using primitive library
elements to higher-level design using technology-independent module generators. An
understanding of these various levels of design is
important in understanding when to use the Logic package and when
to get your hands dirty and do it yourself using library primitives
(from the Xilinx Virtex library for example).

In the remainder of this section the layered structure of the JHDL
design components support is
described. Each of the subsections below is simply a short summary introduction
to help in understanding the overall JHDL structure. Each subsection contains a
pointer to the specific section in the Users Manual on that level of
design. You should consult those other sections of the manual for the
full discussion on each level of design.

Note - the levels of design described below are not mutually
exclusive. Some JHDL designers use all of them in any given design
depending on their needs and what is provided by each.

Level 1 Design - Instantiating Library Primitives

At its lowest and simplest level, JHDL design can be done by instancing
the exact circuit primitives you want. Thus, if you were designing for
a Xilinx Virtex FPGA you could simply instance circuit primitives from the
JHDL Xilinx Virtex primitive library. Such a primitive library exists
in JHDL for every technology supported. This makes it possible to get
access to whatever FPGA features exist in the technology you are
targeting - you can do extremely low-level design
and get the most in performance and packing density from the part.
Here is an example of the instantiation of a specific
Virtex I/O buffer:

Level 2 Design - The Logic Package

While providing primitive instantiation is important in JHDL, restricting
designers to just it would make for a
cumbersome design entry method. The Logic package overcomes much
of this by providing a layer of technology-independent routines on top
of the primitive libraries. Using it, a designer can call up logic
gates, multiplexors, etc. to create a design. Once created, this
design can be targeted to any supported FPGA technology by simply
specifying the desired technology at circuit build time.

The Logic package is simply a large set of subroutines which users can
call. This does two things: (a) it provides a functional
interface for creating logic and (b) the subroutines hide all
technology dependencies from the user. The functional interface makes
it possible to do much work for the user.

Here is an example of using Logic calls to build an adder:

add_o(a, b, q);

Depending on the technology targeted this would result in a circuit
built up from logic gates or from special structures such as
fast-carry logic. This is an important idea - Logic calls produce
technology-optimized building blocks yet provide a
technology-independent API to the user. The Logic package API
provides for the construction of the following kinds of circuits:
simple gates (AND, OR, etc), registers, simple arithmetic (adders,
subtractors), multiplexors, and shifters. In addition, it provides a
wide range of subroutines to simplify the creation and manipulation of
wires (splitting, merging, slicing, creation of constant wires).

Level 3 Design - The Logic.Modules Package

The Logic.Modules package layers on top of Logic by providing
more predefined circuit building blocks for users to incorporate into
their designs. These consist of larger building blocks than are found
in Logic. Examples include counters, delay lines, multipliers, and
floating point units. In addition, Logic.Modules circuits
are often parameterized for speed, pipelining, number format, etc.

Like Logic, Logic.Modules provides for the creation of
technology-independent designs - they will work
for any technology supported by JHDL. Logic.Modules does its work by
simply
calling appropriate combinations of Logic routines such as the
add() routine in the example in the previous section.
This has the advantage that designs done using only Logic and
Logic.Modules are portable to any technology JHDL supports.
The disadvantage of this is that Logic.Modules calls cannot take
advantage of technology-specific FPGA features. Users will have to
weigh the convenience of using a generic module from Logic.Modules against the
speed/area penalty it may have over a technology-optmized version of
the same function and the work associated with creating such a
technology-optimized module.

Here is an example of how a clearable,
loadable, up counter might be created:

Level 4 Design - Technology-Specific Module Generators

Logic calls produce technology-optimized circuits for simple
circuits (such as adders). Although Logic.Modules
calls use Logic calls to do their work, their circuits may not be
technology optimized. For example, a multiplier from Logic.Modules
may use Logic's technology-optimized add() calls yet still may
not produce the smallest circuit possible. Why? In the case of
Virtex, an additional AND gate is provided which can reduce the size
of an array multiplier by
as much as 50% if it is used. Thus, there is a need for technology-specific
module generators for many functions.

JHDL provides a few of these. They may or may not correspond exactly
to modules found in Logic or Logic.Modules. However, the intention
is that they take advantage of any technology-specific features to
give the smallest/fastest circuits possible. BIG CAVEAT: that is,
they are the smallest/fastest circuits that the
JHDL developer team took the time to create. You likely could do even
better with enough effort. Here is an example of the creation of a
delay line for Virtex using a hypothetical module generator (being technology specific, it will build them
out of SRL's):

To reiterate, the list of Level 4 module generators is incomplete.
However, just the optimized module you need may be available in a
technology specific library. To find out what modules are available
for the technology for which you are designing, consult the
API section of the documentation and look at
the Modules subpackage of the package of the technology of interest
(e.g. byucc.jhdl.Xilinx.Virtex.Modules).

Level 5 Design - The Contrib Package

Knowing that users of JHDL may want to contribute their own circuit
modules, a Contrib package has been created. Users wishing to contribute
to this package for inclusion in future JHDL releases may do so by
contacting the JHDL development team. No restrictions on
the format or structure of these contributions have been created.
Each contributed design likely will be in its own sub-package in
Contrib.Logic.
Consult the distribution in package Contrib.Logic for examples (it may
be empty until someone contributes to it).

The JHDL Development Team strongly encourages contributions.

Design Levels Summary

As a final note, there is no requirement that only one design level be
adopted for any given project. Experienced JHDL users usually base
large portions of their design on Logic and Logic.Modules. They then
descend into technology-specific design using Primitive Instantiation
or technology-specific module generators (from the distribution or of
their own creation) as needed to get the area/performance they desire.
A good strategy is to start with Logic and Logic.Modules
to get a design up and simulating quickly. Later you can convert portions
to technology-specific design if and where needed.

The table below summarizes the characteristics of each of the design
levels described above. Consult the indicated sections elsewhere in this Users
Manual for detailed information on each.

Level

Advantages

Disadvantages

Users Manual Reference

Level 1

Primitive Instantiation

Access to the bare metal - can get access to any and all
FPGA-specific library features and elements.