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

📄 sci_alu_latched_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.
 *   latched logic version (output values are 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 -/
 *   },
 *********************************************************************/

/**********************************************************************
 * Definition for a structure to store output values when the ALU is
 * latched.  When enable is 1, the ALU returns the currently calculated
 * outputs, and when 0, the ALU returns the latched previous results.
 *********************************************************************/
 #include <stdio.h>
 typedef struct PLIbook_SciALUoutputs  *PLIbook_SciALUoutputs_p; 
 typedef struct PLIbook_SciALUoutputs {
   char *instance_p; /* shows which task instance owns this space */
   double result;    /* stored result of previous operation */
   int    excep;
   int    err;
   PLIbook_SciALUoutputs_p next_ALU_outputs; /* next stack location */
 } PLIbook_SciALUoutputs_s;

  /* declare global stack pointer */
  static PLIbook_SciALUoutputs_p ALU_outputs_stack = NULL;


/**********************************************************************
 * C model of a Scientific Arithmetic Logic Unit.
 *   Latched outputs version.
 *********************************************************************/
#include <math.h>
#include <ERRNO.h>
void PLIbook_ScientificALU_C_model(
       int     enable,     /* input; 0 = latched */
       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 */
       char   *instance_p) /* input; pointer to system task instance */
{
  PLIbook_SciALUoutputs_p ALU_outputs;

  /* Locate the output storage in the stack for this model instance  */
  /* If no storage is found, then allocate a storage block and add   */
  /* the storage to the stack.                                       */
  ALU_outputs = ALU_outputs_stack; /* top-of-stack is in global var. */
  while (ALU_outputs && (ALU_outputs->instance_p != instance_p))
    ALU_outputs = ALU_outputs->next_ALU_outputs;

  /* If no storage area found for this model instance, create one */
  if (ALU_outputs == NULL) { 
    ALU_outputs = 
      (PLIbook_SciALUoutputs_p)malloc(sizeof(PLIbook_SciALUoutputs_s));
    ALU_outputs->instance_p = instance_p; /* set owner of this space */
    ALU_outputs->next_ALU_outputs = NULL;
    ALU_outputs_stack = ALU_outputs; /* save new top-of-stack */
  }

  if (enable) { /* ALU is not latched, calculate outputs and store */
    switch (opcode) {
      case 0x0: ALU_outputs->result = pow    (a, b);      break;
      case 0x1: ALU_outputs->result = sqrt   (a);         break;
      case 0x2: ALU_outputs->result = exp    (a);         break;
      case 0x3: ALU_outputs->result = ldexp  (a, (int)b); break;
      case 0x4: ALU_outputs->result = fabs   (a);         break;
      case 0x5: ALU_outputs->result = fmod   (a, b);      break;
      case 0x6: ALU_outputs->result = ceil   (a);         break;
      case 0x7: ALU_outputs->result = floor  (a);         break;
      case 0x8: ALU_outputs->result = log    (a);         break;
      case 0x9: ALU_outputs->result = log10  (a);         break;
      case 0xA: ALU_outputs->result = sin    (a);         break;
      case 0xB: ALU_outputs->result = cos    (a);         break;
      case 0xC: ALU_outputs->result = tan    (a);         break;
      case 0xD: ALU_outputs->result = asin   (a);         break;
      case 0xE: ALU_outputs->result = acos   (a);         break;
      case 0xF: ALU_outputs->result = atan   (a);         break;
    }
    ALU_outputs->err   = (errno == EDOM);   /* arg out of range */
    ALU_outputs->excep = (errno == ERANGE); /* result out of range */
    errno = 0;                              /* clear the error flag */
    if (ALU_outputs->err) ALU_outputs->result = 0.0;
  }
  
  /* return the values stored in the C model */
  *result = ALU_outputs->result;  
  *err    = ALU_outputs->err;  
  *excep  = ALU_outputs->excep;  

  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
 * puts the C model outputs into simulation.  Passes the instance
 * pointer of the Verilog system task which represents the C model
 * to serve as a unique flag within the C model.
 *********************************************************************/
int PLIbook_ScientificALU_misctf(int user_data, int reason, int paramvc)
{
  #define ALU_ENABLE 1  /* system task arg 1 is ALU enable input     */
  #define ALU_A      2  /* system task arg 2 is ALU A input          */
  #define ALU_B      3  /* system task arg 3 is ALU B input          */
  #define ALU_OP     4  /* system task arg 4 is ALU opcode input     */
  #define ALU_RESULT 5  /* system task arg 5 is ALU result output    */
  #define ALU_EXCEPT 6  /* system task arg 6 is ALU exception output */
  #define ALU_ERROR  7  /* system task arg 7 is ALU error output     */

  double  a, b, result;
  int     opcode, excep, err, enable;
  char   *instance_p;
  
  /* 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);

  a      = tf_getrealp(ALU_A);
  b      = tf_getrealp(ALU_B);
  opcode = tf_getp(ALU_OP);

  /* Obtain the instance pointer for this system task instance */
  instance_p = tf_getinstance();

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

  /* 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() != 7)
    tf_error("$scientific_alu requires 7 arguments");
    
  else {
    if (tf_typep(ALU_ENABLE) != TF_READONLY)
      tf_error("$scientific_alu arg 1 must be a net\n");
    else if (tf_sizep(ALU_ENABLE) != 1)
      tf_error("$scientific_alu arg 1 must be scalar\n");

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

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

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

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

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

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

⌨️ 快捷键说明

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