IVerilog 源码分析 --PLI框架简介

PLI 基础

Verilog 提供了PLI(Programming Language Interface)机制, 用来进行硬件设计和软件设计者进行交互。 它可以在Verilog的设计之中加入用户自定义的系统函数,这些系统函数是通过C语言软件的方式实现, 这可以理解为, 通过插件的方式, 来扩充硬件设计语言的功能。
PLI常见的功能如下:

  • C语言bus函数建模;
  • 访问C语言代码库函数;
  • 延时计算功能;
  • 自定义输出显示;
  • 联合仿真;
  • 设计的debug功能;
  • 仿真结果分析;

我们比较感兴趣的是访问C语言代码库函数以及design debug功能, 这也是我们后面扩展和使用PLI的功能。 目前的PLI用的比较新的功能是基于VPI的, 我们就忽略ACC/TF部分。
(System)Verilog LRM提供了如下的VPI头文件:
vpi_user.h
sv_vpi_user.h (SystemVerlog部分)

添加系统函数的步骤

The general steps to create a PLI application are:

  • Define a system task or system function name for the application.
  • Write a C language calltf routine which will be executed by the simulator whenever
    simulation encounters the system task name or the system function name.
    Optionally, additional C language routines can be written which will be executed
    by the simulator for special conditions, such as when the simulator compiler or
    elaborator encounters the system task/function name.
  • Register the system task or system function name and the associated C language
    routines with the Verilog simulator.
    This registration tells the simulator about the new system task or system function name,
    and the name of the calltf routine associated with that task or system function (along with any other routines).
  • Compile the C source files which contain the PLI application routines, and link the object files into the Verilog simulator.
VPI的常用函数

获取实例, 并且遍历所有的子对象

/* OBJECT CODES */
#define vpiConstant     7
#define vpiFunction    20
#define vpiIntegerVar  25
#define vpiIterator    27
#define vpiMemory      29
#define vpiMemoryWord  30
#define vpiModPath     31
#define vpiModule      32
#define vpiNamedBegin  33
#define vpiNamedEvent  34
#define vpiNamedFork   35
#define vpiNet         36
#define vpiNetBit      37
#define vpiParameter   41
#define vpiPartSelect  42
#define vpiPathTerm    43
#define vpiPort        44
#define vpiRealVar     47
#define vpiReg         48
#define vpiRegBit      49
#define vpiSysFuncCall 56
#define vpiSysTaskCall 57
#define vpiTask        59
#define vpiTimeVar     63
#define vpiUdpDefn     66
#define vpiUserSystf   67
#define vpiNetArray   114
#define vpiIndex       78
#define vpiLeftRange   79
#define vpiParent      81
#define vpiRightRange  83
#define vpiScope       84
#define vpiSysTfCall   85
#define vpiArgument    89
#define vpiInternalScope 92
#define vpiModPathIn     95
#define vpiModPathOut    96
#define vpiVariables   100
#define vpiExpr        102

extern vpiHandle  vpi_handle(PLI_INT32 type, vpiHandle ref);
extern vpiHandle  vpi_iterate(PLI_INT32 type, vpiHandle ref);
extern vpiHandle  vpi_scan(vpiHandle iter);

获取仿真的时间

typedef struct t_vpi_time {
        PLI_INT32 type;
        PLI_UINT32 high;
        PLI_UINT32 low;
        double real;
} s_vpi_time, *p_vpi_time;
void vpi_get_time (
       vpiHandle object,          /* handle for an object, or NULL */
       p_vpi_time time )          /* pointer to application-allocated s_vpi_time structure */

获取value change:

typedef struct t_vpi_value {
      PLI_INT32 format;         /* vpiBinStrVal, vpiDecStrVal,
                                                vpiScalarVal, piRealVal,
                                                vpiOctStrVal, vpiHexStrVal,
                                                vpiIntVal, vpiStringVal,
                                               vpiTimeVal, vpiSuppressVal,
                                               vpiVectorVal, vpiStrengthVal,
                                               vpiObjTypeVal */

      union {
	    char      *str;
	    PLI_INT32 scalar;
	    PLI_INT32 integer;
	    double real;
	    struct t_vpi_time *time;
	    struct t_vpi_vecval *vector;
	    struct t_vpi_strengthval *strength;
	    char      *misc;
      } value;
} s_vpi_value, *p_vpi_value;
void vpi_get_value(
         vpiHandle object,                         /* handle for an object */
         p_vpi_value value)                       /* pointer to application-allocated s_vpi_value structure */

注册callback 函数:

#define cbValueChange        1
#define cbStmt               2
#define cbForce              3
#define cbRelease            4
#define cbAtStartOfSimTime   5
#define cbReadWriteSynch     6
#define cbReadOnlySynch      7
#define cbNextSimTime        8
#define cbAfterDelay         9
#define cbEndOfCompile      10
#define cbStartOfSimulation 11
#define cbEndOfSimulation   12
#define cbError             13
#define cbTchkViolation     14
#define cbStartOfSave       15
#define cbEndOfSave         16
#define cbStartOfRestart    17
#define cbEndOfRestart      18
#define cbStartOfReset      19
#define cbEndOfReset        20
#define cbEnterInteractive  21
#define cbExitInteractive   22
#define cbInteractiveScopeChange 23
#define cbUnresolvedSystf   24
#define cbAtEndOfSimTime    31
typedef struct t_cb_data {
      PLI_INT32 reason;
      PLI_INT32 (*cb_rtn)(struct t_cb_data*cb);
      vpiHandle obj;
      p_vpi_time time;
      p_vpi_value value;
      PLI_INT32 index;
      ICARUS_VPI_CONST PLI_BYTE8 *user_data;
} s_cb_data, *p_cb_data;

extern vpiHandle vpi_register_cb(p_cb_data data);
extern PLI_INT32 vpi_remove_cb(vpiHandle ref);
系统任务创建实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值