时间:2024-05-04
王远 陈孟东 陈冬 刘杨 齐鹏
摘要:该文在对System Verilog与C语言的接口进行介绍的基础上,详细描述了两者之间数据共享的基本方法,然后通过对一款示例芯片基本功能的分析,设计了芯片模拟器的四个基本接口函数并对其实现进行了简要描述。通过该芯片模拟器设计与实现的介绍,可以从中了解System Verilog测试平台下芯片模拟器实现的一般方法。
关键词:System Verilog;芯片模拟器
中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)07-1662-03
Design and Implementation of Chip Simulator Based on System Verilog
WANG Yuan1, CHEN Meng-dong1, CHEN Dong2, LIU Yang2, QI Peng2
(1.Jiangnan Institute of Computing Technology, Wuxi 214000, China; 2.65587 Army, Siping 136000, China)
Abstract: This paper introduces the interface between System Verilog and C, and describes the basic method of data sharing between two languages. Through the functional analysis of a sample chip, we design four interface functions of the chip simulator and describe their implementation. We can learn about the realization of chip simulator on System Verilog platform through this paper.
Key words: System Verilog; chip simulator
1概述
在當今百万门级的ASIC设计中,验证所占用的时间无疑成为缩短集成电路产品设计周期中的瓶颈。如何改进验证方法,改善验证手段,从而提高验证效率,缩短验证周期,是验证人员乃至产品经理们最关心的问题[1]。System Verilog结合了来自Verilog、VHDL、C++的概念,以及验证平台语言和断言语言,将硬件描述语言HDL与现代的高层级验证语言HVL结合了起来,使原本繁琐费时的验证工作变得相对简单易行。与传统的验证方法相比,这种验证方法大大提高了验证工作的效率,缩短了验证的周期,同时有力地保证了验证的完备性。
同时,System Verilog提供了与其他语言的编程接口,可以通过和其他语言数据共享的方式进行相互交互,将验证工作中的繁琐复杂的功能交给软件来实现,提高验证的效率和性能。这样在芯片的验证过程中,就可以通过数据共享将芯片的主要功能通过软件来实现,然后通过比对结果来验证芯片功能的正确性。
2 System Verilog与C语言接口介绍
Verilog使用编程语言接口(PLI, Programming Language Interface)来跟C语言交互,相比之下System Verilog引入了直接编程接口(DPI, Direct Programming Interface),它能更加简单的连接C、C++或者其他非Verilog编程语言[2]。
一旦声明或者使用import语句“导入”了一个C子程序,就可以像调用System Verilog中的子程序一样来调用它。import声明定义了C任务和函数的原型,但使用的是System Verilog的数据类型,带有返回值的C函数会被映射成一个System Verilog函数,void类型的C函数则被映射成一个System Verilog任务或者void函数。导入的C子程序可以有多个参数或者没有参数,缺省情况下参数的方向是input,即数据从System Verilog流向C函数,但是参数的方向也可以定义为output和inout。
通过DPI传递的每个变量都有两个相匹配的定义,一个是System Verilog的,一个是C语言的,这里需要确保两者使用的是兼容的数据类型。由于数据类型比较繁杂,为了说明两者之间数据类型的对应关系,以下就System Verilog和C语言之间的数据传递进行简单介绍。
2.1数据类型映射
表1给出了System Verilog和C语言子程序输入输出之间数据类型的映射关系,C结构类型在头文件svdpi.h中定义,在使用时需要包含此头文件。
在使用两种语言进行对接交互的时候,函数参数和返回值的数据类型参照上表进行相应转换即可保证两者的数据是兼容并可以互相通信使用的。
2.2开放数组
当需要在System Verilog和C之间共享数组的时候,可以采用反向工程的方式分析出数组在System Verilog中的存储方式,而在C中根据数组的内存映射方式进行操作。然而这种方式很容易出错,一旦任何一个数组有变化,必须重新编写代码进行调试。在System Verilog中提供了“开放数组(open array)”来处理这种情况,这使得我们能够编写出可以操作任何大小数组的通用C代码。在System Verilog中开放数组的查询函数比较多,这里笔者就基本的开放数组的使用方法进行简单介绍。
使用基本的开放数组在System Verilog和C程序之间传递数据时,在System Verilog中声明相应的C函数,然后在C代码中可以使用svOpenArrayHandle类型的句柄来引用此开放数组。该句柄指向一个含有字范围等开放数组信息的结构,可以通过调用svGetArrayPtr等方法来获取实际的数组元素,该函数返回一个void*类型的指针。
2.3复合类型
对于C和C++中比较复杂的类,就类属性的内存映射方式来讲,两种语言并不完全一致,不能直接共享对象。为了达到共享的目的,System Verilog测试平台使用压缩结构来保存一个简单的像素,使用类来封装对像素的操作。通过使用压缩和解压缩的方法对两种数据格式进行转换,就可以使两者共享符合类型的数据了。
3芯片模拟器的设计与实现
通过以上介绍,笔者针对芯片的整体架构及功能,采用上述的System Verilog与C对接的方式对芯片模拟器整体架构及主要功能模块的设计和实现进行详细说明。
3.1芯片模拟器整体架构
在基于System Verilog与C对接的模拟器实现中,System Verilog作为整个验证环境的平台,将测试数据分别发送给芯片的硬件逻辑和芯片模拟器,然后收集两者的数据输出结果进行比较,以期判断芯片逻辑的正确与否[3],具体的结构如图1所示。
图1
其中,芯片模拟器采用软件的方法实现了芯片逻辑需要验证的功能,并根据整个验证平台的需要添加需要的辅助功能。为了更直观的介绍芯片模拟器的设计和实现,这里以笔者实现的一个简单芯片模拟器为例进行说明。
此芯片的主要功能可以简化为发送、接收数据以及配置芯片参数这三个简单的功能,芯片模拟器的功能则是在这三个接口上对芯片的功能进行模拟实现,然后比对相应的数据是否正确。其中发送方向上对测试数据进行处理然后发送输出,接收方向则从接收方向对测试数据进行处理,配置芯片参数通过测试数据生成模块将参数发送给芯片模拟器进行配置。需要注意的是,为了验证芯片逻辑的正确与否,这里System Verilog平台发送给芯片逻辑和芯片模拟器的数据必须是完全相同的,这样才能保证通过结果比对得到的测试结果是有参考价值的。
通过以上分析,笔者将这三个主要功能分别进行实现,其中发送和接收数据两部分需要用到芯片参数配置部分所配置的芯片参数,因而这里将芯片参数设定为全局参数,方便芯片参数配置部分进行参数配置以及发送和接收数据时依照此参数进行数据处理。芯片参数配置设计一个单独的接口方便进行参数配置,同时,为了验证参数配置地是否正确,需要另外的接口来从全局参数中读取芯片参数来验证参数配置的正确性。发送数据方向设计一个接口来处理发送方向的数据,这里需要用到芯片的参数,通过以上的设计简单的读取全局芯片参数即可。接收数据方向同样设计一个接口来处理接收方向的数据,和发送方向类似,通过读取全局芯片参数进行数据处理。芯片模拟器的整体结构如图2所示:
图2
3.2配置接口
配置接口负责芯片参数的配置以及验证所配置参数的正确性。由于需要配置的参数比较多,这里通过地址译码的方式来进行配置;同样,读取芯片参数时也需要相应的地址来读取所需的芯片参数,基于此两个函数的结构就确定了。
配置芯片参数的函数接口如下:
int setReg(const svBitVecVal* addr, const svOpenArrayHandle data);
其中,返回值为1表示配置成功,返回0表示配置过程中出错;参数addr表示所配置参数在地址列表中的地址,参数data则为相应地址所配置的芯片参数值,这里data采用开放数组的方式来处理相应数据,为共享数据提供了便利[4]。为了能够调用此函数,在相应的System Verilog代码中需要导入此函数,具体如下:
import“DPI-C”function int setReg(input bit [7:0] addr, input bit data[]);
读取芯片参数的函数接口如下:
int getReg(const svBitVecVal* addr, const svOpenArrayHandle data);
类似函数setReg,返回值为1表示读取参数成功,为0表示读取失败;参数addr表示要读取参数的地址,data则是读出的芯片参数。同样,为了能够调用此函数,也需要在相应的System Verilog代码中导入此函数,具体如下:
import“DPI-C”function int getReg(input bit [7:0] addr, output bit data[]);
这里需要注意的是此处data的数据方向为output,因为这里是读取芯片参数,data的数据空间需要在System Verilog中先分配好[5]。
3.3发送方向
发送方向和接收方向的数据处理是芯片最主要的功能,此部分需要按照芯片逻辑所设计的功能进行模拟实现,这两部分中所用到的芯片参数已通过读取全局参数解决,其他部分只需用C语言来进行相应功能的实现即可。具体的函数接口如下:
int send(const svOpenArrayHandle data, const svBitVecVal* type);
其中函数返回值为1表示发送方向数据处理完成并成功发送,0表示发送方向出错;data即为需要处理的数据,type表示待处理数据的数据类型。System Verilog中导入此函数的方式如下:
import“DPI-C”function send(input bit data[], input bit [2:0] type);
在进行数据处理时只需要在相应的子函数中将data进行数据类型转换,使其能够在C语言中进行处理,这样就可以使用软件的方法对芯片功能进行模拟了。具体方法如下:
unsigned char* data_in = (unsigned char*)svGetArrayPtr(data);
通过函数将data转换为C语言中的指针类型,这样就可以通过指针访问System Verilog中的数据,实现System Verilog和C的数据共享,完成芯片相应功能的模拟。
3.4接收方向
接收方向的数据处理和发送方向类似,函数接口如下:
int recv(const svOpenArrayHandle data);
其中函数返回值为1表示接收方向数据处理完成,0表示接收方向出错;data即为接收的待处理数据。System Verilog中导入此函数的方式如下:
import“DPI-C”function recv(input bit data[]);
数据处理以及数据共享的实现和发送方向的处理类似,这里不再赘述。
4结论及下一步工作
本文首先介绍System Verilog和C语言之间数据交互的方法以及两者互相调用子函数的方式,然后通过笔者以该方式实现的芯片模拟器为例进行详细说明,以此方式来对整个芯片的功能进行验证,具有一定的普遍性。通过这种方式实现的芯片模拟器比较灵活,并且实现起来相对硬件描述语言简单,同时通过数据共享,能够对芯片功能的各个方面进行比较详尽的模拟,在芯片验证工作中具有非常出色的表现。
最后,需要指出,通过这种方式实现的芯片模拟器,在一些方面还存在着不足,在硬件更底层的模拟中还不能够完全取代其他验证方式;在一些比较特殊的情形中通过软件来模拟比硬件描述语言更为复杂,这也是此方法的不足;另外,笔者实现的芯片模拟器在芯片功能模拟时模拟程度还不是非常精确,需要后续的改进和完善。
参考文献:
[1]周卓.基于SV语言的802.11 MAC芯片逻辑验证方案[J].现代电子技术,2009(18).
[2] Chris Spear.System Verilog for Verification[M].Springer,2006.
[3] Janick Bergeron,Eduard Cerny,Alan Hunter,et al.System Verilog验证方法学[M].夏宇闻,杨雷,陈先勇,等,译.北京:北京航空航天大学出版社,2007.
[4]程刚,蔡敏.基于System Verilog的SoC功能验证方法研究[J].科学技术与工程,2009(22).
[5]李磊,罗胜钦.基于VMM方法的SOC集成验证[J].电子与封装,2011,11(1).
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!