UVM学习之路(6)— QuestaSim的调试方法
一、前言
在使用仿真器的过程中会涉及到库窗口、仿真窗口和过程窗口,他们将与硬件、模型 和在线运行的进程一一对应。
二、库窗口
所有编译成功的硬件(module、interface、program)和软件(class、package)都可以被放入库中,如果不指定放入的位置,他们会被放入默认的work库中。如下所示,是QuestaSim的库窗口;

三、仿真窗口
仿真窗口(sim window)代表目前正在进行的仿真结构,一般在验证环境中,应该包含硬件测试的结构组件和待测设计(DUT)。如下所示,是QuestaSim的仿真(sim)窗口,我们可以看到除了有我们自己编写后被编译出来的库,还有被默认引入的标准库;
不过需要注意的是,仿真窗口只能提供静态的 层次结构,即由module、program、interface和package的内容,但是对于class的例化实例这种在验证环境中十分重要的动态软件内容,则需要在类窗口(class window)和对象窗口(object window)中查看。
四、过程窗口
过程窗口(process window)代表着整个仿真在某一个时间点上所有过程语句块(initial、always、assign)的状态。如下所示,是QuestaSim的过程窗口;
如果状态为
active
,代表该进程块正在执行,如果是
ready
状态,代表该进程块是非活跃状态。
五、查看信号和波形
我们在启动仿真后仿真器会自动打开波形(Wave)窗口,如下所示
然后我们就可以在仿真窗口或者信号窗口(objects window)中选中需要的信号添加到波形窗口处,如下所示,选中要添加的波形,右键点击【Add Wave】即可
这样我们点击运行后即可在Wave窗口中看到波形了
另外,在命令窗口(transcript window)使用命令
log -r/*
在开始仿真前调用,可以确保TB层次下所有信号都可以保存到数据库以供查看任何信号的波形。
六、测量时钟
在Wave窗口中点击绿色+号的【Insert cursor】图标,添加一个时间轴
然后我们移动时间轴,可以看到两个时间轴之间的时间间隔
接着格式设置图标,
将【Show frequency in cursor delta】勾选上
我们就可以看到,之前的时间间隔变成了频率格式
七、设置断点
设置断点可以便于查看软件程序(function、task、object)中局部变量的数值。因为软件部分的变量(即动态变量dynamic variable)是无法添加到波形窗口的,所以软件部分的变量我们需要通过设置断点的方法来查看。编写代码如下所示
module breakpoint1;
int val1;
int val2;
int result;
function int incr_static(input int a);
result = a + 1;
return result;
endfunction
function automatic int incr_dynamic(input int a);
int result;
result = a + 1;
return result;
endfunction
initial begin
val1 = 0;
val1 = incr_static(val1);
val1 = incr_static(val1); // breakpoint line8 result == ?
end
initial begin
val2 = 0;
val2 = incr_dynamic(val2);
val2 = incr_dynamic(val2); // breakpoint line14 result == ?
end
endmodule
编译仿真运行,然后在仿真窗口双击模块名称
我们就可以看到代码窗口打开了,并在模块声明行出现了 一个小旗子
接着在代码窗口左边的行号上点击一下即可设置一个断点了
然后我们点击【Run -All】图标,或者输入
run -all
命令,让代码运行到14行断点处
然后我们可以在【Locals】窗口中看到动态变量的值
八、强制修改信号
编写代码如下所示,
module simstart1;
logic a1=0;
logic a2, a3, a4, a5;
bit rstn, clk;
assign a2 = a1; // assign
initial begin // initial
a3 = a1;
end
always @(posedge clk, negedge rstn) begin // sequential logic
if(rstn === 'b0) a4 <= 0;
else a4 <= a1;
end
always @(a1) begin // combination logic
a5 <= a1;
end
initial begin
#10ns rstn <= 0;
#20ns rstn <= 1;
end
initial forever #5ns clk <= !clk;
endmodule
在第19行设置断点,仿真运行100ns,会发现我们无法运行到断点处,这是因为仿真过程中a1的值一直没有改变
我们在【Objects】窗口中选中
a1
,右键选择【Modify】->【Force…】以强行修改a1的值
编辑如下所示,将要修改为的值输入
1'h1
,延时等待时间输入
10ns
,点击OK保存
然后输入命令
run 20ns
运行20ns,可以看到,在10ns时运行到断点处停下来了
但是此时
a5
并没有变化
我们在输入
run 0
命令让仿真再运行一个时间片,可以看到,a5的值 已经变成
1'h1
了,然后运行箭头也离开了19行