1. Introduction to PLI functions
Verilog PLI(Programming Language Interface) is a mechanism for Verilog code to call C/C++ functions. It enables Verilog to call C/C++ functions written by users like some system calls (e.g. $display/$stop/$random), so that we can start our own system task/function with C/C++ language to realize the inconvenient functions of Verilog and establish contact with the outside world.
PLI can accomplish the following functions:
Power analysis
Code Coverage Tool
Modify Verilog simulation data structure (e.g. change to more precise delay, i.e. sdf inversion)
Custom Output Display
Joint simulation
Debugging function of design
Simulation analysis
C Model Interface for Accelerated Simulation
Testbench Modeling
Verilog PLI provides some access to the internal data structure of verilog
TF routines: Most of them start with tf_and are mainly used for user-defined operation of system tasks and function variables, tool functions (such as setting callback functions and writing data to output)
Access routines: Second generation PLI. All begin with acc_ Object-oriented access to SV structure is provided. It is mainly used to access and modify information, which is partly duplicated by delay value, logic value. ACC routines and TF routines.
VPI routines: Third generation PLI. Most start with vpi_ Object-oriented access to SV structure, behavior, assertion, coverage objects is provided. It contains all the functions of TF and ACC routines.
2. User-defined task/function naming
The rules are as follows:
The first character must be$
The remaining characters can be letters, numbers, underscores, or$
Case-sensitive
Names can be of any length
3. User-defined task/function parameters
Example:
$get_vector("test_vector.pat", input_bus);
A set of PLI routines can be used in PLI programs to read/write these parameters
4. task/function
User-defined task can be used anywhere SV task can be used
User-defined function s can be used anywhere SV task can be used, return values, and the length is determined by user-provided sizetf
5. User-provided PLI application
Such C functions are not independent C programs, but are Link-loaded into tools, which may be called when user-defined task/function is called.
6. PLI include file
Definition
constant
struct
data
These documents are
vpi_user.h
sv_vpi_user.h
7. NC Example
Files
test.v
module test; wire a, b, c; initial begin $module_info; end pipe p1 (a, b, c); //stimuli //monitor response endmodule
pipe.v
module pipe ( out, in, clk ); output out; reg out; input in, clk; always @ (in) @ (posedge clk) out <= repeat (2) @ (posedge clk) in; endmodule
mod_info.c
#include <stdio.h> #include "vpi_user.h" #include "vpi_user_cds.h" void module_info() { vpiHandle moditH, topmodH; moditH = vpi_iterate(vpiModule, NULL); if(!moditH) { vpi_printf(" Error: no modules in the design\n"); } while (topmodH = vpi_scan(moditH)) { vpi_printf("Top module Full Name: %s\n", vpi_get_str(vpiFullName, topmodH)); vpi_printf(" Top module Name: %s\n", vpi_get_str(vpiName, topmodH)); } } void register_my_systfs() { s_vpi_systf_data task_data_s; p_vpi_systf_data task_data_p = &task_data_s; task_data_p->type = vpiSysTask; task_data_p->tfname = "$module_info"; task_data_p->calltf = (int(*)()) module_info; task_data_p->compiletf = 0; vpi_register_systf(task_data_p); }
pli.map
$module_info call = module_info
vpi_user.c
#include <stdarg.h> #include "vpi_user.h" #include "vpi_user_cds.h" extern void register_my_systfs(); void (*vlog_startup_routines[VPI_MAXARRAY])() = { register_my_systfs, 0 /*** final entry must be 0 ***/ };
RUN
There are three ways to run on NC, but the first one is not tried.
Method 1 Using the irun Utility
irun test.v pipe.v module_info.c -loadvpi :module_info
Actual measurements will not find $module_info at run time
Method 2 Using a PLI/VPI Map File
The plimap file is shown above.
irun test.v pipe.v mod_info.c -plimapfile pli.map -gui
Load-plimap file at run time
Or it can be loaded when elab
irun test.v pipe.v mod_info.c -afile pli.map -gui
Method Three Associating C Functions with a New System Task
Register your VPI program with C function
Initialize an s_vpi_systf_data structure
Call vpi_register_systf()
Provide the name of the registration function to simulator
typedef struct t_vpi_systf_data { int type; int sysfunctype; char *tfname; int (*calltf)(); int (*compiletf)(); int (*sizetf)(); char *user_data; } s_vpi_systf_data, *p_vpi_systf_data;
Run the command as follows:
gcc -fPIC -c -o vpi_user.o vpi_user.c mod_info.c -I${IES_HOME}/tools/include -I${IES_HOME}/tools/inca/include gcc -shared -fPIC -o libvpi.so vpi_user.o irun -c test.v pipe.v irun -64bit -R
The tool automatically loads libvpi.so
perhaps
gcc -fPIC -shared -o libmyvpi.so vpi_user.c mod_info.c -I${IES_HOME}/tools/include -I${IES_HOME}/tools/inca/include ncvlog test.v pipe.v ncelab -access +rw test -loadvpi libmyvpi:register_my_systfs ncsim test -input
For PLI, using - sv_lib is not useful
gcc -fPIC -shared -o libmyvpi.so vpi_user.c mod_info.c -I${IES_HOME}/tools/include -I${IES_HOME}/tools/inca/include irun -c test.v pipe.v irun -R -64bit -sv_lib libmyvpi.so
Errors will be reported:
irun(64): 15.10-s020: (c) Copyright 1995-2016 Cadence Design Systems, Inc. Loading snapshot worklib.test:v .................... Done $module_info; | ncsim: *E,MSSYSTF (./test.v,5|17): User Defined system task or function ($module_info) registered during elaboration and used within the simulation has not been registered during simulation.
Note: Part 7 above is owned by Cadence.