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

📄 read_stimulus_tf.c

📁 pli_handbook_examples_pc verilog hdl 与C的接口的典型例子
💻 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 + -