Principles of PLI

VPI
‡ Verilog Procedural Interface(VPI)
± PLI2.0: the third generation of PLI library function ± Remove the inconsistency and incompleteness in both tf and acc routines in PLI1.0
‡ Can not use tf or acc routines to read the condition that makes a while loop to terminate.

± Functions in PLI1.0 and PLI2.0 are independent of each other and can co-exist in the same user application.

A PLI Routine Using VPI ‡ User C functions: applications ± ± ± ± The main body of a PLI routine Implement the functionality of the corresponding system call Include a header file called ³vpi_user. ± sizetf ‡ Returns an integer which is same as the number of bits in the returned value of the system call ± calltf ‡ The main function which implements the functionality of the system call ± compiletf ‡ Initialize a set of variables which can be used later during the entire simulation . calltf. compiletf: The actual name is completely user-defined.h´ A set of pre-specified but user-defined functions ‡ sizetf.

/* for sized function callbacks only */ PLI_BYTE8 *user_data. /* vpiSysTask.Time.Sized.A PLI Routine Using VPI ‡ The registration function ± Registering the associated functions and other properties of a system call ‡ First: the names of the associated functions and other properties of the system call are assigned to different fields of a structure of type ³s_vpi_systf_data´ ‡ Second: using the library function ³vpi_register_systf()´ typedef struct t_vpi_systf_data { PLI_INT32 type. /* the compiletf function name */ PLI_INT32 (*sizetf)(PLI_BYTE8 *). vpi[Int. } s_vpi_systf_data. /* first character must be `$' */ PLI_INT32 (*calltf)(PLI_BYTE8 *). /* the calltf function name */ PLI_INT32 (*compiletf)(PLI_BYTE8 *). *p_vpi_systf_data.Real. . /* vpiSysTask. vpiSysFunc */ PLI_INT32 sysfunctype. SizedSigned]Func */ PLI_BYTE8 *tfname.

A PLI Routine Using VPI ‡ The start-up array vlog_startup_routines[] ± Lists all the registration functions ± Presents them to the simulator ± An array of pointers to functions returning void types ± The last element in this array should be zero. .

enter NULL */ vpi_register_systf(&task_data_s). 0}. int add_int_calltf() { pintrf(³Enter the first integer:´.compiletf = NULL.h" #include "vpi_user_cds.h> #include "vpi_user.A simple exampleexample$add_int() #include <stdio. the last element must be a zero.tfname =³$add_int´.calltf = add_int_call_tf. scanf(³%d´. void registration() /* Place all the function registration here */ { s_vpi_systf_data task_data_s.type = vpiSysTask. } /******************************** * The registration function * *******************************/ void registration(). /* The calltf routine */ task_data_s. /*declare the structure */ task_data_s. /* No return value for out system call */ task_data_s. n1+n2). &n2). . * *************************************************************/ void (*vlog_startup_routines[]) () = {registration. &n1). printf(³The sum of two integers: %d\n´. scanf(³%d´. /* No function. printf(³Enter the second integer:´). /* HDL task name */ task_data_s. /* Registering the task */ } /* ********************************************************** The start-up array.h" /******************************************** * The user C function add_int_calltf() * ********************************************/ int add_int_calltf().

h" #include "vpi_user_cds. if (vpi_chk_error(NULL)) { vpi_printf("Error occurred while setting up user %s\n". "$set_values". set_values_calltf. } } } void (*vlog_startup_routines[VPI_MAXARRAY])() = { setup_set_value_callbacks. while (systf_data_p->type) { vpi_register_systf(systf_data_p++). .$set_values() example#include "vpi_user. 0.h" static s_vpi_systf_data systfList[] = { {vpiSysTask. {0}. 0}.h" #include "set_values. void setup_set_value_callbacks() { p_vpi_systf_data systf_data_p = &(systfList[0]). "defined system tasks and functions."). 0 /*** final entry must be 0 ***/ }. return. set_values_checktf. }. 0.A simple example.

Section 6.1 ‡ Verilog-XL ± vconfig generate a shell script generate the compiled binary .Integrating user application with Verilog simulator ‡ The same as what has been described in Chapter 2.

Handle and its declaration ‡ handle: the basic data structure for all data access ± ± ± ± Set up a handle to that object to access the properties of an object An equivalent of a C language pointing to the data structure of the object A way to use indirect addressing All references to that object such as getting its value. using its handle ± Whenever an object is required to be passed to a function. yet_another_Handle . some_Handle. traversing a relationship etc.h as vpiHande ± Irrespective of the nature of the object ‡ The data type of a handle ‡ Handle declaration ± vpiHandle netHandle.mod_Handle. its handle is passed as an argument ± Defined in vpi_user.

Associating a handle to an object ‡ Associate the handle with the object ‡ If we know the name of the object and the handle to its scope ± Vpi_handle_by_name() ± Ex) handle my_handle. an argument to the system call ± If a handle is available to an object. . scope_handle). ‡ If find out a handle to an object which is in some way related to a given object ± Given object: the top level module. ± Ex) If a handle is available to a net or a register. it is possible to get a handle to any other object related to it. it is possible to retrieve a handle pointing to its parent module instance. my_handle = vpi_handle_by_name(³my_reg´.

Relationship between two objects ‡ Relationship between two objects ± Not related ± One-to-one. ± One-to-many ± Many-to-one ‡ VPI handles the one-to-one and the one-to-many relationships ‡ vpi_handle_multi(): the many-to-one relation .

moduleHandle = vpi_handle(vpiModule. A handle to the second object can be obtained using the library function vpi_handle() and the handle to the first object vpi_handle() ± Take the type of relationship and the handle to the first object as its arguments and returns the handle to the second object parent_module_of_a_reg(regHandle) vpiHandle regHandle. regHandle). the symbol for the destination object with a prefix vpi . handleStart). { vpiHandle moduleHandle. /* moduleHandle can be used here for other purpose */ } handleDest = vpi_handle(vpiObj.One-toOne-to-one relationship ‡ ‡ ‡ Ex) a register and its parent module instance ± There can be only one module containing that particular register. the handle handleDest to the destination object the starting object handleStart.

‡ Return an iterator handle.One-toOne-to-many relationship ‡ ‡ EX) the relationship between a module and the registers(or nets). /*The handle to the starting object handleStart The iterator handle itrDest to the destination objects with obj The symbol for the destination object with a prefix vpi */ While(handleDest = vpi_scan(itrDest)) { /* process handleDest */ } . handleStart). ‡ When all such objects are traversed. it returns a NULL. itrDest = vpi_iterate(vpiObj. a module and primitive instances within it vpi_iterate() and vpi_scan() ± vpi_iterate() ‡ take the type of one-to-many relationship to traverse and a handle to a reference object as its arguments. a port and its bits. ± vpi_scan() ‡ Use an iterator handle as its argument in a loop to return a handle to the next object related to the reference object.

} . return ²1.Example int regs_in_a_module(moduleHandle) vpiHandle moduleHandle. regHandle. regItr = vpi_iterate(vpiReg. /* regItr is the iterator handle to all registers inside this module */ if(!regItr) { printf(´No reg inside module\nµ). { vpiHandle regItr. moduleHandle). } else { /* In each iteration the following while loop returns a handle to the next register instantiate within the module */ while(regHandle = vpi_scan(regItr)) { /* Use regHandle here to process anything related to the register */ } } return 0.

switch and UDPs ‡ Method ± Access a class from a given object or another class ‡ How to get a handle to a member of a class starting from an object ± The class regs ‡ comprises of register and individual bit of a register array. . ± Unlike a type such as vpiModule. a method is applicable to a general class of objects and does not depend on the type of the returned handle. ‡ The relationship between a register bit and its parent array of registers is one-to-one.Class and method ‡ Class: objects of similar nature ± A class named primitive: object types gate. reg_bit_handle). ‡ To obtain a handle to the register array from the handle to the register bit ± reg_array_handle = vpi_handle(vpiParent. ± The method vpiParent is used to get the handle reg_array_handle to the parent object within the class regs.

Tagged relationship ‡ tag: predefined keyword used as the first argument for the vpi_handle() or vpi_iterate() ± Allow accessing properties of the destination objects(or class) of a specific type ± Ex) an object of type memory: left and right ranges accessed by using the tags vpiLeftRange and vpiRightRange .

‡ These objects provide a starting point for traversing a relationship. .Getting Handles to basic objects ‡ How a handle can be obtained to some of the most commonly referenced objects(basic objects) without taking the help of any other handle.

return ²1. top_mod_iterator = vpi_iterate(vpiModule. if(!top_mod)iterator) { printf(´No top-level module found\nµ). top_mod_handle)).Getting handles to the top level modules int get_top_mods() { vpiHandle top_mod_iterator. vpi_get_str(vpiName. } else while(top_mod_handle = vpi_scan(top_mod_iterator)) printf(´Top module: %s\nµ. top_mod_handle. return 0 } . NULL).

NULL). int pin = 1. vpiHandle syscall_handle.syscall_handle). tf_param_handle. return ±1.Getting handle to the parameters passed to the current system int list_param() { vpiHandle tf_param_iterator. return 0. if(!tf_param_iterator) { printf(³No arg. } . vpi_get_str(vpiName. return ±1. } else while(tf_param_handle = vpi_scan(tf_param_iterator)) printf(³Parameter %d: %s\n´. syscall_handle = vpi_handle(vpiSysTfCall. if(!syscall_handle) { printf(³No handle to the system call«\n´). tf_param_handle)). to the system call\n´). pin++. } else { tf_param_iterator = vpi_iterate(vpiArgument.

vpi_iterate(): one-to-one. modHandle). modhandle: the handle to the current module vpiDefNetType: an integer property ‡ Relationships ± vpi_handle(). in the case of a class. a tag or. one-to-many ± The type of the destination object(or. int currNetType. currNetType = vpi_get(vpiDefNetType.Design Objects-Properties and Relationships Objects‡ Properties ± Three categories ‡ Boolean and integer: vpi_get() ‡ String: vpi_string_get() ‡ Complex ± The data access interface can be defined in terms of the properties associated with that object or class and the relations it has with other objects/classes ± The property name and the handle to the current object are passed as arguments. the method) .

Remainders: each type of object and class defined in Verilog HDL ‡ Describe the properties and relations associated with it using a tabular format ± The type/method for each object/class is mentioned in parenthesis along with its name in the header ± Ex) object Module: associated with a type vpiModule The first argument of the vpi_handle() or vpi_iterate() .

Summary of functions and their properties Purpose Accessing an object from its properties VPI function vpi_handle_by_name() vpi_handle_by_index() vpi_get() vpi_get_str() vpi_get_value() vpi_put_value() vpi_get_delays() vpi_put_delays() vpi_get_time() vpi_register_cb() vpi_remove_cb() vpi_register_systf() vpi_get_systf_info() vpi_handle() vpi_iterate() vpi_scan() vpi_handle_multi() vpi_mcd_open() vpi_mcd_close() vpi_mcd_print() vpi_mcd_name() vpi_printf() vpi_get_vlog_info() vpi_compare_objects() vpi_chk_error() vpi_free_objects() Accessing properties of an object Getting simulation time Simulation related callbacks User-defined system call routines Traversing relationships File related activities Displaying messages Getting product invocation information Comparing objects Getting error information Freeing allocated memory .

Sources SUNGHO KWAK .

Sign up to vote on this title
UsefulNot useful