lab2当中主要练习ucli的使用,lab2的加法器结构框图如下图所示:
这次给的教程文件当中已经提前埋好了bug,教程所做的就是debug的全流程。
PartA和PartB分别用的是修改源文件和利用ucli的办法。
PartA
1. 首先进入总目录下的./lab2/parta当中,利用.f文件运行命令:
$ vcs –f adder.f -R
编译顺利通过,但是仿真的过程出现了报错:
***ERROR at time = 25750 ***
a = 01, b = 01, sum = 00; cin = 0, cout = 0
在这里应该得到sum=02 ,现在需要找到出错的原因在哪里。
2.Verilog system task call
verilog的task call(系统调用)可以放在RTL模块代码中也可以放在testbench当中,在实际的debug过程中,更好的选择是将task call放在testbench当中。愿意有二:
(1)testbench本来就是用来检验程序结果的,使用task call以后更容易设置断点。
(2)可以避免重复编译,省略资源和时间。
现在我们用more命令,查看addertb.v文件的内容:
$ more addertb.v
module addertb;
reg [7:0] a_test, b_test;
wire [7:0] sum_test;
reg cin_test;
wire cout_test;
reg [17:0] test;
add8 u1(a_test, b_test, cin_test, sum_test, cout_test); //DUT(Device Under Test)的例化
initial
if (!$test$plusargs("monitoroff")) //判定输入的命令当中是否有"monitoroff"字段
$monitor ($time, " %h + %h = %h; cin = %h, cout = %h",
a_test, b_test, sum_test, cin_test, cout_test);//若没有则开始监控过程
initial
begin
for (test = 0; test <= 18'h1ffff; test = test +1) begin
cin_test = test[16];
a_test = test[15:8];
b_test = test[7:0];
#50;
if ({cout_test, sum_test} !== (a_test + b_test + cin_test)) begin
$display("***ERROR at time = %0d ***", $time); //显示出错时的时间和数据信息
$display("a = %h, b = %h, sum = %h; cin = %h, cout = %h",
a_test, b_test, sum_test, cin_test, cout_test);
$finish; //检测到出错后结束仿真,相当于一个端点
end
#50;
end
$display("*** Testbench Successfully completed! ***");
$