Using the DPI and PLI
The following only applies to SystemVerilog support.
DSim uses shared libraries for the DPI and PLI.
DPI
The following options pertain to the DPI:
Option | Description |
---|---|
-sv_lib name |
Loads the named shared library at runtime. The shared library extension for your platform (e.g. ".so") is optional. |
-dpiheader ... |
Generate C/C++ DPI header file for exported items. |
-dpiheader
is a compile-time option. It is given the name of an include file to write out which contains prototypes for any exported SystemVerilog tasks/functions, as well as definitions for any structs that have C compatible layout.
-sv_lib
is a runtime option only. This option may be given multiple times, to load more than one DPI library.
DPI Import
If SystemVerilog code declares a DPI import function, then the resulting image will reference the function, which ought to be resolved by loading a library (see above). Resolution failures are detected at the point where a DPI function is called to allow images to run without the DPI library, as long as they don't try to call the DPI functions.
DPI Export
If SystemVerilog code declares a DPI export function, then the resulting image will define the corresponding C function. This function will link properly with any DPI code provided, even if the call into the DPI export is made from a DPI import function. (Not all simulators support this smoothly!)
PLI
PLI support is evolving. The current support is sufficient to support licensing calls for specific partners, and fetch/deposit for UVM register model backdoor operations. Other applications may work, but this is not guaranteed. If your application does not work, use -trace-vpi
to help find out why and contact Metrics support for assistance.
DSim aims to support the VPI interface. As of SystemVerilog, the tf and acc interfaces are deprecated. New code should not be using these. DSim supports a very limited set of tf routines, and does not support acc at all.
The following options pertain to the PLI:
Option | Description |
---|---|
-pli_lib name |
Loads the named shared library at compile time and run time. The shared library extension for your platform (e.g. ".so") is optional. dsim will look in the shared library for the vlog_startup_routines array and will call the routines within the array. Note: The routines listed in the array should be declared as static to avoid conflicting with other bootstrap routines. |
+acc+[rwcbfsWF] |
Instruments the compiled code for VPI access. Using this option incurs a runtime penalty. |
-acc-specs file |
Allows fine-grained specification of VPI accessibility. |
Unlike DPI, PLI libraries must be loaded in both at compile time and run time. The set of system calls defined by a PLI library is given in a table in the library, which also contains pointers to functions used at compile time to validate arguments (checktf,sizetf
).
Specifying VPI Object Accessibility
Each variable/net in the design has a VPI accessibility, which consists of one or more of the following permissions:
Name | Description |
---|---|
r | The object's value can be read, or attributes can be queried. |
w | The object's value can be written, but not forced. |
c | The object's connectivity can be extracted (vpiLowConn , vpiHighConn ) |
b | Callbacks can be set on the object. This permission is required to allow waveform dump of the object. |
f | The object can be forced as a whole. |
W | Individual elements of an unpacked array variable can be forced. |
F | Individual bits of an integral variable can be forced. |
s | (Whole design only) Enables inclusion of the PLI simulation regions (Pre/PostNBA, Pre/PostReNBA used for cbReadWriteSynch or cbReadOnlySynch ). Enabling these regions will result in a slight loss of performance. |
The +acc+[rwcbfsWF]
option is used to specify the default accessibility for the whole design. Default is no access. A value of +acc
is equivalent to +acc+rwb
.
For finer-grain control, one may specify the accessibility of any net in an external file, using the -acc-specs
option. The file is of a common format described in Setting Options by Scope Using Specification File.
Each line in the -acc-specs
file is either a module line, a path line, or a net line.
The key word module
indicates a module line of the form
module name +mode
where name
is the name of a module (not an instance) and mode
is one or more of the permissions rwcbf
. The module line specifies the default permissions of all variables/nets in the module.
The key word path
indicates a path line of the form
signal path +mode
where path
is indicates a scope starting point and mode
is one or more of the permissions rwcbf
. A net(s)/variable(s) in the path's scope will have the mode applied.
The keyword signal
indicates a net line of the form
signal name +mode
where name
is the name of a net/variable, and mode
is one or more of the permissions rwcbf
.
The #
or //
strings may be used to introduce comments.
Impact of Specifying Permissions
The VPI permissions allow DSim to optimize the design and choose implementations without impacting VPI requirements. Absent any VPI access requirements, DSim's optimizers may transform the design in ways that would result in incorrect behavior.
Read Permission
Consider the code:
reg [3:0] foo = 10; always @(x) y = {foo,x};
If we knew that there was no requirement to read foo
, then we can change the code to:
always @(x) y = {4'd10,x};
However, if there were a VPI reader, then after the optimization, the VPI code would fail due to optimization removing the declaration of foo
.
Write Permission
Consider the code:
assign a = b & c; assign d = a | e;
If we knew that nothing outside the code could possibly write to a
, then we can change the code to:
always @(b or c or e) begin a = b & c; d = a | e; end
Since two processes have been reduced to one, we can amortize the overhead of block scheduling. Assuming that the computations are cheap (e.g. the variables are single-bit reg
) this is a big savings. However, this transform fails if VPI writes to a
: since the transformed block is no longer sensitive to a
, a write to a
will never provoke an update of d
. Adding +w
permission to a
will disable this optimization and result in correct behavior, but lower performance.
More importantly, write permission is required if vpi_put_value()
will be called with a delay, so that the variable can be instrumented with the data structures required to implement the delay mechanism.
Callback permission
When +b
permission is specified for a net/variable, then every time the variable is updated, the new value is compared to the previous value, and the value change callback is invoked if there is a change. The code to compare and execute callback is compiled into every expression that may update the variable, and the compare logic may be as costly as the update to the variable itself. Although DSim also has to do comparisons on variables for which other processes are sensitive, DSim tries to generate the comparison code only when necessary.
When the +b
permission is specified for a scope containing a concurrent or immediate assertion, then every time an assertion evaluation starts or ends, DSim checks for registered callbacks to invoke. These checks add extra overhead to assertion evaluation, even if no callbacks are registered.
Force permission
When a variable is forced, the compiled code tracks whether or not the variable is currently forced. The force state of a variable is checked prior to each write, so that the write is "not done" when the variable is forced. Similar to callbacks, this adds considerable overhead to each write. Normally, DSim will instrument variables for forcing only if a Verilog force
statement could potentially reference the variable - this property can be statically computed at compile time. However, with +f
, DSim must instrument every single variable having this permission, which again is quite costly.
The situation is worse for nets. Individual bits of a net can be forced, so a write to a multi-bit net may result in some bits (the unforced bits) changing value, and other bits not changing. Net forcing is actually done using an interpreted engine, which also handles inout
ports, strength logic modelling, tran solving and net delays. Again, this treatment is usually reserved only for those nets that can be determined to be forced at compile time, but +f
will force this treatment for every affected net.
The SV-LRM restricts variable forcing as operating only on singular (ie non-unpacked-array) variables. As an extension, DSim lifts such a restriction to permit the operation on bit-select/part-select of singular variables, and individual singular elements (a.k.a. words) of an unpacked array. Bit-level and word-level forcing requires additional overhead to track possible forces down to the bit or word level. The required instrumentation level (none, entire, word, bit) is determined for each variable separately. For Verilog/SystemVerilog code this is done by analyzing all references to the variable to determine the correct level. For VPI access, the required level is determined by the VPI flags:
* +acc+f
instruments for forcing of singular variables.
* +acc+W
instruments for forcing of individual words of an uni-dimensional or multi-dimensional unpacked array.
* +acc+F
instruments for forcing of individual bits of a singular variable or word.
+acc+WF
is relevant only for variables; all VPI forces to 4-state nets work at bit-level, even with +acc+f
.
Performance loss with a global +acc+f
, +acc+W
, or +acc+F
is so bad that it is strongly recommended to use an -acc-specs
file to apply force permission only to those nets that specifically require it.
Tracing/debugging DPI/PLI/VPI
Name | Description |
---|---|
-debug-vpi |
Log all failed/invalid VPI calls. |
-trace-vpi |
Log all VPI calls, successful or otherwise. Also log actions associated with PLI library loading. |
-trace-dpi |
Log all actions associated with DPI library loading. |
Building Shared Libraries
This is platform-specific.
Linux x86, 32-bit
To compile:
gcc -c -o file.o file.c -I$DSIM_HOME/include
To create shared library:
gcc -shared -o mylib.so file1.o file2.o ...
Linux x86, 64-bit
To compile:
gcc -c -fPIC -o file.o file.c -I$DSIM_HOME/include
To create shared library:
gcc -shared -o mylib.so file1.o file2.o ...