Modeling with C++
By Donna Mitchell, SynaptiCAD
As designs become more complicated, engineers will need to explore design tools that offer high-level
behavioral model features and that are portable down to gate level designs.
System-level designers have been using C and C++ for many years to model large systems, but generally
hardware designers have avoided them, instead using hardware description languages such as Verilog and
VHDL. This is because hardware description languages (HDL) are generally better at modeling hardware
at the register transfer level and gate level, and C++ is better for modeling high-level behavior such
as that used in bus-functional models.
However, hardware design complexity is increasing because more system-level functionality is being implemented
in hardware to increase system performance. This is forcing hardware designers to look more closely
at languages such as C++ that excel at behavior-level modeling so that they can begin modeling their
system earlier in the design cycle. New languages and tools for modeling hardware in C++ and connecting
C++ models to HDL models have recently emerged that reduce the learning curve and development time for
creating mixed C++/HDL designs. This article examines some of the benefits of C++ based models and how
new tools decrease the time to create and use them.
Benefits of C++
C++ provides many benefits for modeling behavioral algorithms including: advanced data structures, standard
libraries, embedded software models, and object-oriented features that promote code reuse. Engineers
can quickly build behavioral models using data structures like queues and associative arrays that mimic
the functionality of many hardware components without incurring the cost in memory and simulation time
of an equivalent HDL behavioral model.
Figure 1: C++ based Hardware Design Flow
Pre-written standard libraries can be used to quickly bring functionality to a design. Everything from
data structure libraries to networking socket interface libraries are available in C++. Often the library
code is free and open source, making it easy for the engineer to design with and debug into the new
C++ also provides an environment for development of mixed software and hardware components for embedded
applications. Engineers can start out designing at a high-level and refine down to a low level as needed.
This makes it easier to examine tradeoffs in architecture because software and hardware components can
both be described with behavioral models.
C++ data structures are particularly useful in test benches to verify high-level characteristics of
a design. For example, associative arrays and queues can be used to check non-deterministic and deterministic
arrival of packets, respectively, in a switched communications network. C++ also provides a rich environment
for developing code coverage and constrained randomization algorithms for generating input stimulus
to a design.
C++ code is portable to virtually all computing platforms, and C++ compilers are low cost compared to
HDL simulators, even free in many cases. In particular, the free GNU gcc compilers make it very easy
to move modeling code to different platforms. This means that an engineer can develop and debug his
code anywhere, including his laptop or home machine, without having to worry about license management.
When it is time to begin larger simulations or mixed C++/HDL simulations, he can move his design back
to a faster machine.
Challenges with C++
C++ does present several problems for engineers attempting to model hardware behavior. First it is difficult
to develop a set of classes able to handle hardware concepts like the passage of time, parallelism,
and signal driver resolution. Also, details of making PLI calls to an HDL simulator and developing a
method to map C++ signals to HDL signals is tedious and requires a great deal of effort. For example,
mapping code of this type can require several thousand lines of PLI-based code. And finally, you must
master C++ object oriented programming techniques and become proficient at building libraries in order
to get things to work. However there are many new tools and techniques that can help you overcome the
most demanding of these challenges.
Open Source C++ Libraries
Fortunately, several open source libraries are available that provide you with a framework to begin
modeling your design. In particular, SystemC and Cadence's TestBuilder libraries are excellent examples
of modeling libraries. SystemC v2.0 provides the modeling constructs for both high-level behavioral
models, gate level design, and the links for doing mixed C++ and HDL simulations. TestBuilder is a verification
library that provides transaction-level modeling features, constrained randomization, and automated
signal mapping between C++ signals and HDL signals.
As an example, hundreds of lines of PLI code to map an HDL signal to a C++ signal of the same name can
be reduced to the single line below using TestBuilder: write_addr (getFullInterfaceHdlNameP("write_addr"),
Graphical Code Generation
Working with C++ libraries provides an advantage in developing code, but the initial learning curve
is still significant. The syntax and library function calls are different for each library you incorporate
into your design. There is often a framework and recommended way to structure your design when using
the library. In addition, you must learn how to setup your C++ compiler and HDL environment so that
C++ library code is properly linked with your simulator. To make matters even more tedious, compilers
on different platforms often require different options (e.g. different make files). Graphical code generation
and GUI-based project management tools address these issues by automatically generating model code and
make files that are portable across platforms and different simulators and compilers.
SynaptiCAD's TestBencher Pro tool is one such a graphical code generation and GUI-based project management
tool. TestBencher generates bus-functional models for several languages including SystemC, TestBuilder,
Verilog, VHDL, e, and OpenVera. Users draw language independent timing diagrams to describe each bus
transaction graphically and enter information about the relevant data structures including random data
generation and packing order. The tool generates the bus-functional model directly from this information.
Since most of the information is language independent very few changes are needed to generate a bus-functional
model in a different language so these models can be used during both the architectural C++ phase and
for gate level simulations.
GUI-based tools also further reduce the amount of C++ "glue code" that must be written by the user.
For example, these tools can completely automate the mapping code between C++ signals and HDL signals
and keep these mappings up-to-date as you change your design and test bench code. Similarly, these tools
can hide from users the C++ specific details of syntax requirements for data structure definitions,
template instantiations, etc.
GUI-based project management tools can be used to handle all of the of the external compiler and simulator
control necessary to build C++ dynamic libraries, link them to the HDL simulator, and run the simulation.
For example, TestBencher can launch simulators and compilers automatically, and hand off the generated
code so it is very easy to move from test bench development to simulation. It can also import the final
simulation results so that they can be viewed graphically. Figure 1 shows a typical modern design flow
for C++ based hardware modeling.
Golden Reference Models
C++ is also a valuable tool for developing "golden reference models" that run in parallel with a VHDL
or Verilog RTL model. Golden reference models are high-level descriptions of a design and are used to
compare to the results of an RTL-level model during simulation. Reference models usually model interaction
between components at the transaction level (e.g. read transaction/write transaction) instead of at
the signal level. Normally it is a pain to develop a golden reference model because the reference model's
transaction-level I/O must be exactly the same as the RTL model, which is tedious work especially when
the RTL model is in a constant state of change. Connecting a C++ golden reference model to an HDL simulator
also requires detailed knowledge of PLI.
However, with the new C++ libraries and code generation tools, it is much easier to develop these models.
For example, the combination of the TestBuilder library and TestBencher Pro makes developing and keeping
a golden reference model current with the RTL level model relatively easy. TestBuilder provides an easier
method for integrating C/C++ based models into a test bench than using a raw PLI-based approach. TestBencher,
in turn, generates out all of the stub-functions for the C++ golden reference model, keeping the transaction
interface to the reference model the same as the HDL level model. With these tools, the user only needs
to write the behavioral C++ code inside the stub-functions that enables the golden reference model to
emulate the RTL-level model.
C++ also offers a very robust set of I/O capabilities, especially when combined with a standard GUI
library. This can be very useful for quickly creating a graphical front-end to view results of a simulation.
One such library, Qt, provides a graphical API that works across platforms and is pretty easy to use.
For example, if you were designing an ATM network switch fabric, it could be useful to view simulation
results as packets moving through a graphical picture of the switches, rather then staring at waveform
results or transaction-vs-time graphs. With Qt, you can write a quick graphical interface that shows
the packets moving through the different switches in the switch fabric.
There is some work being done on C++ synthesis, but behavioral C++ synthesis is still in its infancy,
so hardware modeling in C++ is usually only done for architectural exploration at a high-level or for
behavioral modeling in test bench code (which generally does not need to be synthesized). In particular,
none of the current C++ synthesis tools support critical features of C++ such as pointers and pointer-based
As designs become more complicated, engineers will need to explore design tools that offer high-level
behavioral model features and that are portable down to gate level designs. C++ provides many benefits
for modeling behavioral algorithms including advanced data structures, standard libraries, embedded
software models, and all of the object-oriented features of the language that simplify code re-use.
But raw C++ is just too difficult to use by itself for hardware modeling. New hardware modeling libraries
like SystemC and TestBuilder make C++ useable for architectural modeling, but they are still difficult
to use. Graphical code generation and GUI-based project management tools like TestBencher Pro ease many
of the problems incurred by using the C++ hardware modeling libraries. By choosing a combination of
the new tools, you can automate the most tedious aspects of model development, allowing you to focus
on the design and operation of the models.
Donna Mitchell is a co-founder of SynaptiCAD Inc. She received her BS and MS degrees in electrical engineering
from Virginia Tech. The company can be reached at (540) 953-3390, or www.syncad.com.
Information on C++ Tools
SystemC Library, free open source modeling library supported by OSCI. www.systemc.org
TestBuilder Library, free open source verification library supported by Cadence. www.testbuilder.net
TestBencher Pro, a graphical code generation and GUI-project management tool by SynaptiCAD. www.syncad.com
Qt Library, GUI library from Trolltech, with a free version for noncommercial development. www.trolltech.com
Back to Technical Papers page