<- Click here to Toggle

Home » Resources » Direct Programming Interface(DPI) » Imported Tasks & Funcions

Imported Tasks & Funcions

The usage of imported functions is similar as for native SystemVerilog functions.

a) Required properties of imported tasks and functions — semantic constraints:

The semantic constraints imposed on imported tasks or functions. Some semantic restrictions are shared by all imported tasks or functions. Other restrictions depend on whether the special properties pure or context are specified for an imported task or function.

Instant completion of imported functions: Imported functions shall complete their execution instantly and consume zero-simulation time, similarly to native functions. Note that imported tasks can consume time, similar to native SystemVerilog tasks.

Input, Output and Inout arguments: Imported functions can have input,output and inout arguments. The formal input arguments shall not be modified. If such arguments are changed within a function, the changes shall not be visible outside the function; the actual arguments shall not be changed.

The imported function shall not assume anything about the initial values of formal output arguments. The initial values of output arguments are undetermined and implementation dependent.

The imported function can access the initial value of a formal inout argument. Changes that the imported function makes to a formal inout argument shall be visible outside the function.

Special properties pure and context: A function whose result depends solely on the values of its input arguments and with no side effects can be specified as pure . This can usually allow for more optimizations and thus can result in improved simulation performance. An imported task can never be declared pure.

An imported task or function that is intended to call exported tasks or functions or to access SystemVerilog data objects other then its actual arguments e.g. via VPI or PLI calls must be specified as context . A task or function not specified as context shall not read or write any data objects from SystemVerilog other then its actual arguments. the effects of calling PLI, VPI, or exported SystemVerilog tasks or functions can be unpredictable and can lead to unexpected behavior.

If neither the pure nor the context attribute is used on an imported task or function, the task or function shall not access SystemVerilog data objects, however it can perform side-effects such as writing to a file or manipulating a global variable.

Memory management: The memory spaces owned and allocated by the foreign code and SystemVerilog code are disjoined. Each side is responsible for its own allocated memory. Specifically, an imported function shall not free the memory allocated by SystemVerilog code (or the SystemVerilog compiler) nor expect SystemVerilog code to free the memory allocated by the foreign code (or the foreign compiler). In this last scenario, a block of memory is allocated and freed in the foreign code, even when the standard functions malloc and free are called directly from SystemVerilog code.

Reentrancy of imported tasks: Since imported tasks can block (consume time), it is possible for an imported task’s C code to be simultaneously active in multiple execution threads. Standard reentrancy considerations must be made by the C programmer.

C++ exceptions: It is possible to implement DPI imported tasks and functions using C++, as long as C linkage conventions are observed at the language boundary. If C++ is used, exceptions must not propagate out of any imported task or function.

b) Pure functions:

A pure function call can be safely eliminated if its result is not needed or if the previous result for the same values of input arguments is available somehow and can be reused without needing to recalculate. Only nonvoid functions with no output or inout arguments can be specified as pure . Functions specified as pure shall have no side effects whatsoever; their results need to depend solely on the values of their input arguments.

Specifically, a pure function is assumed not to directly or indirectly

a) perform any file operations.

b) read or write anything in the broadest possible meaning, includes i/o, environment variables, objects from the operating system or from the program or other processes, shared memory, sockets, etc.

c) access any persistent data, like global or static variables.

c) Context tasks and functions :

Some DPI imported tasks or functions require that the context of their call is known. It takes special instrumentation of their call instances to provide such context. All DPI exported tasks or functions require that the context of their call is known. This occurs since SystemVerilog task or function declarations always occur in instantiable scopes, hence allowing a multiplicity of unique task or function instances.

For the sake of simulation performance, an imported task or function call shall not block SystemVerilog compiler optimizations. Only the actual arguments can be affected (read or written) by its call. For imported tasks or functions not specified as context , the effects of calling PLI or VPI functions or SystemVerilog tasks or functions can be unpredictable and such calls can crash if the callee requires a context that has not been properly set.

The declaring an import context task or function does not automatically make any other simulator interface automatically available. For VPI access (or any other interface access) to be possible, the appropriate implementation defined mechanism must still be used to enable these interface(s).

d) Import declarations:

Each imported task or function shall be declared. Such declaration are referred to as import declarations .The syntax of an import declaration is similar to the syntax of SystemVerilog task or function prototypes.

Imported functions can have the properties context or pure. imported tasks can have the property context . Import declaration is equivalent to defining a task or function of that name in the SystemVerilog in which the import declaration occurs, and thus multiple imports of the same task or function name into the same scope are forbidden. c_identifier provides the linkage name for this task or function in the foreign language. The qualifier ref cannot be used in import declarations.

The following are examples of external declarations.

import "DPI" function void myInit();
import "DPI" pure function real sin(real);// from stdandard math library
import "DPI" function chandle malloc(int size); // standard C function
import "DPI" function chandle newElem(bit [15:0]);// the prior import, but has different SystemVerilog name and provides a default value for the argument.

Calling imported functions:

The usage of imported functions is identical as for native SystemVerilog functions. Specifically, arguments with default values can be omitted from the call; arguments can be passed by name, if all formal arguments are named.

Argument passing:

Argument passing for imported functions is ruled by the WYSIWYG principle. The principle “What You Specify Is What You Get” guarantees the types of formal arguments of imported functions an actual argument is guaranteed to be of the type specified for the formal argument, with the exception of open arrays. Another way to state this is that no compiler (either C or SystemVerilog) can make argument coercions between a caller’s declared formal and the callee’s declared formals. this is because the callee’s formal arguments are declared in a different language than the caller’s formal arguments;

The evaluation order of formal arguments follows general SystemVerilog rules. For input and inout arguments, the temporary variable is initialized with the value of actual argument with the appropriate coercion; For output or inout arguments, the value of the temporary variable is assigned to the actual argument with the appropriate conversion. The assignments between a temporary and the actual argument follow general SystemVerilog rules for assignments and automatic coercion.

The actual implementation of argument passing is transparent to the SystemVerilog side of the interface. In particular, it is transparent to SystemVerilog whether an argument is actually passed by value or by reference.

Value changes for output and inout arguments: The SystemVerilog simulator is responsible for handling value changes for output and inout arguments. Such changes shall be detected and handled after control returns from imported functions to SystemVerilog code.