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

📄 dump_memory_tf.c

📁 pli_handbook_examples_pc verilog hdl 与C的接口的典型例子
💻 C
字号:
/**********************************************************************
* $dump_mem example -- C source code using TF/ACC PLI routines
*
* C source to illustrate reading 4-state logic values from all
* addresses of a Verilog memory array.
*
* The logic values are represented as characters in the C language. 
* Every eight bits of a Verilog memory word are passed to/from 
* Verilog as a C structure containing a pair of C bytes (of type char),
* using an aval/bval encoding, where:
* 0/0 = logic 0, 1/0 = logic 1, 0/1 = logic Z, 1/1 = logic X.
*
* 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:
* ------
*   Syntax:  $dump_mem_hex(<memory_word_select>);
*            $dump_mem_ascii(<memory_word_select>);
*
*     Note:  The word select of the memory is ignored, but is
*            required by the tf_nodeinfo() syntax.
*
*   Example:
*    reg [23:0] RAM [0:3];
*    initial $ump_mem_hex(RAM[0]);
*
* Routine definitions for a veriusertfs array:
*  /* routine prototypes -/
*   extern int PLIbook_DumpMem_checktf(),
*              PLIbook_DumpMem_calltf();
*  /* table entries -/
*   {usertask,                         /* type of PLI routine -/
*     0,                               /* user_data value -/
*     PLIbook_DumpMem_checktf,         /* checktf routine -/
*     0,                               /* sizetf routine -/
*     PLIbook_DumpMem_calltf,          /* calltf routine -/
*     PLIbook_DumpMem_misctf,          /* misctf routine -/
*     "$dump_mem_hex",                 /* system task/function name -/
*     1                                /* forward reference = true -/
*   },
*   {usertask,                         /* type of PLI routine -/
*     1,                               /* user_data value -/
*     PLIbook_DumpMem_checktf,         /* checktf routine -/
*     0,                               /* sizetf routine -/
*     PLIbook_DumpMem_calltf,          /* calltf routine -/
*     PLIbook_DumpMem_misctf,          /* misctf routine -/
*     "$dump_mem_bin",                 /* system task/function name -/
*     1                                /* forward reference = true -/
*   },
*   {usertask,                         /* type of PLI routine -/
*     2,                               /* user_data value -/
*     PLIbook_DumpMem_checktf,         /* checktf routine -/
*     0,                               /* sizetf routine -/
*     PLIbook_DumpMem_calltf,          /* calltf routine -/
*     PLIbook_DumpMem_misctf,          /* misctf routine -/
*     "$dump_mem_ascii",               /* system task/function name -/
*     1                                /* forward reference = true -/
*   },
**********************************************************************/

#include "veriuser.h"         /* IEEE 1364 PLI TF  routine library */

#define HEX   0  /* values of user_data for system task names */
#define BIN   1
#define ASCII 2

/**********************************************************************
* checktf routine
**********************************************************************/
int PLIbook_DumpMem_checktf(int user_data)
{
  if (tf_nump() != 1)
    if (user_data == HEX)
      tf_error("Usage error: $dump_mem_hex(<memory_word_select>);");
    else if (user_data == BIN)
      tf_error("Usage error: $dump_mem_bin(<memory_word_select>);");
    else 
      tf_error("Usage error: $dump_mem_ascii(<memory_word_select>);");
  return(0);
}

/**********************************************************************
* misctf routine
*
* The misctf routine is used to call tf_nodeinfo() at the 
* beginning of simulation, so that the memory allocated by 
* tf_nodeinfo() is only allocated one time for each instance of
* $dump_mem_??.
**********************************************************************/
int PLIbook_DumpMem_misctf(int user_data, int reason)
{
  p_tfnodeinfo node_info;  /* pointer to structure for tf_nodeinfo() */

  if (reason != REASON_ENDOFCOMPILE)
    return(0);  /* exit now if this is not the start of simulation */
  
  /* allocate memory for an s_tfexprinfo structure */
  node_info = (p_tfnodeinfo)malloc(sizeof(s_tfnodeinfo));

  /* Get the nodeinfo structure for tfarg 1 */
  if (!tf_nodeinfo(1, node_info)) {
    tf_error("Err: $dump_mem_?? could not get tf_nodeinfo for tfarg 1");
    tf_dofinish(); /* about simulation */
    return(0);
  }
  else if (node_info->node_type != TF_MEMORY_NODE) {
    tf_error("Err: $dump_mem_?? arg is not a memory word -- aborting");
    tf_dofinish(); /* about simulation */
    return(0);
  }
  else
    tf_setworkarea((char *)node_info); /*put info pointer in workarea*/

  return(0);
}

/**********************************************************************
* calltf routine
**********************************************************************/
/* prototypes of functions invoked by the calltf routine */
void PLIbook_DumpMemHex();
void PLIbook_DumpMemBin();
void PLIbook_DumpMemAscii();


int PLIbook_DumpMem_calltf(int user_data)
{
  p_tfnodeinfo node_info;

  node_info = (p_tfnodeinfo)tf_getworkarea();

  io_printf("\nWithin PLI:\n");
  io_printf(" Memory array width=%d  depth=%d  ngroups=%d\n",
               node_info->node_vec_size,
               node_info->node_mem_size,
               node_info->node_ngroups);


io_printf("\n\nnode_ms_index = %d    node_ls_index = %d\n\n",
          node_info->node_ms_index, node_info->node_ls_index);

  if (user_data == HEX)      /* application called by $dump_mem_hex */
    PLIbook_DumpMemHex(node_info);
  else if (user_data == BIN) /* application called by $dump_mem_bin */
    PLIbook_DumpMemBin(node_info);
  else                       /* application called by $dump_mem_ascii */
    PLIbook_DumpMemAscii(node_info);

  return(0);
}

/**********************************************************************
* Function to dump each word of a Verilog array in hexadecimal
**********************************************************************/
void PLIbook_DumpMemHex(p_tfnodeinfo node_info)
{
  char *aval_ptr, *bval_ptr;
  int   word_increment, mem_address, group_num;

  io_printf(" Current memory contents of aval/bval groups in hex:\n");

  word_increment = node_info->node_ngroups * 2;
  for (mem_address = 0;
       mem_address < node_info->node_mem_size;
       mem_address++) {

    io_printf("   address %d:\t ", mem_address);

    /* set pointers to aval and bval words for the address */
    aval_ptr = node_info->node_value.memoryval_p
               + (mem_address * word_increment);
    bval_ptr = aval_ptr + node_info->node_ngroups;

    /* print groups in word in reverse order so will match Verilog:
       the highest group number represents the left-most byte of a
       Verilog word, the lowest group represents the right-most byte */
    for (group_num = node_info->node_ngroups - 1;
         group_num >= 0; 
         group_num--) {
      io_printf("  group %d: %x/%x",
                group_num, aval_ptr[group_num], bval_ptr[group_num]);
    }
    io_printf("\n");
  }
  io_printf("\n\n");
  return;
}

/**********************************************************************
* Function to dump each word of a Verilog array in ASCII
**********************************************************************/
void PLIbook_DumpMemAscii(p_tfnodeinfo node_info)
{
  char *aval_ptr;
  int   word_increment, mem_address, group_num;

  /* Read current memory values as a string using only aval bits */
  io_printf(" Current memory contents in ASCII are:\n");
  io_printf("  ");

  word_increment = node_info->node_ngroups * 2;
  for (mem_address = 0;
       mem_address < node_info->node_mem_size;
       mem_address++) {
    /* set pointer to aval word for the address */
    aval_ptr = node_info->node_value.memoryval_p
               + (mem_address * word_increment);

    /* print groups in word in reverse order so will match Verilog:
       the highest group number represents the left-most byte of a
       Verilog word, the lowest group represents the right-most byte */
    for (group_num = node_info->node_ngroups - 1;
         group_num >= 0; 
         group_num--) {
      io_printf("%c", aval_ptr[group_num]);
    }
  }
  io_printf("\n\n");
  return;
}


/* #define OBVIOUS   /* compile more obvious, less efficient version */
#define EFFICIENT /* compile Drew's more efficient version */

#if defined EFFICIENT
/**********************************************************************
* Function to dump each word of a Verilog array in binary.
* This example of the function uses a more efficient C coding style to
* select one bit from a word.
**********************************************************************/
void PLIbook_DumpMemBin(p_tfnodeinfo node_info)
{
  char *aval_ptr, *bval_ptr;
  int   word_increment, mem_address, word_bit;
  char  aval_val, bval_val;

  io_printf(" Current memory contents in binary are:\n");

  word_increment = node_info->node_ngroups * 2; /* 1 word = aval/bval pair */
  for (mem_address = 0;
       mem_address < node_info->node_mem_size;
       mem_address++) {
    /* set pointers to aval and bval words for the address */
    aval_ptr = node_info->node_value.memoryval_p
               + (mem_address * word_increment);
    bval_ptr = aval_ptr + node_info->node_ngroups;
    io_printf("   address %d:\t ", mem_address);

    /* print groups in word in reverse order so will match Verilog:
       the highest group number represents the left-most byte of a
       Verilog word, the lowest group represents the right-most byte */
    for (word_bit = node_info->node_vec_size - 1;
         word_bit >= 0; 
         word_bit--) {
    	aval_val = (aval_ptr[word_bit >> 3]) & (1 << (word_bit & 0x7));
    	bval_val = (bval_ptr[word_bit >> 3]) & (1 << (word_bit & 0x7));

      /* translate aval/bval pair to 4-state logic value */
    	if (!bval_val) {
        if (!aval_val)  io_printf("0");  /* aval/bval == 0/0 */
        else            io_printf("1");  /* aval/bval == 1/0 */
      }
      else {
        if (!aval_val)  io_printf("z");  /* aval/bval == 0/1 */
        else            io_printf("x");  /* aval/bval == 1/1 */
      }
    }
    io_printf("\n");
  }
  return;
}

#elif defined OBVIOUS
/**********************************************************************
* Function to dump each word of a Verilog array in binary.
* This example of the function uses a more obvious but less efficient
* C coding style to select one bit from a word.
**********************************************************************/
void PLIbook_DumpMemBin(p_tfnodeinfo node_info)
{
  char *aval_ptr, *bval_ptr;
  int   word_increment, mem_address, word_bit, group_num, group_bit;
  char  aval_val, bval_val, bit_mask;

  io_printf(" Current memory contents in binary are:\n");

  word_increment = node_info->node_ngroups * 2;

  for (mem_address = 0;
       mem_address < node_info->node_mem_size;
       mem_address++) {

    io_printf("   address %d:\t ", mem_address);

    /* step 1: set pointers to aval and bval words for the address */
    aval_ptr = node_info->node_value.memoryval_p
               + (mem_address * word_increment);
    bval_ptr = aval_ptr + node_info->node_ngroups;
    for (word_bit = node_info->node_vec_size - 1;
         word_bit >= 0; 
         word_bit--) {

      /* step 2: determine the group which contains the bit number */
      group_num = word_bit / 8;
    
      /* step 3: determine which bit in the group contains the bit */
      group_bit = word_bit % 8;
    
      /* step 4: set an 8-bit mask to block all unwanted bits in group */
      bit_mask = 0x01;  /* Set mask to most-signif. bit of 8-bit group */
      bit_mask = bit_mask << group_bit; /* Shift to bit to be modified */
    
      /* step 5: select desired aval and bval bits from the groups */
      aval_val = aval_ptr[group_num] & bit_mask;
      bval_val = bval_ptr[group_num] & bit_mask;
    
      /* translate aval/bval pair to 4-state logic value */
    	if (!bval_val) {
        if (!aval_val)  io_printf("0");  /* aval/bval == 0/0 */
        else            io_printf("1");  /* aval/bval == 1/0 */
      }
      else {
        if (!aval_val)  io_printf("z");  /* aval/bval == 0/1 */
        else            io_printf("x");  /* aval/bval == 1/1 */
      }
    }
    io_printf("\n");
  }
  io_printf("\n");
  return;
}

#endif

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

⌨️ 快捷键说明

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