Principles of PLI VPI Verilog Procedural InterfaceVPI PLI




![A PLI Routine Using VPI • The start-up array vlog_startup_routines[] – Lists all the A PLI Routine Using VPI • The start-up array vlog_startup_routines[] – Lists all the](https://slidetodoc.com/presentation_image_h/d7a252cae97443bd55994b994c8ed2d7/image-5.jpg)


















- Slides: 23
Principles of PLI
VPI • Verilog Procedural Interface(VPI) – PLI 2. 0: the third generation of PLI library function – Remove the inconsistency and incompleteness in both tf and acc routines in PLI 1. 0 • Can not use tf or acc routines to read the condition that makes a while loop to terminate. – Functions in PLI 1. 0 and PLI 2. 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. h” A set of pre-specified but user-defined functions • sizetf, calltf, compiletf: The actual name is completely user-defined. – 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
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_INT 32 type; /* vpi. Sys. Task, vpi. Sys. Func */ PLI_INT 32 sysfunctype; /* vpi. Sys. Task, vpi[Int, Real, Time, Sized. Signed]Func */ PLI_BYTE 8 *tfname; /* first character must be `$' */ PLI_INT 32 (*calltf)(PLI_BYTE 8 *); /* the calltf function name */ PLI_INT 32 (*compiletf)(PLI_BYTE 8 *); /* the compiletf function name */ PLI_INT 32 (*sizetf)(PLI_BYTE 8 *); /* for sized function callbacks only */ PLI_BYTE 8 *user_data; } s_vpi_systf_data, *p_vpi_systf_data;
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.
A simple example$add_int() /**************** * The registration function * ****************/ void registration(); void registration() /* Place all the function registration here */ { s_vpi_systf_data task_data_s; /*declare the structure */ task_data_s. type = vpi. Sys. Task; /* No return value for out system call */ task_data_s. tfname =“$add_int”; /* HDL task name */ task_data_s. calltf = add_int_call_tf; /* The calltf routine */ task_data_s. compiletf = NULL; /* No function, enter NULL */ vpi_register_systf(&task_data_s); /* Registering the task */ } /* ***************************** The start-up array, the last element must be a zero. * *******************************/ void (*vlog_startup_routines[]) () = {registration, 0}; #include <stdio. h> #include "vpi_user. h" #include "vpi_user_cds. h" /********************** * The user C function add_int_calltf() * **********************/ int add_int_calltf(); int add_int_calltf() { pintrf(“Enter the first integer: ”; scanf(“%d”, &n 1); printf(“Enter the second integer: ”); scanf(“%d”, &n 2); printf(“The sum of two integers: %dn”, n 1+n 2); }
A simple example- $set_values() #include "vpi_user. h" #include "vpi_user_cds. h" #include "set_values. h" static s_vpi_systf_data systf. List[] = { {vpi. Sys. Task, 0, "$set_values", set_values_calltf, set_values_checktf, 0, 0}, {0}, }; void setup_set_value_callbacks() { p_vpi_systf_data_p = &(systf. List[0]); while (systf_data_p->type) { vpi_register_systf(systf_data_p++); if (vpi_chk_error(NULL)) { vpi_printf("Error occurred while setting up user %sn", "defined system tasks and functions. "); return; } } } void (*vlog_startup_routines[VPI_MAXARRAY])() = { setup_set_value_callbacks, 0 /*** final entry must be 0 ***/ };
Integrating user application with Verilog simulator • The same as what has been described in Chapter 2, Section 6. 1 • Verilog-XL – vconfig generate a shell script generate the compiled binary
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, traversing a relationship etc. using its handle – Whenever an object is required to be passed to a function, its handle is passed as an argument • The data type of a handle – Defined in vpi_user. h as vpi. Hande – Irrespective of the nature of the object • Handle declaration – vpi. Handle net. Handle, mod_Handle, some_Handle, yet_another_Handle
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; my_handle = vpi_handle_by_name(“my_reg”, 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, an argument to the system call – If a handle is available to an object, it is possible to get a handle to any other object related to it. – Ex) If a handle is available to a net or a register, it is possible to retrieve a handle pointing to its parent module instance.
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
One-to-one relationship • Ex) a register and its parent module instance – There can be only one module containing that particular register. • • 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(reg. Handle) vpi. Handle reg. Handle; { vpi. Handle module. Handle; module. Handle = vpi_handle(vpi. Module, reg. Handle); /* module. Handle can be used here for other purpose */ } handle. Dest = vpi_handle(vpi. Obj, handle. Start); the handle. Dest to the destination object the starting object handle. Start, the symbol for the destination object with a prefix vpi
One-to-many relationship • • EX) the relationship between a module and the registers(or nets), a port and its bits, 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. • Return an iterator handle. – 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. • When all such objects are traversed, it returns a NULL. itr. Dest = vpi_iterate(vpi. Obj, handle. Start); /*The handle to the starting object handle. Start The iterator handle itr. Dest to the destination objects with obj The symbol for the destination object with a prefix vpi */ While(handle. Dest = vpi_scan(itr. Dest)) { /* process handle. Dest */ }
Example int regs_in_a_module(module. Handle) vpi. Handle module. Handle; { vpi. Handle reg. Itr, reg. Handle; reg. Itr = vpi_iterate(vpi. Reg, module. Handle); /* reg. Itr is the iterator handle to all registers inside this module */ if(!reg. Itr) { printf(“No reg inside modulen”); return – 1; } else { /* In each iteration the following while loop returns a handle to the next register instantiate within the module */ while(reg. Handle = vpi_scan(reg. Itr)) { /* Use reg. Handle here to process anything related to the register */ } } return 0; }
Class and method • Class: objects of similar nature – A class named primitive: object types gate, 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. • The relationship between a register bit and its parent array of registers is one-to-one. • To obtain a handle to the register array from the handle to the register bit – reg_array_handle = vpi_handle(vpi. Parent, reg_bit_handle); – The method vpi. Parent is used to get the handle reg_array_handle to the parent object within the class regs. – Unlike a type such as vpi. Module, a method is applicable to a general class of objects and does not depend on the type of the returned handle.
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 vpi. Left. Range and vpi. Right. Range
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. • These objects provide a starting point for traversing a relationship.
Getting handles to the top level modules int get_top_mods() { vpi. Handle top_mod_iterator, top_mod_handle; top_mod_iterator = vpi_iterate(vpi. Module, NULL); if(!top_mod)iterator) { printf(“No top-level module foundn”); return – 1; } else while(top_mod_handle = vpi_scan(top_mod_iterator)) printf(“Top module: %sn”, vpi_get_str(vpi. Name, top_mod_handle)); return 0 }
Getting handle to the parameters passed to the current system int list_param() { vpi. Handle tf_param_iterator, tf_param_handle; vpi. Handle syscall_handle; int pin = 1; syscall_handle = vpi_handle(vpi. Sys. Tf. Call, NULL); if(!syscall_handle) { printf(“No handle to the system call…n”); return – 1; } else { tf_param_iterator = vpi_iterate(vpi. Argument, syscall_handle); if(!tf_param_iterator) { printf(“No arg. to the system calln”); return – 1; } else while(tf_param_handle = vpi_scan(tf_param_iterator)) printf(“Parameter %d: %sn”, pin++, vpi_get_str(vpi. Name, tf_param_handle)); return 0; }
Design Objects-Properties and Relationships • 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. int curr. Net. Type; curr. Net. Type = vpi_get(vpi. Def. Net. Type, mod. Handle); modhandle: the handle to the current module vpi. Def. Net. Type: an integer property • Relationships – vpi_handle(), vpi_iterate(): one-to-one, one-to-many – The type of the destination object(or, a tag or, in the case of a class, 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 vpi. Module The first argument of the vpi_handle() or vpi_iterate()
Summary of functions and their properties Purpose Accessing an object from its properties 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 VPI function vpi_handle_by_name() vpi_handle_by_index() 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()
Sources SUNGHO KWAK