📄 read_stimulus_tf.c
字号:
/**********************************************************************
* $read_stimulus_ba example -- C source code using TF PLI routines
*
* For the book, "The Verilog PLI Handbook", Chapter 11
* Copyright 1998, Sutherland HDL Inc, Portland, Oregon.
*
* C source to read test vectors from a file and apply them to
* simulation. Once called, this application will call itself back
* until it reaches End-of-File.
*
* Each line in the test vector file contains a delay time and a vector
* value, separated by white space. Delay values define when the
* vector is to be applied to simulation. Delays may be relative to
* the previous time, or absolute to time 0. The test vector value
* may be in binary or hex. An example file is:
*
* 100 00000000
* 70 10111001
* ...
*
* 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
*
* Usage:
*
* initial
* $read_stimulus<base><delay_type>("file_name", verilog_reg);
*
* where:
* <base> is b or h (for binary or hex vectors).
* <delay_type> is r or a for relative or absolute times.
* "file_name" is the name of the file to be read, in quotes.
* verilog_reg is a verilog register data type of the same bit
* width as the patterns to be read.
*
* Output:
*
* Verbose debugging output is enabled with a +read_stimulus_debug
* invocation option to the simulation
*
* NOTES:
* 1. There is no error checking on the data read from the file.
* 2. Delay times are limited to 32-bit integers.
*
* Routine definitions for a veriusertfs array:
* /* routine prototypes -/
* extern int PLIbook_ReadStimulus_checktf(),
* PLIbook_ReadStimulus_calltf(),
* PLIbook_ReadStimulus_misctf();
* /* table entries -/
* {usertask, /* type of PLI routine -/
* 0, /* user_data value -/
* PLIbook_ReadStimulus_checktf, /* checktf routine -/
* 0, /* sizetf routine -/
* PLIbook_ReadStimulus_calltf, /* calltf routine -/
* PLIbook_ReadStimulus_misctf, /* misctf routine -/
* "$read_stimulus", /* system task/function name -/
* 1 /* forward reference = true -/
* },
* {usertask, /* type of PLI routine -/
* 0, /* user_data value -/
* PLIbook_ReadStimulus_checktf, /* checktf routine -/
* 0, /* sizetf routine -/
* PLIbook_ReadStimulus_calltf, /* calltf routine -/
* PLIbook_ReadStimulus_misctf, /* misctf routine -/
* "$read_stimulus_ba", /* system task/function name -/
* 1 /* forward reference = true -/
* },
* {usertask, /* type of PLI routine -/
* 1, /* user_data value -/
* PLIbook_ReadStimulus_checktf, /* checktf routine -/
* 0, /* sizetf routine -/
* PLIbook_ReadStimulus_calltf, /* calltf routine -/
* PLIbook_ReadStimulus_misctf, /* misctf routine -/
* "$read_stimulus_br", /* system task/function name -/
* 1 /* forward reference = true -/
* },
* {usertask, /* type of PLI routine -/
* 2, /* user_data value -/
* PLIbook_ReadStimulus_checktf, /* checktf routine -/
* 0, /* sizetf routine -/
* PLIbook_ReadStimulus_calltf, /* calltf routine -/
* PLIbook_ReadStimulus_misctf, /* misctf routine -/
* "$read_stimulus_ha", /* system task/function name -/
* 1 /* forward reference = true -/
* },
* {usertask, /* type of PLI routine -/
* 3, /* user_data value -/
* PLIbook_ReadStimulus_checktf, /* checktf routine -/
* 3, /* sizetf routine -/
* PLIbook_ReadStimulus_calltf, /* calltf routine -/
* PLIbook_ReadStimulus_misctf, /* misctf routine -/
* "$read_stimulus_hr", /* system task/function name -/
* 1 /* forward reference = true -/
* },
*********************************************************************/
#include <stdio.h> /* ANSI C standard I/O library */
#include "veriuser.h" /* IEEE 1364 PLI TF routine library */
/* prototypes of sub-functions */
char *PLIbook_reason_name();
/*********************************************************************/
/* structure definition for data used by the misctf routine */
/*********************************************************************/
typedef struct PLIbook_stim_data {
FILE *file_ptr; /* pointer to the test vector file */
long file_position; /* position within file of next byte to read */
char *vector; /* pointer to stimulus vector */
char dummy_msg[20]; /* dummy message field to show save/restart */
} PLIbook_stim_data_s, *PLIbook_stim_data_p;
/*********************************************************************/
/* checktf routine */
/*********************************************************************/
int PLIbook_ReadStimulus_checktf()
{
bool err = FALSE;
if (tf_nump() != 2) {
tf_text("$read_stimulus_?? requires 2 arguments\n");
err = TRUE;
}
if (tf_typep(1) != tf_string) {
tf_text("$read_stimulus_?? arg 1 must be a string\n");
err = TRUE;
}
if (tf_typep(2) != tf_readwrite) {
tf_text("$read_stimulus_?? arg 2 must be a register data type");
err = TRUE;
}
if (err)
tf_message(ERR_ERROR, "", "", ""); /* print stored messages */
return(0);
}
/*********************************************************************/
/* calltf routine */
/*********************************************************************/
int PLIbook_ReadStimulus_calltf()
{ /* call the misctf routine at the end of current */
tf_setdelay(0); /* time step, with REASON_REACTIVATE; the misctf */
/* routine reads the stimulus file. */
return(0);
}
/*********************************************************************/
/* misctf routine */
/*********************************************************************/
int PLIbook_ReadStimulus_misctf(int user_data, int reason)
{
int delay, foo;
char base;
PLIbook_stim_data_p data_p;
bool debug = FALSE;
if(mc_scan_plusargs("read_stimulus_debug")) debug = TRUE;
if (debug)
io_printf("** read_stimulus misctf called for %s at time %s **\n",
PLIbook_reason_name(reason), tf_strgettime());
switch(reason) {
case REASON_ENDOFCOMPILE: /* misctf called at start of simulation */
/* Check work area to see if application data is already
/* allocated and the vector file opened. This check is necessary
/* because REASON_RESTART can occur before REASON_ENDOFCOMPILE */
data_p = (PLIbook_stim_data_p)tf_getworkarea();
if (data_p)
return(0); /* abort if work area already contains data */
/* allocate a memory block for data storage */
data_p=(PLIbook_stim_data_p)malloc(sizeof(PLIbook_stim_data_s));
/* store a pointer to the application data in the work area */
tf_setworkarea((char *)data_p);
/* fill in the application data fields */
data_p->file_ptr = fopen(tf_getcstringp(1), "r");
if ( !data_p->file_ptr ) {
tf_error("$read_stimulus_?? could not open file %s",
tf_getcstringp(1));
tf_dofinish(); /* exit simulation if cannot open file */
break;
}
data_p->file_position = ftell(data_p->file_ptr);
data_p->vector = (char *) malloc((tf_sizep(2) * 8) + 1);
strcpy(data_p->dummy_msg, "Hello world");
break;
case REASON_REACTIVATE: /* misctf called by tf_setdelay */
/* get the pointer to the data structure from the work area */
data_p = (PLIbook_stim_data_p)tf_getworkarea();
/* read next line from the file */
if ( (fscanf(data_p->file_ptr,"%d %s\n",
&delay, data_p->vector)) == EOF) {
tf_rosynchronize(); /* if end of file, schedule a callback */
break; /* at the end of the current time step */
}
if (debug)
io_printf("** values read from file: delay = %d vector = %s\n",
delay, data_p->vector);
/* set flag for test vector radix */
switch(user_data) {
case 0:
case 1: base = 'b'; break; /* vectors are in binary format */
case 2:
case 3: base = 'h'; break; /* vectors are in hex format */
}
/* convert absolute delays to relative to current time */
switch(user_data) {
case 0:
case 2: /* using absolute delays; convert to relative */
delay = delay - tf_gettime();
}
/* schedule the vector to be applied after the delay period */
tf_strdelputp(2, tf_sizep(2), base, data_p->vector, delay, 0);
/* schedule reactive callback to this routine after delay time */
tf_setdelay(delay);
break;
case REASON_ROSYNCH: /* misctf called at end of time step */
io_printf("\n$read_stimulus_?? has encountered end-of-file.\n");
tf_dofinish;
break;
case REASON_FINISH: /* misctf called at end of simulation */
io_printf("\nPLI is processing finish at simulation time %s\n\n",
tf_strgettime());
/* get the pointer to the application data from the work area */
data_p = (PLIbook_stim_data_p)tf_getworkarea();
/* close file */
if (data_p->file_ptr) fclose(data_p->file_ptr);
/* de-allocate storage */
free(data_p);
break;
case REASON_SAVE: /* misctf called for $save */
/* get the pointer to the application data from the work area */
data_p = (PLIbook_stim_data_p)tf_getworkarea();
/* save current file position in the application data */
data_p->file_position = ftell(data_p->file_ptr);
/* add application data to simulation save file */
tf_write_save((char *)data_p, sizeof(PLIbook_stim_data_s));
if (debug)
io_printf("\nPLI data saved (last file position was %ld)\n\n",
data_p->file_position);
break;
case REASON_RESTART: /* misctf called end of simulation */
/* re-allocate memory for PLI application data */
data_p=(PLIbook_stim_data_p)malloc(sizeof(PLIbook_stim_data_s));
/* save new application data pointer in work area */
tf_setworkarea((char *)data_p);
/* retrieve old application data from save file */
if (!tf_read_restart((char *)data_p,
sizeof(PLIbook_stim_data_s)) ) {
tf_error("\nError retrieving PLI data from save file!\n");
return(0);
}
if (debug) {
io_printf("\nPLI data retrieved from save file.\n");
/* test to see if old application data was restored */
io_printf(" dummy message = %s, file position = %ld\n\n",
data_p->dummy_msg, data_p->file_position);
}
/* re-open test vector file */
data_p->file_ptr = fopen(tf_getcstringp(1), "r");
if ( !data_p->file_ptr ) {
tf_error("$read_stimulus_?? could not re-open file %s",
tf_getcstringp(1));
tf_dofinish(); /* exit simulation if cannot open file */
}
/* re-position file to next test vector to be read */
if ( fseek(data_p->file_ptr, data_p->file_position, SEEK_SET)) {
tf_error("$read_stimulus_?? could not reposition file");
tf_dofinish(); /* exit simulation if reposition open file */
}
break;
}
return(0);
}
/*********************************************************************/
/* Function to convert reason integer to reason name */
/*********************************************************************/
char *PLIbook_reason_name(int reason)
{
char str[25];
switch (reason) {
case REASON_ENDOFCOMPILE : return("REASON_ENDOFCOMPILE"); break;
case REASON_FINISH : return("REASON_FINISH"); break;
case REASON_INTERACTIVE : return("REASON_INTERACTIVE"); break;
case REASON_SYNCH : return("REASON_SYNCH"); break;
case REASON_ROSYNCH : return("REASON_ROSYNCH"); break;
case REASON_REACTIVATE : return("REASON_REACTIVATE"); break;
case REASON_PARAMVC : return("REASON_PARAMVC"); break;
case REASON_PARAMDRC : return("REASON_PARAMDRC"); break;
case REASON_SAVE : return("REASON_SAVE"); break;
case REASON_RESTART : return("REASON_RESTART"); break;
case REASON_RESET : return("REASON_RESET"); break;
case REASON_ENDOFRESET : return("REASON_ENDOFRESET"); break;
case REASON_FORCE : return("REASON_FORCE"); break;
case REASON_RELEASE : return("REASON_RELEASE"); break;
}
return("Non-standard or Unknown Reason");
}
/*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -