In general Verilator flattens the Verilog module hierarchy when generating C++ or SystemC models, and will generate just a small number of C++ classes (very often just one).
However when direct access to a signal is needed, Verilator must expose the hierarchy, and will define multiple C++ classes, corresponding to the modules in the hierarchy to the signal.
For example with ORPSoC the top level SystemC module generated
is Vorpsoc_fpga_top
. As shown in Section 5.2.1, this was used when instantiating the main
ORPSoC module:
orpsoc = new Vorpsoc_fpga_top ("orpsoc");
However if the wb_freeze
signal in the CPU
control unit were to be accessed additional C++ classes would be
declared. The signal's hierarchical references is:
orpsoc_fpga_top.or1200_top.or1200_cpu.or1200_ctrl.wb_freeze
Verilator creates public classes for all the intermediate modules in
this hierarchy (or1200_top
,
or1200_cpu
and or1200_ctrl
),
each of which includes a pointer to the next level down in the
hierarchy. Thus the wb_freeze
can be accessed
from C++ through the top level module (orpsoc
,
instantiated as above) as follows:
orpsoc->v->or1200_top->or1200_cpu->or1200_ctrl->wb_freeze
Notice that there is one intervening class, v
,
after the top level module. This is explained later.
To access these, the header files for the intervening modules must be included. These take their name from the top level module, and the intermediate module, thus:
#include "Vorpsoc_fpga_top_or1200_top.h" #include "Vorpsoc_fpga_top_or1200_cpu.h" #include "Vorpsoc_fpga_top_or1200_ctrl.h"
All these intermediate modules are plain C++ classes, not SystemC
modules. This is the reason for the intervening class,
v
. The top level class,
Vorpsoc_fpga_top
is a
SystemC module. However it is only a wrapper for the plain C++
Verilator model of the top level module. Thus the
v
points to the plain C++ model of the top level
module, and is inserted after the SystemC module at the top
level. It has its own header, which must be included:
#include "Vorpsoc_fpga_top_orpsoc_fpga_top.h"
Note | |
---|---|
Verilator does provide a mechanism for accessing signals without
breaking up the C++ into separate modules. This is achieved by use
of the However if access to a diverse range of signals in many modules is required, this may be necessary to avoid the performance penalty of breaking the model into many small classes. |