Passing Arguments: By Value or By Reference
Both imported and exported tasks and functions can have zero or more
arguments passed to them. The arguments can be passed either by value
or by reference (that is, through a pointer).
Passing an argument by value requires maintaining a copy of the
argument inside the compiler. For this reason, it is usually limited
to 'small' SystemVerilog input data.
Passing by reference, however, does not require any copying of data
and DPI maintains the same basic layout of the data across the boundary.
For example, a 32-bit integer remains a 32-bit integer after crossing the
boundary between SystemVerilog and C regardless of the direction of
data transfer. An exception when copying does occur is when an element or
range of elemenets of a packed array is passed as argument (though in C
parlance, this is equivalent of passing by reference).
For exported task and function, the user has the responsibility of
allocating memories for any arguments passed by reference. This means
the user must know the mapping between the SystemVerilog data type that
the exported task or function expects and the C type that is being
passed. Specifically, if you are passing an element or range of a packed
array, as we saw
earlier, you must know how it is representated on the C side in order
to allocate memories for that argument. The header file svdpi_src.h
provides these system and implementation specific information.
Direction of Arguments
SystemVerilog has a notion of direction for any task or function argument.
An argument must be one of input, output or inout.
However, C does not have any such notion. The conflict arises, for example,
when the C side tries to modify an argument that is declared as an input
on the import declaration. For this and various other reasons, there are
some specific rules related to the direction of an argument.