This is an excerpt from the Chapter 1 of the book Principles of Verilog PLI by Swapnajit Mittra published from Kluwer Academic Publishers. ISBN: 0-7923-8477-6 [All copyright reserved. No portion of this text can be used for for commercial purpose without explicit permission from the author nor can it be used for re-print in hardcopy or electronic form.] Order the book here.

PLI - A QUICK TOUR

Previous | Next

FOUR STEPS FOR WRITING A PLI ROUTINE

Step 3 of 4: The essential data structure

There are a number of data structures that must be defined in a PLI program. These are the variables through which Verilog communicates with the C code. Although OVI (Open Verilog International - the organization responsible for standardizing Verilog) recommends only one mandatory datastructure (veriusertfs), the exact number and syntax of these data structures vary from simulator to simulator. Verilog-XL from Cadence Design Systems, for example, requires four such data structures and functions for any PLI routine to work, whereas VCS, from Chronologic needs none, but needs a separate input file. Going by the popularity ofVerilog XL, we are going to mention all four of them here; the users of Chronologic VCS and Veriwell may ignore the them. These data structures, in the order they should appear, are given below.
veriuser_version_str
This character pointer can be used to indicate a version of the compiled Verilog for your reference. It can be also set to NULL string.The string appears on standard out as well as goes to the Verilog log file when you run your compiled Verilog. A typical example of using it is shown below.

char *veriuser_version_str ="\n\
=============================\n\
VERILOG PLI FIRST_ATTEMPT \n\
($print_reg) \n\
=============================\n";

endofcompile_routines
This data structure, as the name suggests, can be used for declaring functions that will be invoked at the end of the simulation. The present example does not need it. Nonetheless there has to be a default definition as shown below.

int (*endofcompile_routines[])() ={0};

err_intercept
This function, which returns either true or false (i.e. a boolean type), can be used to enhance the error detection mechnism of the code and can be ignored for small applications. A typical example of this routine would be as shown below.

bool err_intercept(level, facility,code)
int level; char * facility; char *code;
{ return (true); }

veriusertfs
The main interaction between the C-code that one writes and the Verilog simulator is done through a table. The Verilog simulator looks at this table and figures out the properties that the system call corresponding to this PLI routine would be associated with. This array, called veriusertfs in Verilog XL, may not be called by any other name as the simulator will not recognize that. Each element of veriusertfs has a distinct function and is very important to achieve the overall objective of writing the PLI routine.

The number of rows in veriusertfs is same as that of the number of user-defined system calls, plus one for the last entry, which is a mandatory {0} .

In the present case, the veriusertfs array should look like:

s_tfcell veriusertfs[] =
{
/*** Template for an entry :
{usertask|userfunction,
data,
checktf(),
sizetf(),
calltf(),
misctf(),
"$tfname"
},
***/
{usertask, 0, my_checktf, 0, my_calltf,0, "$print_reg"},
{0} /* Final entry must be zero */
}

In the above data-structure my_checktf and my_calltf are the names ofthe two functions that we will use to implement the system call $print_reg. my_checktf is the routine which checks the validity of the passed parametersetc and my_calltf actually executes the system call. These names are arbitrary and could have been something else. The first entry usertask indicates that the system call does not return anything and is equivalent to procedure in Pascal or function returning void in C. Note that :

  • The relative positions of these names in veriusertfs are very important- for example my_checktf (or any other name ) has to be the 3rd element,as long as we want to use it as a checking function.
  • Any function that we do not use (e.g. misctf in our example. The objective of providing so many functions will be discussed in Chapter 2) should be replaced by a '0'.
  • We need to define a separate entry in veriusertfs for each system call in case there are more than one.
This table, in case of VCS, is written in a separate file, usually called PLI.tab (once again the name could be anything) whose content, in the present example, will be as shown below.

$print_reg check=my_checktf call=my_calltf

Previous | Next Share/Save/Bookmark




Verification Management
Join Verification Management Group


Shop Amazon - Contract Cell Phones & Service Plans

Book of the Month