⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read_test_vector_vpi.c

📁 pli_handbook_examples_pc verilog hdl 与C的接口的典型例子
💻 C
字号:
/**********************************************************************
 * $read_test_vector example -- PLI application using VPI routines
 *
 * C source to read a test vector value from a file and apply the
 * vector to a Verilog simulation.  The $read_test_vector application
 * is intended to be used in a loop, where each time it is called, it 
 * reads the next vector from a file.  When the last vector has been 
 * read, the PLI routine will stop simulation.
 *
 * Usage:   $read_test_vector("<file_name>",<register_variable>);
 *
 * Example:
 *    reg [11:0] vector;
 *    always @(negedge clk) $read_test_vector("vector.pat",vector);
 *
 * 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 <malloc.h>    /* ANSI C standard memory allocation 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) */

/* include utility routines to work with tfargs */
#include "vpi_utilities.c"

/* prototypes of routines in this PLI application */
int PLIbook_ReadVector_calltf(), PLIbook_ReadVector_compiletf(),
    PLIbook_StartOfSim();

/**********************************************************************
 * Define storage structure for file pointer and vector handle.
 *********************************************************************/
typedef struct PLIbook_Data {
  FILE *file_ptr;    /* test vector file pointer */
  vpiHandle  obj_h;  /* pointer to store handle for a Verilog object */
} PLIbook_Data_s, *PLIbook_Data_p;

/**********************************************************************
 * VPI Registration Data
 *********************************************************************/
void PLIbook_ReadVector_register()
{
  s_vpi_systf_data tf_data;

  tf_data.type      = vpiSysTask;
  tf_data.tfname    = "$read_test_vector";
  tf_data.calltf    = PLIbook_ReadVector_calltf;
  tf_data.compiletf = PLIbook_ReadVector_compiletf; 
  tf_data.sizetf    = NULL;
  tf_data.user_data = NULL;
  vpi_register_systf(&tf_data);
}

/**********************************************************************
 * compiletf routine
 *********************************************************************/
int PLIbook_ReadVector_compiletf(char *user_data)
{
  s_cb_data   cb_data_s;
  vpiHandle   systf_h, arg_itr, arg_h;
  int         tfarg_type, err = 0;
  char       *file_name;
  
  systf_h = vpi_handle(vpiSysTfCall, NULL);
  arg_itr = vpi_iterate(vpiArgument, systf_h);
  if (arg_itr == NULL) {
    vpi_printf("ERROR: $read_test_vector requires 2 arguments\n");
    tf_dofinish();
    return(0);
  }
  arg_h = vpi_scan(arg_itr);  /* get handle for first tfarg */
  if (vpi_get(vpiType, arg_h) != vpiConstant) {
    vpi_printf("$read_test_vector arg 1 must be a quoted file name\n");
    err = 1;
  }
  else if (vpi_get(vpiConstType, arg_h) != vpiStringConst) {
    vpi_printf("$read_test_vector arg 1 must be a string\n");
    err = 1;
  }
  arg_h = vpi_scan(arg_itr);  /* get handle for second tfarg */
  tfarg_type = vpi_get(vpiType, arg_h);
  if ( (tfarg_type != vpiReg) &&
       (tfarg_type != vpiIntegerVar) &&
       (tfarg_type != vpiTimeVar) ) {
    vpi_printf("$read_test_vector arg 2 must be a register type\n");
    err = 1;
  }
  if (vpi_scan(arg_itr) != NULL) {
    vpi_printf("read_test_vector requires only 2 arguments\n");
    vpi_free_object(arg_itr);
    err = 1;
  }
  if (err)
    tf_dofinish();

  /* setup a callback for start of simulation */
  cb_data_s.reason    = cbStartOfSimulation;
  cb_data_s.cb_rtn    = PLIbook_StartOfSim;
  cb_data_s.obj       = NULL;
  cb_data_s.time      = NULL;
  cb_data_s.value     = NULL;
  cb_data_s.user_data = (char *)systf_h; /* pass systf_h to callback */
  vpi_register_cb(&cb_data_s);

  return(0);
}

/**********************************************************************
 * calltf routine
 *********************************************************************/
int PLIbook_ReadVector_calltf(char *user_data)
{
  s_cb_data      data_s;
  s_vpi_time     time_s;
  s_vpi_value    value_s;
  FILE          *vector_file;
  vpiHandle      systf_h, arg2_h;
  PLIbook_Data_p vector_data;  /* pointer to a ReadVecData structure */

  char           vector[1024]; /* fixed vector size, could use malloc*/

  systf_h = vpi_handle(vpiSysTfCall, NULL);

  /* get ReadVecData pointer from a work area for this task instance */
  /* the data in the work area was loaded at the start of simulation */
  vector_data = (PLIbook_Data_p)PLIbook_get_vpiworkarea(systf_h);
  vector_file = vector_data->file_ptr;  
  arg2_h      = vector_data->obj_h;
  
  /* read next line from the file */
  if ( (fscanf(vector_file,"%s\n", vector)) == EOF) {
    vpi_printf("$read_test_vector reached End-Of-File\n");
    fclose(vector_data->file_ptr);
    tf_dofinish();
    return(0);
  }

  /* write the vector to the second system task argument */
  value_s.format = vpiBinStrVal;
  value_s.value.str = vector;
  vpi_put_value(arg2_h, &value_s, NULL, vpiNoDelay);

  return(0);
}

/**********************************************************************
 * StartOfSim callback -- opens the test vector file and saves the
 * pointer and the system task handle in the work area storage.
 *********************************************************************/
int PLIbook_StartOfSim(p_cb_data cb_data)
{
  s_vpi_value  argVal;
  char        *file_name;
  FILE        *vector_file;
  vpiHandle    systf_h, arg_itr, arg1_h, arg2_h;

  PLIbook_Data_p vector_data;  /* pointer to a ReadVecData structure */
  
  vector_data = (PLIbook_Data_p)malloc(sizeof(PLIbook_Data_s));
  
  /* retrieve system task handle from user_data */
  systf_h = (vpiHandle)cb_data->user_data;

  /* get argument handles (compiletf already verified only 2 args) */
  arg_itr = vpi_iterate(vpiArgument, systf_h);
  arg1_h  = vpi_scan(arg_itr);
  arg2_h  = vpi_scan(arg_itr);
  vpi_free_object(arg_itr); /* free iterator -- did not scan to null */

  /* read file name from first tfarg */
  argVal.format = vpiStringVal;
  vpi_get_value(arg1_h, &argVal);
  if (vpi_chk_error(NULL)) {
    vpi_printf("ERROR: $read_test_vector could not get file name\n");
    return(0);
  }
  file_name = argVal.value.str;
  
  if ( !(vector_file = fopen(file_name,"r")) ) { 
    vpi_printf("$read_test_vector could not open file %s", file_name);
    tf_dofinish;
    return(0);
  }

  /* store file pointer and tfarg2_h in work area for this instance */
  vector_data->file_ptr = vector_file;
  vector_data->obj_h = arg2_h;
  PLIbook_set_vpiworkarea(systf_h, (char *)vector_data);

  return(0);
}

/*********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -