使用PLI接口实现故障注入


1. PLI相关

1.1 PLI概念

Verilog PLI即Verilog 编程语言接口,是Verilog提供给用户用来扩展Verilog 仿真器功能的接口。

1.2 发展历史

PLI 的发展主要经历了 3 代。

1. 1985-TF 接口
第一代被称为任务/函数(Task/Function)接口,简称 TF 接口。TF 接口包含一套 C 语言函数库,均以 tf_ 为前缀,定义在 veriuser.h 中。这些 C 函数一般称为 TF 子程序,主要包括用户自定义任务和函数、实用函数、回调机制和数据写输出。

2. 1989-ACC 接口
第二代被称为存取(Access)接口,简称 ACC 接口。ACC 接口中的函数均以 acc_ 为前缀,定义在 acc_user.h 中。ACC 子程序主要用于访问和修改 Verilog 描述的多种对象。ACC 库函数是 TF 库函数的叠加,而非替换。一般 PLI 接口特指是 TF 和 ACC 接口。

3. 1995-VPI 接口
第三代被称为过程接口(Verilog Process Interface),简称 VPI 接口。VPI 子程序是 TF 和 ACC 子程序功能的合集,定义在 vpi_user.h 中。相对于 PLI 子程序又多又乱,VPI 尤显精炼。由于 PLI 诞生之初,没有统一的标准,完全是在实践中发展,导致常用的 PLI 库函数有近百个,写程序时基本都要查手册。而 VPI 是根据一定的标准统筹规划制定的,融入了很多面向对象的思想,库函数精简度远超 PLI。但是 VPI 结构比较复杂,不容易上手。VPI 最大的弱点还是对仿真器的支持并不友好。

2003-SystemVerilog 与 DPI
作为 Verilog 的扩展,2003 年 SystemVerilog 标准发布,支持更多形式的仿真。DPI 接口(Direct Procee Interface)成为软件与 SystemVerilog 交互的接口,目前占主流。一般情况下,使用 PLI 的 TF 和 ACC 接口就能满足仿真需求了。

1.3 PLI可以完成的功能

C语言总线功能模型

抽象的硬件功能模型可以采用C语言实现,而不需要HDL来描述,这样即可以通过隐藏一些具体的实现细节以保护知识产权

优化仿真的性能

PLI提供了很多方法用来在Verilog仿真与C语言模型之间传递数据

访问编程语言库

PLI使得Verilog 模型和测试程序可以访 问C语言库函数,通过PLI,Verilog可以给C函数传递参数,并可以将函数返回值返回给Verilog仿真器

读测试向量文件

测试向量是给仿真输入激励的通用方法,C语言的读文件功能是很容易实现的,因此采用PLI可以很方便的将C程序读取的值传递给Verilog 仿真器

显示输出

PLI使得用户输出程序可以动态的读取任意仿真的仿真值,并输出联合仿真,复杂的设计需要有不同层次的逻辑描述结构,各种描述结构有不同的仿真器,PLI为不同的仿真器之间的通信提供接口

仿真结果分析

通过PLI可以为HDL模型提供激励,也可以获取模型的输出,对结果进行分析

1.4 PLI库函数

PLI 库是Verilog PLI 标准中定义的C 语言函数库,PLI 应用中相关的子例程通过调用这些库函数完成与Verilog 仿真过程的交互。PLI 库函数可分为TF 实用库函数ACC 访问库函数

TF实用库函数

TF实用库函数用于在PLI应用的子例程与Verilog HDL仿真器交互数据,主要处理对象为HDIL任务或函数传递的参数。实用库函数也称为TF库函数。实用库函数总是以前缀tf_开头,若一个PLI应用文件中使用了实用库函数,须包含veriuser.h头文件,所有实用库函数的数据类型和常量都必须在该头文件中定义。实用库函数的用途包括:获取系统任务的信息;获取任务参数列表信息;获取任务参数值;把参数新值传递给调用库函数的任务;监视参数值得变化;执行管理维护任务;显示必要的信息;暂时挂起、终止、暂存或恢复仿真环境等。

ACC访问库函数

ACC访问库函数是提供给PLI应用程序访问HDL设计在仿真过程中的内部数据结构的C语言库函数,可以通过它读取HDL描述的内部数据结构中与某个对象相关的数据,也可以把特定对象的信息数据写入HDL描述的内部数据结构中,完成读写对象信息。存取库函数以前缀acc_开头,使用存取库函数的用户自定义的PLI应用相关的子例程必须调用acc_initialize ()库函数,用来初始化环境,退出时,用户自定义的PLI应用相关的子例程必须调用acc_close ()库函数,完成一些相关的处理工作。
若一个PLI应用文件中用到存取库函数,必须要包含acc_user.h头文件,所有访问库函数的数据类型和常量都必须在该头文件中定义。存取库函数使用句柄的概念来访问特定对象,句柄是预定义的指向HDL设计中特定对象的数据类型,获取了该对象的句柄就能获得对象的所有信息,同样可以通过该句柄修改对象的信息。存取库函数主要可以分为六类:取值函数,句柄处理函数,后继处理函数,修改函数,值变链接VCL函数和杂项处理函数。

1.5 PLI应用子例程

PLI应用子例程主要包括五类:

  1. calltf例程:在仿真过程中,系统任务被调用时执行;
  2. checktf 例程:在编译时执行,也就是在仿真时刻О之前执行,用来检查系统任务参数合法性;
  3. sizetf例程:用于返回标量或向量值的系统函数,sizetf例程在仿真时刻0前被执行一次,此例程反馈给仿真器系统函数返回值的位宽;
  4. misctf例程:事件驱动例程,由仿真事件回调或应用例程调度事件的回调,当misctf任务被调用时,仿真器传递参数reason常量,misctf例程执行时检查reason常量判断事件类型,然后执行相应的操作;
  5. consumer例程:通过一种称为值变链接VCL的PLI回调机制进行调用,由 calltf或misctf例程为仿真过正中内部数据结构的特定对象添加VCL标记,当指定的对象某逻辑值反生变化时,调用由VCL标记指定的consumer 例程。

前四类直接与PLI系统任务或函数名相关联,而consumer例程是在仿真过程中监视某个对象的数据信息,当某些逻辑值发生改变时被调用,不与系统任务或函数名直接相关。例程的类型规定了仿真器在仿真过程中触发该例程的机制或调用该例程的时刻。

1.6 PLI应用的注册与调用

在仿真过程中PLI 子例程通过调用PLI 提供的库函数来完成任务,但是Verilog 仿真器必须要知道用户自定义的系统任务相应的用户自定义的PLI 子例程的存在以及它们之间的关联性PLI 应用的注册就是将四个用户自定义PLI 子例程与用户自定义的PLI 系统任务或函数名相关。

PLI IEEE 标准提供了一种接口机制用于注册PLI 应用,接口机制定义了四项内容:

  1. PLI 应用的类型,是系统任务还是系统函数;
  2. 用户自定义的系统任务或函数名;
  3. 用户自定义的与 PLI 应用相关的子例程名;
  4. 与系统任务或函数相关的仿真器需要的其他一些信息。

VCS 是通过table 文件将系统任务或函数与相关的PLI 子例程相关联,table 文件的格式如下

val_proc 是系统任务名,在源文件中调用系统任务时,在前面加$符号;call 对应的是calltf 例程;check 对应的是checktf 例程;misc 对应的是misctf 例程;data 整型值指定传递给calltf、checktf 及misctf 例程的第一个参数,默认值为0;data 值与系统任务或函数名一一对应,用于区分对应相同C 例程的不同系统任务;acc 后加指定模块内允许的访问操作。

1.7 创建并调用一个PLI 任务的基本流程

流程如下:

以一个简单的系统任务$hello_verilog 为例
首先定义系统任务$hello_verilog,采用C语言实现PLI任务相关的PLI子例程

其次,将 PLI 任务注册到仿真器中,Synopsys  VCS 仿真器的 table 文件名为hello.tab ![](https://cloudpicture-1313887899.cos.ap-chongqing.myqcloud.com/blog_picture/202212051944224.png) 然后在Verilog HDL 源文件中调用系统任务
最后使用VCS 仿真器编译Verilog PLI 源代码,生成一个名为simv的可执行程序,运行simv 程序进行对硬件设计的仿真。

2. 如何利用Verilog PLI实现故障注入

2.1 基于Verilog PLI 技术的故障注入工具VPFIT

VPFIT :一个系统的故障注入工具,包含配置、控制、监视和数据分析等不同的功能模块
关键基于PLI 技术的对Verilog HDL 描述的系统模型进行故障注入,故障注入过程主要由PLI 系
统任务完成。VPFIT 工具的实现主要包括四个PLI 系统任务:Test_Exectime 任务、Inject_Transfault 任务、Inject_Intermfault 任务和Inject_Permfault 任务。主要使用了misctf 例程的回调机制来实现四个基本的系统任务。

基于Verilog PLI 技术的故障注入工具VPFIT 针对的对象为使用Verilog 硬件描述语言构造的目标系统模拟模型,采用的是PLI 技术,VPFIT 的总体框架主要包括用户配置模块、RTL 源码及Testbench 模块、Verilog PLI 库、Verilog仿真器以及故障注入结果分析与数据统计模块。

用户配置文件:主要用于配置故障注入实验的参数,包括故障注入目标模块的选择、故障注入次数、故障持续时间区间选择、工作负载选择和无故障工作负载运行时间等。
Verilog RTL源码:故障注入目标系统HDL源代码。
Testbench:是针对目标系统编写的顶层模块,主要完成的任务是对故障注入系统产生负载激励。
Verilog PLI 库:包括系统PLI库用户自定义PLI库。系统PLI库提供了一组标准的系统任务和函数,在硬件描述的模块中可以直接使用,除此还包括TF实用库函数和ACC 访问库函数,供自定义的PLI应用的相关子例程调用实现用户自定义系统任务。用户自定义PLI 库是包含PLI应用例程的C语言源代码经过编译后生成的库文件,以动态链接库的形式存放在系统库目录下。

2.2 故障注入的实现

VPFIT 工具的实现主要包括四个PLI 系统任务:

  1. Test_Exectime 任务:测试未注入故障时工作负载的执行时间
  2. Inject_Transfault 任务:完成瞬时故障的注入
  3. Inject_Intermfault 任务:完成间歇故障的注入
  4. Inject_Permfault 任务:完成永久故障的注入
    主要使用了misctf 例程的回调机制来实现四个基本的系统任务。

2.2.1 misctf 例程回调

四个任务都使用了Misctf 例程的回调机制,Misctf 例程由各种仿真事件或 PLI 应用例程调度事件驱动,完成仿真事件的自动回调或 PLI 应用调度事件的回调。当 misctf 任务被调用时,仿真器传递参数reason 常量,misctf 例程被调用时由reason 常量得到回调原因,判断事件类型,然后执行相应的操作。

Misctf 例程的回调可以分为两类: * 基于仿真事件的自动回调 Misctf 例程由于仿真过程中各种仿真事件驱动而自动调用,通过这种对misctf例程的回调过程来处理各种特殊的操作。Misctf 例程可以由各种原因自动调用,misctf 例程通过检查常量输入参数reason,只需处理PLI 应用相关事件的回调即可。 * 基于PLI 应用例程调度事件的回调 TF 库提供了一些库函数,使PLI 应用可以调度它的misctf 例程在未来的仿真时间被调用,当由这三个函数调度的misctf 例程被激活时,仿真器将向misctf 例程传递一个reason参数常量值REASON_REACTIVATE。

2.2.2 TestExectime 任务

定义 PLI 任务 Test_Exectime,主要目的是测试未注入故障时工作负载的执行时间Tworkload

当 REASON_ENDOFCOMPILE 事件发生时,在 State_flag=0状态,调用库函数 tf_gettime()获得当前仿真时间;当 REASON_FINISH 事件发生时,在END 状态,同样调用库函数tf_gettime()获得当前仿真时间,通过两个不同状态获得的时间差就可得到未注入故障时工作负载的执行时间Tworkload。 ### 2.2.3 InjectTransfault 任务 定义 PLI 任务 Inject_Transfault,主要功能是完成瞬时故障的注入

2.2.4 InjectIntermfault 任务

定义PLI 任务Inject_Intermfault,主要功能是完成间歇故障的注入

2.2.5 InjectPermfault 任务

定义 PLI 任务 Inject_Permfault,主要功能是完成永久故障的注入


文章作者: DPH
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 DPH !
  目录