浅谈System Verilog的DPI机制

电子说

1.3w人已加入

描述

在上一篇《浅谈建模的意义和验证的危机》中,曾大肆鼓吹“对于认知DUT,行为建模既是方法,也是目的”,“心中没有她,又怎能待好她”,呼吁IC验证者要通过手写DUT的reference model来实现对DUT的规格特性的充分理解。然而,此篇内容却涉及调用第三方的代码作为reference model。此刻耳畔仿佛想起了啪啪的打脸之声。

System Verilog(SV)把其他编程语言统一成为外语,Foreign Programming Language(FPL)。Direct Programming Interface(DPI)是SV定义的一种专门集成外语代码和处理SV之外的业务功能的机制,主要负责和广大的外部语言代码进行沟通和交涉。如果用西安的各所大学来比喻SV的各个机制功能,那么DPI对应的大致就是西安外事学院了。

海纳百川,有容乃大是川大的校训。SV的制定者希望Test Bench能兼济包容,也不希望所有组件和代码都只能是由SV语言开发。并且不得不承认,通过集成C/C++/Matlab的代码,会缩短搭建验证平台的时间,减少IC验证者的工作量。

在DPI机制中,仿真系统的资源被分成独立的两部分:SV-domain(SV语言区域)和FPL-domain(其他语言区域)。这些资源包括缓存数据和变量的存储资源,也包括程序编译链接和执行的运行资源。在验证平台中调用FPL程序代码时要遵循黑盒原则,即FPL代码涉及的业务功能是独立的,与SV部分要充分解耦。在SV和FPL中无法直接访问对方代码中的变量。

他们就像白天和黑夜。虽然黑夜给了我们黑色眼睛,我们也曾用它去寻找光明,但是黑夜永远不懂光明,正如白天不懂夜色的黑。

Verilog

System Verilog 3.1版本支持的FPL只有C。其他语言可以通过C写的wrapper包装一下实现跟SV的通信。

DPI专门定义了一些数据类型,这些数据类型与SV的多种数据有对应关系。在C程序的接口处,使用这些专门定义的参数,利用数据类型的对应关系,实现SV-domain和C-domain的通信。为了便于使用,SV还为某些重要的数据类型,量身定制了一系列的操作和处理函数。如何使用这些数据类型和相应的操作函数实现两个domain的数据传递和转换,是DPI关键技术点,也是本文的干货所在。

通常情况,C的函数都是不消耗仿真时间,即延时是0,瞬间完成,就像在SV中调用function一样。只不过这个function的端口类型只有input,output和inout,不支持ref。

为了把C语言的数据类型能映射到SV语言,SV定义了一个文件svdpi.h。在该文件中定义了许多的数据类型,这些类型基本可以和C语言的数据类型一一对应。

Verilog

上面表格是我挑出的比较重要的几种数据类型,而其中比较重要的是open array[]。

绿皮书有一章节(12.5)专门介绍它,在svdpi.h中也专门为它定义了很多的微操函数。

在C语言里面,函数接口的参数会划分方向,对于输入的变量,加上const,一旦在C程序中,对输入变量进行赋值操作,编译器会报错。我觉得犯这种错误的概率太低,没必要加。问道于何同学,觉得这种错误还是比较常见的,建议加上。

Verilog

在SV角度看,open array[ ]就是动态数组(dynamic array)。SV之所以选择动态数组来进行SV和C之间的数据内容传递,是因为动态数组的深度可以灵活改变。只要在定义dpi接口的时候,把动态数组的名称和C的对应的数组关联上,那么只需要在不同的场景中,通过动态的改变动态数组的深度,就可实现SV和C的数据传递。

队列(queue)表示有意见,嘟嘟囔囔的撅着小嘴问,为啥不选我?

先坐下吧,闵老师扶了扶眼镜说,SV和C的数据存储虽然都放在内存中,但是系统需要把它们俩的存储空间分开,最忌讳内存越界。动态数组在每次使用之前,需要先通过new[N]来分配空间,之后动态数组的内存空间就确定了。然而队列的存储空间是一直可变的,SV虽然会初始时刻给你分配一定空间,但是当元素把空间装满后,SV会自动分配更多的空间。这样就容易造成内存越界。

关联数组(associative array)也想发言,把肥嘟嘟的小手举得高高的。

先把手放下来,闵老师笑着轻轻摆了摆手,你太离散了,存储的都是稀疏和分散的数据,SV仿真器要采用tree或hash table的方式来存放,会带来额外的存储开销。

以上就是DPI的相关背景介绍。干说不练假把式,我们举个例子吧。

如下图所示,peak_find是一个matlab函数,输入变量signal包含多个无符号数据,经过一系列运算和处理,输出4个无符号数据到变量peak_two之中。

Verilog

将该函数集成到SV的Test Bench中,使用matlab engine的方式需要定义一个c程序将其包起来,名称如下所示。

void peak_find_dpi(const svOpenArrayHandle signal_i, svOpenArrayHandle peak_two_o);

其接口参数就用到了开放数组。

该C函数可分为如下几步:

Verilog

图4 dpi.c的流程图

站在SV角度看,C程序是外来的,是舶来品,需要“进口”,即import。代码只需一行: import “DPI-C” function void name_of_your_c_function();

假如我们国家只能进口美国的商品,其他国家的货物就得都先到美国,再来中国。同样的道理,用matlab engine的方式,调用matlab程序,得用C程序先包装一下。

matlab程序如此,C++程序亦是如此。

对于C程序,仿真时通常是用GCC编译,而matlab程序是用到了mathWorks公司的MATLAB工具,SV仿真需要用到Synopsys公司的VCS工具。夜路走的多了难免遇到鬼,工具用的多了也难免有版本问题。

so文件报错是一个典型的工具版本不一致引入的问题。如下图所示。这个问题其实是IT问题,不是IC验证技术问题,但是它跟IC验证息息相关。

Verilog

就像神农尝百草,梅同学通过尝试多个版本的MATLAB,GCC和VCS,最终发现GCC4.8.5+MATLAB2015B+2017以上VCS的组合可以比较稳妥。同时把/usr/lib64/libstdc++.so也要更新到6.0.21。遂搞定这个问题。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分