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

📄 sci_alu_comb_misctf_tf.c

📁 pli_handbook_examples_pc verilog hdl 与C的接口的典型例子
💻 C
字号:
/**********************************************************************
 * $scientific_alu example -- PLI application using TF routines
 *
 * C model of a Scientific Arithmetic Logic Unit.
 *   Combinational logic version (output values are not stored).
 *
 * 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
 *
 * Routine definitions for a veriusertfs array:
 *  /* routine prototypes -/
 *   extern int PLIbook_ScientificALU_checktf(),
 *              PLIbook_ScientificALU_calltf(),
 *              PLIbook_ScientificALU_misctf();
 *  /* table entries -/
 *   {usertask,                         /* type of PLI routine -/
 *     0,                               /* user_data value -/
 *     PLIbook_ScientificALU_checktf,   /* checktf routine -/
 *     0,                               /* sizetf routine -/
 *     PLIbook_ScientificALU_calltf,    /* calltf routine -/
 *     PLIbook_ScientificALU_misctf,    /* misctf routine -/
 *     "$scientific_alu",               /* system task/function name -/
 *     1                                /* forward reference = true -/
 *   },
 *********************************************************************/

/**********************************************************************
 * C model of a Scientific Arithmetic Logic Unit.
 *   Combinational logic version (outputs change on an input change).
 *********************************************************************/
#include <math.h>
#include <ERRNO.h>
void PLIbook_ScientificALU_C_model(
       double  a,        /* input */
       double  b,        /* input */
       int     opcode,   /* input */
       double *result,   /* output from ALU */
       int    *excep,    /* output; set if result is out of range */
       int    *err)      /* output; set if input is out of range */
{
  switch (opcode) {
    case 0x0: *result = pow    (a, b);      break;
    case 0x1: *result = sqrt   (a);         break;
    case 0x2: *result = exp    (a);         break;
    case 0x3: *result = ldexp  (a, (int)b); break;
    case 0x4: *result = fabs   (a);         break;
    case 0x5: *result = fmod   (a, b);      break;
    case 0x6: *result = ceil   (a);         break;
    case 0x7: *result = floor  (a);         break;
    case 0x8: *result = log    (a);         break;
    case 0x9: *result = log10  (a);         break;
    case 0xA: *result = sin    (a);         break;
    case 0xB: *result = cos    (a);         break;
    case 0xC: *result = tan    (a);         break;
    case 0xD: *result = asin   (a);         break;
    case 0xE: *result = acos   (a);         break;
    case 0xF: *result = atan   (a);         break;
  }
  *err   = (errno == EDOM);   /* arg to math func. out of range */
  *excep = (errno == ERANGE); /* result of math func. out of range */
  errno = 0;                  /* clear the error flag */
  if (*err) *result = 0.0;    /* set result to 0 if error occurred */
  return;
}
/*********************************************************************/


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

/**********************************************************************
 * calltf routine: turns on asynchronous callbacks to the misctf
 * routine whenever an argument to the system task changes value.
 *********************************************************************/
int PLIbook_ScientificALU_calltf()
{
  tf_asynchon();
  return(0);
}

/**********************************************************************
 * misctf routine: Serves as an interface between Verilog simulation
 * and the C model.  Called whenever the C model inputs change value,
 * reads the input values, and passes the values to the C model, and
 * writes the C model outputs into simulation.
 *********************************************************************/
int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc)
{
  #define ALU_A      1  /* system task arg 1 is ALU A input          */
  #define ALU_B      2  /* system task arg 2 is ALU B input          */
  #define ALU_OP     3  /* system task arg 3 is ALU opcode input     */
  #define ALU_RESULT 4  /* system task arg 4 is ALU result output    */
  #define ALU_EXCEPT 5  /* system task arg 5 is ALU exception output */
  #define ALU_ERROR  6  /* system task arg 6 is ALU error output     */

  double  a, b, result;
  int     opcode, excep, err;

  /* abort if misctf was not called for a task argument value change */
  if (reason != REASON_PARAMVC)
    return(0);

  /* abort if task argument that changed was a model output */
  if (paramvc > ALU_OP) /* model outputs are after model inputs */
    return(0);

  /* Read current values of C model inputs from Verilog simulation */
  a      = tf_getrealp(ALU_A);
  b      = tf_getrealp(ALU_B);
  opcode = tf_getp(ALU_OP);


  /******  Call C model  ******/
  PLIbook_ScientificALU_C_model(a, b, opcode, &result, &excep, &err);


  /* Write the C model outputs onto the Verilog signals */
  tf_putrealp(ALU_RESULT, result); 
  tf_putp    (ALU_EXCEPT, excep); 
  tf_putp    (ALU_ERROR, err); 

  return(0);
}

/**********************************************************************
 * checktf routine: Verifies that $scientific_alu() is used correctly.
 *   Note: For simplicity, only limited data types are allowed for
 *   task arguments.  Could add checks to allow other data types.
 *********************************************************************/
int PLIbook_ScientificALU_checktf()
{
  if (tf_nump() != 6)
    tf_error("$scientific_alu requires 6 arguments");
    
  else {
    if (tf_typep(ALU_A) != TF_READWRITEREAL)
      tf_error("$scientific_alu arg 1 must be a real variable\n");

    if (tf_typep(ALU_B) != TF_READWRITEREAL)
      tf_error("$scientific_alu arg 2 must be a real variable\n");

    if (tf_typep(ALU_OP) != TF_READONLY)
      tf_error("$scientific_alu arg 3 must be a net\n");
    else if (tf_sizep(ALU_OP) != 4)
      tf_error("$scientific_alu arg 3 must be a 4-bit vector\n");

    if (tf_typep(ALU_RESULT) != TF_READWRITEREAL)
      tf_error("$scientific_alu arg 4 must be a real variable\n");

    if (tf_typep(ALU_EXCEPT) != TF_READWRITE)
      tf_error("$scientific_alu arg 5 must be a reg\n");
    else if (tf_sizep(ALU_EXCEPT) != 1)
      tf_error("$scientific_alu arg 5 must be scalar\n");

    if (tf_typep(ALU_ERROR) != TF_READWRITE)
      tf_error("$scientific_alu arg 6 must be a reg\n");
    else if (tf_sizep(ALU_ERROR) != 1)
      tf_error("$scientific_alu arg 6 must be scalar\n");
  }
  
  return(0);
}
/*********************************************************************/

⌨️ 快捷键说明

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