📄 read_delays_vpi.c
字号:
/**********************************************************************
* $read_delays example -- PLI application using VPI routines
*
* C source to read path delay values of Verilog module paths. Prints
* the names of all path delays in the module and rise and fall delay
* of each path. Note that module paths do not have a name, so a name
* is created by concatenating the names of the input and output
* terminals togehter, with a dollar sign between the names.
*
* Usage: $read_delays(<cell_module_name>);
*
* For the book, "The Verilog PLI Handbook" by Stuart Sutherland
* Book copyright 1999, Kluwer Academic Publishers, Norwell, MA, USA
* Contact: www.wkap.il
* Example copyright 1998, Sutherland HDL Inc, Portland, Oregon, USA
* Contact: www.sutherland.com or (503) 692-0898
*********************************************************************/
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#include "veriuser.h" /* IEEE 1364 PLI TF routine library
(using TF routines for simulation control) */
/* prototypes of routines in this PLI application */
int PLIbook_ReadDelays_calltf(), PLIbook_ReadDelays_compiletf();
void PLIbook_PrintDelays();
char *PLIbook_BuildPathName();
/**********************************************************************
* VPI Registration Data
*********************************************************************/
void PLIbook_ReadDelays_register()
{
s_vpi_systf_data tf_data; /* allocate register data structure */
tf_data.type = vpiSysTask;
tf_data.tfname = "$read_delays";
tf_data.calltf = PLIbook_ReadDelays_calltf;
tf_data.compiletf = PLIbook_ReadDelays_compiletf;
tf_data.sizetf = NULL;
vpi_register_systf(&tf_data);
}
/*********************************************************************/
/**********************************************************************
* compiletf routine
*********************************************************************/
int PLIbook_ReadDelays_compiletf(char *user_data)
{
vpiHandle systf_h, arg_itr, arg_h;
int tfarg_type;
/* obtain a handle to the system task instance */
systf_h = vpi_handle(vpiSysTfCall, NULL);
/* obtain handles to system task arguments */
arg_itr = vpi_iterate(vpiArgument, systf_h);
if (arg_itr == NULL) {
vpi_printf("ERROR: $read_delays requires 1 argument\n");
tf_dofinish(); /* abort simulation */
return(0);
}
/* check the type of object in system task arguments */
arg_h = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_h);
if (tfarg_type != vpiModule) {
vpi_printf("ERROR: $read_delays arg1 must be a module instance\n");
vpi_free_object(arg_itr); /* free iterator memory */
tf_dofinish(); /* abort simulation */
return(0);
}
/* check that there is only 1 system task argument */
arg_h = vpi_scan(arg_itr);
if (arg_h != NULL) {
vpi_printf("ERROR: $read_delays can only have 1 argument\n");
vpi_free_object(arg_itr); /* free iterator memory */
tf_dofinish(); /* abort simulation */
return(0);
}
return(0);
}
/**********************************************************************
* calltf routine
*********************************************************************/
int PLIbook_ReadDelays_calltf(char *user_data)
{
vpiHandle systf_h, arg_itr, mod_h, path_itr, path_h;
/* obtain a handle to the system task instance */
systf_h = vpi_handle(vpiSysTfCall, NULL);
/* obtain handle to system task argument; */
/* compiletf has already verified only 1 arg with correct type */
arg_itr = vpi_iterate(vpiArgument, systf_h);
mod_h = vpi_scan(arg_itr);
vpi_free_object(arg_itr); /* free iterator--did not scan to null */
vpi_printf("\nModule %s paths:\n", vpi_get_str(vpiDefName, mod_h));
path_itr = vpi_iterate(vpiModPath, mod_h);
if (path_itr != NULL)
while ((path_h = vpi_scan(path_itr)) != NULL) {
PLIbook_PrintDelays(path_h);
}
else
vpi_printf(" No path delays found.\n");
return(0);
}
void PLIbook_PrintDelays(vpiHandle modpath_h)
{
char *path_name; /* pointer to path name string */
s_vpi_delay delay_struct; /* structure to setup delays */
s_vpi_time delay_array[6]; /* structure to receive delays */
delay_struct.da = delay_array;
delay_struct.no_of_delays = 2;
delay_struct.time_type = vpiScaledRealTime;
delay_struct.mtm_flag = 1;
delay_struct.append_flag = 0;
delay_struct.pulsere_flag = 0;
vpi_get_delays(modpath_h, &delay_struct);
path_name = PLIbook_BuildPathName(modpath_h);
vpi_printf("Delays for %s = (%.2f:%.2f:%.2f, %.2f:%.2f:%.2f)\n",
path_name,
delay_array[0].real, delay_array[1].real, delay_array[2].real,
delay_array[3].real, delay_array[4].real, delay_array[5].real);
}
char *PLIbook_BuildPathName(vpiHandle modpath_h)
{
vpiHandle term_itr, term_h, net_h;
static char path_name[2050]; /* character array to hold path name */
char *term_name;
path_name[0] = '\0'; /* clear the path name string */
term_itr = vpi_iterate(vpiModPathIn, modpath_h);
if (term_itr == NULL)
return("UNKNOWN PATH NAME");
term_h = vpi_scan(term_itr);
net_h = vpi_handle(vpiExpr, term_h);
if (net_h == NULL)
return("UNKNOWN PATH NAME");
term_name = vpi_get_str(vpiName, net_h);
strcat(path_name, term_name);
vpi_free_object(term_itr); /* free iterator--did not scan to null */
strcat(path_name, "$");
term_itr = vpi_iterate(vpiModPathOut, modpath_h);
if (term_itr == NULL)
return("UNKNOWN PATH NAME");
term_h = vpi_scan(term_itr);
net_h = vpi_handle(vpiExpr, term_h);
if (net_h == NULL)
return("UNKNOWN PATH NAME");
term_name = vpi_get_str(vpiName, net_h);
strcat(path_name, term_name);
vpi_free_object(term_itr); /* free iterator--did not scan to null */
return(path_name);
}
/*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -