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 code.

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"), tbvEnumsT::WRITE_ONLY)

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++ I/O

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.

C++ Synthesis

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 data structures.


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

Information on C++ Tools

SystemC Library, free open source modeling library supported by OSCI.

TestBuilder Library, free open source verification library supported by Cadence.

TestBencher Pro, a graphical code generation and GUI-project management tool by SynaptiCAD.

Qt Library, GUI library from Trolltech, with a free version for noncommercial development.

Back to Technical Papers page