兄弟萌,
当你着手开始写新的RTL时,想不想边写边编译边清理bug呢?
当你对一个语法感到费劲,需不需要立刻有个环境做一下实验呢?
当你费了九牛二虎之力终于写完个模块时,有没有立刻看看波形的悸动呢?
当你完成了初步的debug之后,要不要来些独立自主的随机测试呢?
那么请不要犹豫,果断来入手一波疑似RTL定向验证的巅峰之作auto_testbench吧!
https://gitee.com/gjm9999/auto_testbench
脚本工作与linux环境,下载工程后执行命令:
{$script_path}/auto_testbench [-f module.v] [-v]
-f:后缀rtl的文件名,推荐在rtl所在目录下进行执行,也支持带有路径,如不加则生成空工程用于仿真;
-v:表示需要自动生成比对环境代码,否则只生成仿真环境;
生成的仿真环境如下(以v1版本下的bypass_fifo.v为例):
.
├── cfg
│ ├── cfg.mk
│ ├── check_fail.pl
│ ├── run.do
│ └── tb.f
├── sim
│ └── Makefile
├── top
│ └── testbench.sv
└── ver
└── bypass_fifo_pkg.sv
top目录下的testbench.sv是赏心悦目的顶层文件:
在sim目录下执行:
make run [seed=xxx] [wave=on/off][mode=xxx]
可进行环境仿真,仿真结果会放置于mode同名目录下,可进行波形debug:
verdi -ssf [mode]/wave/xxx.fsdb &
bypass_fifo是本工具的一个测试模块,其接口如下:
module bypass_fifo #(
parameter DEPTH = 8,
parameter WIDTH = 128
)(
input clk,
input rst_n,
input data_in_valid,
input [WIDTH -1:0] data_in,
input data_in_power,
output data_in_ready,
output data_out_valid,
output [WIDTH -1:0] data_out,
input data_out_ready
);
其功能是一个握手型fifo,但是只有data_in_power为1的数据会被输出,其他数据会被丢弃。咱先不说这个功能为啥这么奇怪(事实上这是一对多fifo的一部分),就单纯聊怎么验证这个模块。
在bypass_fifo.v的同级目录下输入:
{$script_path}/auto_testbench -f bypass_fifo.v
会得到如下的提示内容:
##====================================================================##
Gen over! please cd ./bypass_fifo_verification/sim
You need modify ./bypass_fifo_verification/top/testbench.sv
like cp ./bypass_fifo_verification_bak/top/testbench.sv ./bypass_fifo_verification/top/
You need modify ./bypass_fifo_verification/cfg/tb.f
like cp ./bypass_fifo_verification_bak/cfg/tb.f ./bypass_fifo_verification/cfg/
##====================================================================##
提示内容的意思就是:
现在你可以到sim目录去跑仿真了。如果你之前目录下有一个bypass_fifo_verification那我已经把它改名成bypass_fifo_verification_bak目录了,你看看要不要把旧的testbench.sv拷贝过来用,顺便看看tb.f是不是也得拷过来呀。
不管这些,直接跳转到./bypass_fifo_verification/sim目录,执行make cmp进行编译。正常来说编译会直接通过,遇到错了就根据报错进行排查。如果报文件缺失,那么请打开 ./bypass_fifo_verification/cfg/tb.f:
+libext+.v+.sv
-y /home/ICer/gitee_path/auto_testbench/src/
/home/ICer/gitee_path/auto_testbench/src/bypass_fifo.v
../top/testbench.sv
这个文件里会把bypass_fifo.v所在的目录设置为全局搜索目录,如果这样不足以涵盖内部调用的模块,那么请进一步修改该文件。
修改掉全部的编译bug后编译即可通过,之后打开 ./bypass_fifo_verification/top/testbench.sv文件,按照自己的需求修改。在该文件中对信号进行了四种力度的随机:
举个例子,对于data_in_power,其生成逻辑是这样的:
always @(posedge clk or negedge rst_n)begin
if(~rst_n)begin
data_in_power <= 'x;
end
else if(data_in_valid && data_in_ready)begin
data_in_power <= $urandom;
end
else if(data_in_valid == 0)begin
data_in_power <= $urandom;
end
end
上述内容由于涉及到信号识别以及信号匹配,所以很容易出问题(比如aa_bb_rvalid应该找bb_aa_rready,但是可能误找到bb_aa_wready),所以一般需要检查和按照需求修改下。
修改完成后,在sim目录下键入make run seed=0 wave=on进行仿真,等待pass(必然pass因为都没有比对):
之后通过verdi -ssf sim_base/wave/sanity_0.fsdb &打开波形即可:
对于一种场景的模块,建议加入自动比对:单一握手型输出的模块。仍以bypass_fifo为例,如果想要加入自动比对,那么在生成时后缀-v即可:
{$script_path}/auto_testbench -f bypass_fifo.v -v
此时生成的环境中,多了一个文件./bypass_fifo_verification/ver/bypass_fifo_pkg.sv:
package bypass_fifo_pkg;
parameter ERROR_DEBUG_CNT = 5;
parameter DEPTH = 8;
parameter WIDTH = 128;
int error_cnt = 0;
bit check_en = 0;
typedef struct{
bit [WIDTH -1:0] data_in;
bit data_in_power;
} data_in_valid_struct;
data_in_valid_struct data_in_valid_bus_q[$];
typedef struct{
bit [WIDTH -1:0] data_out;
} data_out_valid_struct;
data_out_valid_struct rm_q[$];
data_out_valid_struct data_out_valid_bus_q[$];
endpackage
简单说下思路,工具将若干输入和输出封装为struct,并且声明输入输出队列和一个输出类型的rm队列。在testbench中补充了四个task:
in_queue_gain:获取输入数据,并写入输入队列;
out_queue_gain:获取输出数据,并写入输出队列;
rm_queue_gain:使用输入队列,预期输出数据,并写入rm队列;
queue_check:对比输出队列与rm队列,对比不通过则报错,这个task是固定的不需要修改;
对bypass_fifo而言,前两个方法已经生成正确,不需要修改:
task in_queue_gain();
while(1)begin
@(negedge clk);
if(data_in_valid && data_in_ready)begin
data_in_valid_struct data_in_valid_dat;
data_in_valid_dat.data_in = data_in;
data_in_valid_dat.data_in_power = data_in_power;
data_in_valid_bus_q.push_back(data_in_valid_dat);
end//if-end
end//while-end
endtask: in_queue_gain
task out_queue_gain();
while(1)begin
@(negedge clk);
if(data_out_valid && data_out_ready)begin
data_out_valid_struct data_out_valid_dat;
data_out_valid_dat.data_out = data_out;
data_out_valid_bus_q.push_back(data_out_valid_dat);
end//if-end
end//while-end
endtask: out_queue_gain
而需要修改的是对rm的预期,根据data_in_power判定数据是否需要输出:
task rm_queue_gain();
data_in_valid_struct data_in_valid_dat;
data_out_valid_struct data_out_valid_dat;
while(1)begin
wait(data_in_valid_bus_q.size > 0);
data_in_valid_dat = data_in_valid_bus_q.pop_front();
if(data_in_valid_dat.data_in_power === 1'b1)begin
data_out_valid_dat.data_out = data_in_valid_dat.data_in;
rm_q.push_back(data_out_valid_dat);
end
end
endtask: rm_queue_gain
完成修改后,将./bypass_fifo_verification/ver/bypass_fifo_pkg.sv中的check_en修改为1,重新跑仿真:
此时会发现比对未通过(这个模块确实有功能bug),打开波形确认'hb985d7ad这个数是怎么个情况:
发现'hb985d7ad这个数输出没有握手就data_out_valid跳变了,显然是功能性bug。
作者:尼德兰的喵
文章来源: 芯时代青年
推荐阅读
更多IC设计干货请关注 IC设计专栏。欢迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
玻璃钢生产厂家宁德手糊法玻璃钢雕塑价格无锡玻璃钢人物雕塑多少钱百货商场三八节美陈西藏道路玻璃钢花盆潍坊玻璃钢雕塑联系方式南京三水玻璃钢人物雕塑保山市玻璃钢雕塑批发溧阳商场新年美陈滨州广场玻璃钢雕塑茂名玻璃钢卡通雕塑代理价格重庆户内玻璃钢雕塑供应商普洱玻璃钢雕塑价格表桂平玻璃钢泡沫雕塑价格甘肃商场开业美陈漯河玻璃钢彩绘雕塑定做厂家文山市玻璃钢雕塑价格龙泉玻璃钢牌匾雕塑玻璃钢莲花雕塑长春玻璃钢公园雕塑佛山定做玻璃钢卡通雕塑中山玻璃钢卡通雕塑厂家地址本溪玻璃钢雕塑制作厂家广东大型商场美陈销售公司大型商场美陈研发公司玻璃钢雕塑商家编码怎么写哈尔滨仿铜玻璃钢雕塑制作贵州泡沫玻璃钢雕塑邳州五一商场美陈亳州制作玻璃钢雕塑公司报价商场美陈工程清单香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万