Skip to main content

数字电路测试框架探索…

起因是数电实验课用vivado用verilog写testbench,但是我想用chisel来完成一系列任务,但是我竟然没有什么思路,ysyx的flow是chisel->verilog,然后再用c++编写testbench,而verilator本身会把你的设计变成一个cpp的class,所以在你的testbench中通过对这个class中的某些值做赋值从而达到对整个电路的激励,但是在ysyx群里认为这种方式并不好,不能依赖verilator生成的文件来写testbench,相当于是你的testbench中对于这个类的引用先于verilator这个类的生成,在实际使用时也发现移植性过差,每次对于信号的改变都需要打开这个黑盒来抓信号,所以生出了使用chisel写testbench的想法,其实就是chiseltest,但是据我了解,chiseltest好像已经寄了,具体参考这篇文档https://www.chisel-lang.org/docs/appendix/migrating-from-chiseltest

所以导致我不知道chisel该怎么编写testbench,所以想在网络上探索一下,看看各位大佬们有没有什么解决的办法

现在从文档中得知,chiseltest变成了chiselsim

首先需要了解一下scalatest,因为chiseltest就是这个风格的,scalatest似乎是由很多不同的风格,比如FlatSpec风格就是我需要学习的https://www.scalatest.org/scaladoc/3.2.19/org/scalatest/flatspec/AnyFlatSpec.html稍微有点多,看了一部分了解了一下

然后我去了解了一下chiseltest,这个已经过时的测试框架,主要通过看他的readme,他的readme有一部分给了一些栗子,可以去看一下https://github.com/ucb-bar/chiseltest?tab=readme-ov-file

似乎除了用chisel写testbench,还有其他很多种方式,比如c++,python(cocotb),sv(uvm框架)

其实本质上是因为chisel生成的verilog太丑了,比如说我今天数电实验课想用verilog写一个简单的testbench就觉得特别的别扭,哎

所以最好的期望就是可以用chisel写tb但是仿真速度不会因此变慢,不过….看到一位佬的ppthttps://eminblog.cc/slides/chisel/#21

还是得回归verilog吗呜呜呜

引用sequencer大佬的一句话:验证框架的本质就是如何高效的定义coverage以及如何保证仿真性能的同时 让验证api尽可能简洁 还有就是减少runtime快速的收满coverage (然后之后还有一些话我就听不懂了…

然后他推荐chisel-nix的验证框架,让我去康康

嘶…没了解过nix,打算先去了解一下nix,麻了,里面怎么还有rust啊,感觉门槛有点高呀

我真有点学不明白这个nix呀,感觉看教程都明白,但是教程又感觉很乱,然后一看这个chisel-nix感觉复杂度还挺高的,想放弃了,但忽然想到jyy说的,你觉得难肯定是因为没有找对正确的办法,要学会做减法,当我开始思考什么是正确的方法的时候,我突然就又有信心了,确实,我甚至都没有看过nix的文档….比如我运行nix build的时候我能不能呢个看到他的trace,其实源码是用来了解所有细节的,从源码入手可太蠢了

我之后只用了nix来配置我的macos,具体的是用nix-darwin,可参考我的github仓库:https://github.com/yizishun/nix-darwin-dotfiles

我发现这整个仓库(指chisel-nix)我都看不太懂,这个gcd模块我都有点看不明白,但感觉不复杂而且可以学到很多高级chisel的用法

只可惜我的macos跑不了这个chisel-nix,有些input没有办法构建,有些input(dep)仿佛不支持macos架构,呜呜呜。不过没事,我觉得自己写一个chisel-playground并不是很难

阶段性小总结

现在看到的最好的似乎就是chisel-nix了,其实似乎是有一种准则在里面

1,testbench不能是某个仿真器specific的,比如ysyx的testbench就只能是verilator来仿真,之前也给我带来了不少的困扰

2,生成的module是pure的,就是生成verilog代码不应该包含任何验证相关的代码在里面,ysyx是可以做到这一点的,(即模块应该是可以综合的)

由于第二点的存在,就需要module和testbench的相关测试节藕,在testbench中可以使用dpi来进行对模块进行灌数据,还应该对模块的正确性(sva或者dpi我觉得都可以)进行判断,还应该生成波形文件让人类来进行进一步的正确性判断

所以其实可以使用verilog进行testbench的编写,但是chisel-nix是使用的chisel来做的,生成的sv实际上也是符合要求的(因为似乎我看chisel也有直接dpi的函数了)

(对了,还有一个小问题,之前ysyx可以直接打开verilator这个黑盒子来摸到里面的信号,即用verilator模拟跨模块引用(比如用这些内部信号进行difftest啊),但是其实verilog和chisel都有相关的跨模块引用的方式了,比如说chisel3.probes)

所以,总结一下,做法就是,用一个可以在多个仿真器上面运行的语言(v,sv,chisel…),写一个testbench,这个testbench要实现对模块的灌数据(dpi,或者直接赋值),以及对相关信号(顶层信号或者xmr引用拿信号)的检测(sva,difftest(dpi))


现在打算自己写一个chisel-playground,在此之前我甚至都不太明白mill的工作原理(而且我用nixpkgs下载的mill会出现奇怪的问题,服了),打算先读读mill的文档

然后我发现我不知道怎么bump一个新的chisel,因为chisel-nix里面的tb需要很多很新的chisel特性,所以我打算按照上面的concept学习一下systemverilog,然后用sv构造我的chisel-playground

UVM

有一个描述也很好的描述了tb的作用

这个网站很不错:https://www.chipverify.com/systemverilog/systemverilog-simple-testbench

在我想自己实现一遍这个tb的时候,我发现有个东西叫做UVM,这个东西不仅帮我已经实现了一个tb的框架,而且是很标准化的

我尝试使用多种语言为gcd写tb

但是sv-verilator首先就遇到了各种各样的问题,首先就是verilator对于virtual interface的信号变化没有办法dump,https://github.com/verilator/verilator/issues/5044,我当时还以为是我自己的问题…..debug了好久,麻了,然后我自己的设计估计也有问题,但是由于没有波形,我很难debug,于是

打算下一个vcs试一下,看了一下vcs好像也是把v->c,然后变成可执行文件

有点劝退了,这个东西是商业版的,而且不支持macos,导致我极其难受啊啊啊啊啊啊

然后我发现iverilog这个东西又特别垃圾,都不支持sv的新特性,dpi-c都不支持,又看了一下,啥都不支持,服了

哎,这可怎么办

似乎有人配了一个docker镜像,let me try

成功了,救我大命:https://zhuanlan.zhihu.com/p/266225644

我首先用sv实现了一个tb,然后发现UVM实际上就是sv框架的一个规范化,提供了一些很规范的接口,比如说

一般sv是用mailbox来进行drv和generator,mon和sb的通信,但是UVM提供了更规范的TLM的接口,总之这些东西一时半会也说不太清楚,你用sv也可以实现一个自己的的“UVM”,大概就是这么个意思,我主要看这个网站来写的https://www.chipverify.com/uvm/uvm-testbench-example-1,我觉得写的还行

我感觉整个tb都很依赖于设计,总之难以做到解耦

verilator对于sv的支持还是不够,不过还是找到了一些适用于verilator的uvm框架,https://github.com/chipsalliance/uvm-verilator?tab=readme-ov-file,以及用法,https://github.com/MikeCovrado/GettingVerilatorStartedWithUVM/blob/main/scripts/run_verilator.sh,最后跑出来了,但是总是有很多不尽如意的地方

COCOTB

这个东西的makefile好像有点问题,我还提了一个isuuehttps://github.com/cocotb/cocotb/issues/4284

感觉这个东西写一点小东西的设计挺好的,我觉得他比cpp好写,也更加简单,但是缺点估计就是速度很慢