当前位置:网站首页>【深入浅出玩转FPGA学习13-----------测试用例设计1】
【深入浅出玩转FPGA学习13-----------测试用例设计1】
2022-07-31 00:00:00 【周猿猿】
模拟串口自收发通信
该Testbench是针对笔记16的串门通信实验设计的。串口通信实验设计中,CPLD将接收到的数据又发送出去。因此,在Testbench的用例设计中,使用了遍历测试和随机测试,对发送出去的数据和接收到的数据进行检测对比,最后测试者只要根据打印输出的信息即可判断源代码的设计是否符合要求。
详细的测试脚本如下:
'timescale 1ns/1ns
module tb_uart;
reg clk; //50MHZ主时钟频率
reg rst_n; //低电平复位信号
reg rs232_rx; //RS-232发送数据信号,FPGA接收
wire rs232_tx; //RS-232接收数据信号,FPGA发送
//例化被测工程my_uart_top
my_uart_top uut(
.clk(clk),
.rst_n(rst_n),
.rs232_rx(rs232_rx),
.rs232_tx(rs232_tx)
);
//-------------------------------------------------------------------------------------------------//
//FPGA输入时钟和复位产生
//-------------------------------------------------------------------------------------------------//
parameter PERIOD = 20; //时钟周期,单位ns
parameter RST_ING = 1'b0; //有效复位值,默认低电平复位
//时钟信号产生
initial begin
clk = 0;
forever
#( PERIOD/2) clk = ~clk;
end
//复位任务封装
task sys_reset;
input[31:0] reset_time; //复位时间输入,单位ns
begin
rst_n = RST_ING; //复位中
# reset_time; //复位时间
rst_n = ~ RST_ING; //撤销复位
end
endtask
//-----------------------------------------------------------------------------------------------------//
//常用信息打印任务封装
//-----------------------------------------------------------------------------------------------------//
//警告信息打印任务
task warning;
input[80*8:1] msg;
begin
$ write("WARNING at %t: %s", $time,msg);
end
endtask
//错误信息打印任务
task error;
input[80*8:1] msg;
begin
$ write ("ERROR at %t: %s", $time, msg);
end
endtask
//致命错误打印并停止仿真任务
task fatal;
input[80*8:1] msg;
begin
$write("FATAL at %t : %s", $time, msg);
$write("Simulation false\n");
$ stop;
end
endtask
//完成仿真任务
task terminate;
begin
%write("Simulation Successful\n");
%stop;
end
endtask
//--------------------------------------------------------------------------------------------//
//测试用例设计
//--------------------------------------------------------------------------------------------------//
/波特率参数
parameter BPS9600 =32'd104_167, //9600bps
BPS19200 = 32'd52_083, //19200bps
BPS38400 = 32'd26_041, //38400bps
BPS57600 = 32'd17_361, //57600bps
BPS115200 = 32'd8_681, //115200bps
integer tx_bps; //串口发送波特率设置,需要在接受前设置好
integer rx_bps; //串口接收波特率设置,需要在接收前设置好
reg[7:0] cnt; //发送数据计数器
reg[7:0] data_temp; //串口接收数据寄存器
reg rx_flag; //接收标志位,下降沿表示接收一个数据完成
reg tx_data; //随机发送数据寄存器
initial begin
sys_reset(500); //上电后进行500ns的复位
rs232_rx = 1'b1;
#1000; //1us延时
rx_bps = BPS9600; //串口接收波特率设置
tx_bps = BPS9600; //串口发送波特率设置
//遍历测试//
for(cnt =0; cnt < 255; cnt= cnt + 1)
begin
tx_task(cnt); //发送数据
@(nedge rx_flag); //等待接收到数据
if(data_temp == cnt)
$write("transmit: %d, receive: %d; ture\n", cnt, data_temp);
//自收发数据正确
else begin
$write("transmit: %d, receibe: %d; error\n", cnt, data_temp);
//自收发数据错误
error("false");
end
end
#10_000; //10us延时
//随机测试//
for(cnt =0; cnt<255; cnt = cnt+1) begin //顺序发送0~255
tx_data = {$random};
tx_task(tx_data); //发送随机数据
@(negedge rx_flag); //等待接收到数据
if(data_temp == tx_data)
$write("transmit : %d, receive: %d; ture\n", cnt, data_temp);
//自收发数据正确
else begin
$write(" transmit: %d, receive: %d; error\n", cnt, data_temp);
//自收发数据错误
error("false");
end
end
terminate;
end
//串口发送任务
task tx_task;
input[7:0] txdata; //发送数据输入
integer i;
begin
rs232_rx = 0; //起始位
#tx_bps;
for(i=0; i<8; i=i+1) begin //8位数据发送
rs232_rx = txdata[7-i];
# tx_bps;
end
rs232_rx = 1; //停止位
# tx_bps;
end
endtask
integer j;
//串口接收
always @ (posedge rs232_tx) begin //起始位检测
#(tx_bps/2);
if(rs232_tx == 0) begin
rx_flag = 1;
#tx_bps;
for (j=0; j<8;j=j+1) begin
data_temp[7-j] = rs232_tx;
#tx_bps;
end
rx_flag =0;
end
end
endmodule
图3.3和图3.4分别是该测试用例的打印信息窗口截图和波形截图。对于这两种不同的测试观测手段,虽然波形观测较直观,但是该用例中所有512个结果都通过肉眼来观测肯定让人看花眼,而且还很浪费时间。所以,在Testbench中加入自检测,通过打印窗口的信息来做观察就更加方便智能。
乘法器全覆盖测试
该测试脚本对乘法器设计实现全覆盖测试,即连续产生所有可能的2个16位无符号数组合作为输入。在输入被乘数后,启动乘法运算器,直到FPGA有效运算输出标志位done位置时,测试脚本将乘数、被乘数以及乘积保存到txt文本中,如图3.5所示,并且判断该输出是否正确,输出判断结果。在所有测试完毕后 ,测试脚本输出统计的测试错误数量。
详细的测试脚本如下:
'timescale 1ns/1ns
module vtf_muxtest;
reg clk; //芯片的时钟信号
reg rst_n;
//低电平复位、清零信号。定义为0表示芯片复位;定位为1表示复位信号无效
reg start;
//芯片使能信号。定义为0表示信号无效;定义为1表示芯片读入输入引脚得乘数和被乘数,并将乘积复位清零
reg[15:0] ain; //输入a(被乘数), 其数据位宽为16位
reg[15:0] bin; //输入b(乘数),其数据位宽为16位
wire[31:0] yout; //乘积输出,其数据位宽为32位
wire done; //芯片输出标志信号,定义为1表示乘法运算完成
mux16 uut(
.clk(clk),
.rst_n(rst_n),
.start(start),
.ain(ain),
.bin(bin),
.yout(yout),
.done(done)
);
initial begin
clk = 0;
forever
#10 clk = ~ clk; //产生50MHZ地时钟频率
end
integer i,j;
integer wrong_timer; //运算出错计数器
integer txt_file; //定义文件指针
initial begin
//信号初始化
start=1'b0;
ain = 16'd0;
bin =16'd0;
wrong_timer = 0;
//txt初始化
txt_file = $ fopen("txt_file.txt");
//上电复位
rst_n = 1'b0;
#1000;
rst_n = 1'b1;
#fdisplay(txt_file,"testbench is running!\n");
for(i=0;i<16'hffff;i=i+1) begin
for(j=0;j< 16'hffff;j=j+1) begin
mux_task(i, j);
end
end
$fdisplay(txt_file,"%d wrong!\n",wrong_timer);
$fdisplay(txt_file, "testbench is over!\n");
$stop;
end
reg[31:0] mux_resulet; //乘法输出结果寄存器
//乘法执行任务
task mux_task;
input[15:0] mux_a;
input[15:0] mux_b;
begin
ain = mux_a; //送乘数
bin = mux_ b; //送被乘数
@(posedge clk);
#2 start = 1; //启动乘法器
@(posedge done); //等待运算完成
@(posedge clk);
# 2 mux_result = yout; //读出运算结果
@(posedge clk);
#2 start = 0; //结束运算
@(posedge clk);
end
endtask
always @(posedge done) begin
@(posedge clk);
@(posedge clk); //等待运算结果锁存完成
$fdisplay(txt_file, "ain= %d,bin=%d, yout=%d\t", ain,bin,mux_result);
//打印运算结果
if(ain*bin==yout) $fdisplay(txt_file, "right\n"); //报告运算正确
else begin
$fdisplay(txt_file, "wrong\n"); /报告运算出错
wrong_timer = wrong_timer + 1; //出错计数
end
@(posedge clk);
end
endmodule
该测试用例较之于以往最大的不同是其自动化程度大大提高,不需要测试者对着一长串的波形进行观察,测试结果也可以被有效地记录下来.同时测试者也不用担心测试数据丢失。其实这个测试脚本还可以做得更灵活一些,比如在测试出错时让测试立即终止井报错,这样测试者可以立即和设计者(如果条件许可)沟通,便于设计者快速定位问题所在,无需等到所有测试完毕后再查错。
边栏推荐
猜你喜欢
随机推荐
Debezium error series 20: task failed to create new topic. Ensure that the task is authorized to create topics
How to solve types joiplay simulator does not support this game
A Brief Talk About MPI
Soft Exam Summary
Shell编程条件语句 test命令 整数值,字符串比较 逻辑测试 文件测试
In MySQL, the stored procedure cannot realize the problem of migrating and copying the data in the table
software development design process
【萌新解题】删除链表的倒数第 N 个结点
乌克兰外交部:乌已完成恢复粮食安全出口的必要准备
The first level must project independently
HCIP第十六天笔记
web漏洞之需要准备的工作
.NET Cross-Platform Application Development Hands-on Tutorial | Build a Kanban-style Todo App with Uno Platform
[SAM template question] P3975 [TJOI2015] string theory
mysql中关于存储过程无法实现迁移复制表中数据问题
Soft Exam Study Plan
Steven Giesel 最近发布了一个由5部分内容组成的系列,记录了他首次使用 Uno Platform 构建应用程序的经验。
jira是什么
Learn Scope from a Compilation Perspective!
二叉查找树的定义,查找,插入,删除