====== Simulation Guide for C++ ======
===== Generated Code =====
Suppose that you generate C++ code from Arx source file ''foo.arx''.
The result is a C++ //class// called ''foo'' the description of which
is distributed across the files ''foo.h'' and ''foo.cpp''. Hierarchy
that may have been present in the original Arx description is not
preserved. The execution model that has been chosen for simulation
requires the design to be flattened.
The class will contain four methods:
* A constructor
* A destructor
* A //reset// method
* A //run// method
These methods should be called in an appropriate way from the
testbench, as explained below.
===== Embedding in Tesbench =====
The testbench can be as simple or sophisticated as the circumstances
require as long as a few rules are observed.
The header file ''foo.h'' as generated by Arx contains all information
about the class representing the hardware and should be included in
the testbench code.
#include "foo.h"
First, the object representing the hardware needs to be created by
means of the constructor. Assuming that the class is called ''foo''
and the object ''hardware'', this amounts to the statement:
foo hardware;
To bring the hardware in its //reset state// as specified by the
reset values in the register [[declarations]], the ''reset'' method
should be called.
hardware.reset();
The ''reset'' method should be called before performing the simulation
of clock cycles. If appropriate, the ''reset'' method can be called
multiple times during a simulation.
Calling the ''run'' method once amounts to simulating one clock cycle.
The arguments of ''run'' correspond to the inputs and outputs of the
top-level [[component]] in Arx. The Arx C++ code generator takes care
of converting the output signals into //reference arguments// of
''run''. So the calling environment should take care that the correct
inputs are passed to ''run'' before each call and that the returned
outputs are appropriately processed after each call. So:
hardware.run(, ..., );
Of course, the arguments of ''run'' should have the correct data type.
The C++ data type used by the Arx generator can be found in the
generated code (most likely a signed or unsigned integer of some
specific length).
===== Simulation of Multiple Arx Models =====
As mentioned above, all Arx code residing in a single source file is
flattened by the C++ code generator and translated into a single
simulation model. It is possible to incorporate multiple of these
models in one testbench. This is useful for large designs and
especially for dealing with multiple clock domains and multirate
systems.
==== Known Issues ====
In the current version of Arx, the generated code contains global
variables corresponding to registers in the Arx code and to
enumarations. When simulating
multiple models, this may lead to conflicts. The workaround is to make
sure that there are no name conflicts.
This workaround does not help when instantiating the same model
multiple times in the testbench. If the models are needed in the same
clock domain, the problem can be avoided by creating a new level of
hierarchy in Arx and performing the instantiation in Arx.
===== VCD Generation =====
A //value-change dump// ([[wp>Value_change_dump|VCD]]) can be generated during a C++
simulation. This is achieved by setting the following pre-processor
variable:
#define VCD_OUTPUT
When set, the waveforms for //all// signals in the simulation will be
dumped in a file called ''debug.vcd''. Using a suitable waveform
viewer, one can then analyze the waveforms.
==== Known Issue ====
The current version of Arx does not allow to dump only a subset of the
signals. One should be aware that for larger models and longer
simulations, turning on VCD-output generation considerably slows down
the simulation. In addition, one should be aware that the size of
''debug.vcd'' can grow large.
VCD generation does not work when multiple Arx models are instantiated
in the testbench.