| ||
伴随着SV推广的热浪,SV已经不只是作为一种验证语言流行开来,实际上它同样在早期也作为了一种硬件描述语言和一种通用编程语言得到了应用。在软件编程的过程中,SV同Java一般也有了更为丰富的数据类型和类的相应概念,这种面向对象编程的思想使得一些软件工程师在“移民”到验证领域时的阵痛期并不会太久,但随后他们会感到一些失望,因为SV尽管有着类Java的编程方式、内存管理方式等等,但又缺少一些东西,比如在一些底层数据类型操作的函数在使用起来有点掣肘,下面是一些数据:
这张表格是对于各个主流编程语言中对于字符串String类型的函数数量对比,而更习惯于软件编程的用户(同时精通于Java、Python等)就会对SV目前底层函数的支持表示不满。这些软件用户们更怀念过去在Java、Python中各种丰富的底层函数应用,而从硬件一侧迁移到SV的新用户们则有点“刘姥姥进大观园”,已经觉得新添加的特性有点应接不暇,够学几辈子的了(比起之前的HDL硬件编程需要的语法来看)。
Python的忠实粉丝都知道Python世界的一句谚语“Batteries included”,这指的是官方发行的Python版本自带了相当齐全的软件库,拿来就可以直接写程序,一般不需要安装额外的库,就同一出生就含着金钥匙为自己生命代言的天才一样,做什么都是手到擒来。而SV的用户,尤其在适应了软件编程思维,同时又熟悉一些其它编程语言特性的时候,就对SV缺少像Python一样丰富底层函数的气质颇有微词了。
所以,那些见识过“好东西”的verifier们就局部地联合了起来(公共的验证开源项目数量少而死亡率太高),他们首先在自己的公司内部按照所处项目的实际要求,试图在SV基础上开发一些扩展地库,来弥补一些SV应该具备的底层库;同时,在这些库后来日益完善的基础上,经过公司的同意,他们将这些库开源了出来,并希望不断更新(或者被收入SV的标准第三方库)。我们本节为大家分享两个开源质量较高且至今保持活力的SV的第三方库,通过简明地介绍它们的主要特性,希望读者们首先知道这些库提供的基本特性,而在后期项目使用中,如果有需要就可以快速安装它们,不必再重复造轮子。同时,我们也希望通过本节,读者在以后的工作中,可以有目的性地将库分为公共库(有更广的使用潜力)和VIP库(更有针对性),而将过去那些有收录进公共库潜力的方法、类可以整理到一起,相应地做好单元测试(库开发的标准流程)和文档,造福公司内更多的同事,或者在允许的情况下也开源出来。
SV开源库之一:svlib
Verilog公司开源了他们之前开发的SV的扩展底层库svlib,这个库可以从这个链接中找到。另外既然推荐了他们的功德库svlib,也简单介绍一下这家公司,作为他们共享svlib的一点回报吧。路桑跟这家公司之前在项目中有过合作,他们是一家“高端”的验证咨询公司,可以说里面的接触到的每一位工程师都很有气质(验证工程师的软硬通吃的气质),而且个个以一当十。截止到目前他们在中国还没有直接的业务,但如果接下来他们进入中国寻求业务而且在招聘质量不打折的前提下,这是一家提供良好咨询服务平台的公司。好了,这一段软广告就嵌入到这里吧。
www.verilab.com/resources
svlib分成了若干个分支,不同分支具备相应的功能,这些可以拆解和独立开发的功能包括有:
通用的字符串处理和正则表达式功能。
可以对文件和目录操作的功能,包括目录查找、列表、文件属性征询的功能。
可以同操作系统互动的功能,包括有查找环境变量、传入命令行、时钟日期信息查询等功能。
各种其它方便的功能,例如与枚举类型相关的函数操作。
成套的插件用来从.ini或者YAML配置文件读入,继而存储为配置数据格式DOM;或者反之,从DOM格式,存为.ini或者YAML标准格式。
另外,svlib也有类似uvm_macros.svh的宏文件svlib_macros.svh,该文件也定义了一些易用的宏,方便使用者。下面我们就上面的几种主要的功能做简单介绍。
字符串处理
正如上面拿字符串string类型的例子,SV的string有一点尴尬的是,它并不允许直接让用户在string类型上面扩展,而尽管它看起来就有点像类,但又无法去继承。
string S = " Some text ";
int n = S.len();
S = S.toupper();
对于上面字符串的操作,跟对象的使用很像,但如果像扩展string类型,只能考虑在svlib中添加一个新的类Str,通过类的方法来实现扩展。例如下面的例子:
Str ss = Str::create(" Some text ");
ss.trim(Str::Right);
$display("\"%s\"", ss.get());
输出结果:
" Some text"
通过添加新的字符串类Str(内嵌string变量并且对其操作),这可以在原有string类型的基础上扩展更多需要的方法,例如上面的去除字符串右边的空格。这个新的方法看起来可以带来更多新的特性,但同时也带来了一点麻烦。例如原有的SV用户已经习惯于对string变量本身的操作、通过操作符例如{}来合并字符串、或者直接赋值的形式来获取字符串内容等,这一点同新添加的Str类通过自带函数的操作有明显的差别。
如果SV的用户不习惯新的方式,又或者原有的SV代码不想大规模改动的时候怎么办呢?svlib同时也提供了经典的package内建函数的形式,将一些主要的函数也同时按照就有的函数操作的形式来实现。
$display("\"%s\"", str_strim(S, Str::BOTH));
输出结果:
"Some text"
上面这个方式更贴近于原有的字符串操作,用户可以选择任何一种方式来实现字符串的操作。
正则表达式处理
对于熟悉正则表达式的读者,尤其是Python中正则表达式习惯的读者,对于svlib中新添加的正则表达式类Regex和其函数处理应该不会感到陌生。
Regex re;
re = regex_match("06/07/17", "([0-9]+)/([0-9]+)/([0-9]+)");
if (re != null) begin
$display("Looks like a data");
void'(re.subst("$2-$1-20$3"));
$display("data = %s", re.getStrContents());
end
输出结果:
Look like a data
07-06-2017
svlib提供非常全面的跟正则表达式相关的匹配和替换的方法,更多的函数可以在svlib的文档中找到。
文件和目录操作
文件和目录的操作在脚本语言中是经常使用到的,而SV欠缺这一点(或者说现有的文件打开、读写的操作不满足多样需求)。svlib提供了与路径相关的类、与文本信息相关的类等等。譬如,SV无法批量地得到相关的文件名,而这一些与目录有关的操作,svlib提供了方法。下面的例码就可以将当前目录下所有后缀名以sv结尾的文件都找到并写入到一个字符串的队列中。
string dirList [$];
dirList = sys_fileGlob("*sv");
下面通过Pathname类来完成文件路径的有关操作,通过自带的函数可以取得文件的扩展名、路径名以及文件名本身。
Pathname path = Pathname::create("/home/svlib/src/svlib_pkg.sv");
$display(path.extension()); // .sv
$diaplay(path.dirname()); // /home/svlib/src
$display(path.tail()); // svlib_pkg.sv