深入浅出玩转FPGA学习11----Testbench书写技巧2
结构化Testbench
Testbench也是能够做到可重用化的设计。下面用模块做一个结构化可重用的示例。
这是假设的待验证模块的顶层:
module prj_top(clk,rst_n,dsp_addr,dsp_data,dsp_rw···);
input clk;
input rst_n;
input [23:0] dsp_addr;
input dsp_rw;
inout [15:0] dsp_data;
···
···
endmodule
这是Testbench的顶层:
module tf_prj_top;
//这个例化适用于被例化文件(这里是print_task.v)不对待验证模块接口进行控制
//print_task.v里包含常用信息打印任务封装
print_task print();
//这个例化适用于被例化文件需要对待验证模块接口进行控制,和通常RTL设计中例化方法是一样的
//sys_ctrl_task.v里包含系统时钟产生的单元和系统复位任务
sys_ctrl_task sys_ctrl(
.clk(clk),
.rst_n(rst_n)
);
//dsp_ctrl_task.v包含DSP读/写控制模拟
dsp_ctrl_task dsp_ctrl(
.dsp_rw(dsp_rw),
.dsp_addr(dsp_addr),
.dsp_data(dsp_data).
···
);
//这里的端口例化需要注意的是,原来被测试模块的output为reg,如果被底层的例化模块控制,
//那么这个reg要改为wire类型进行定义,而底层模块要将其定义为reg
wire clk;
wire rst_n;
wire [23:0] dsp_addr;
wire dsp_rw;
wire [15:0] dsp_data;
···
//例化待验证工程顶层
prj_top uut(
.clk(clk),
.rst_n(rst_n),
.dsp_addr(dsp_addr),
.dsp_data(dsp_data),
.dsp_rw(dsp_rw),
···
);
//注意下面调用底层模块的任务的方式,例如sys_ctrl表示上面例化的sys_ctrl_task.v,sys_reset
//是例化文件中的一个任务,用"."做分割
initial begin
sys_ctrl.sys_reset(32'd1000); //系统复位1000ns
#1000;
dsp_ctrl.task_dsp_write(SELECT_STRB0,24'000001,16'h00ff); //DSP写任务调用
#1000;
dsp_ctrl.task_dsp_read(SELECT_STRB0,24'h000008,dsp_rd_data); //DSP读任务调用
...
print.termina

本文介绍了FPGA Testbench的结构化设计,通过示例展示了如何创建可重用的Testbench模块。同时,讨论了在并发执行中可能出现的读/写紊乱状态,并提供了解决方案,强调了使用非阻塞赋值避免任务冲突的重要性。此外,还展示了如何在任务调用中防止同时执行,确保Testbench的正确执行。
最低0.47元/天 解锁文章

723

被折叠的 条评论
为什么被折叠?



