【FPGA 仿真和调试脚本】常用系统任务

发布时间 2023-04-17 14:28:38作者: AnchorX

一、显示任务$display和$write

系统显示任务$display和$write在仿真测试中是最为常用的信息显示方式。$display和$write任务最主要的区别在于,$display在一次输出后会自动换行,而$write则不会,他们的其他用法格式基本类似。

【语法结构】

【任务名】(“【可选字符串】+【格式】”,【信号1】,【信号2】,……)

 

【任务名】可以是$display,$displayb,$displayo,$displayh,$write,$writeb,$writeo或$writeh。

【格式】由“%”和格式字符组成,【信号】为进行显示的信号名,【信号】数量和【格式】数量必须对应。

若不指定显示【信号】的【格式】,则【信号】显示的格式将会是$display和$write默认为十进制,$displayb和$writeb默认为二进制,$displayo和$writeo默认为八进制,$displayh和$writeh默认为十六进制。

$display举例如下:

// 系统打印任务$display的使用
`timescale 1ns/1ns
module testbench_top();

reg [31:0] rval;

initial begin
    rval = 101;
    $display("rval = %h hex %d decimal", rval, rval);
    $display("rval = %0h hex %0d decimal", rval, rval);
    $display("rval = %o octal\nrval = %b bin", rval, rval);
    $display("rval has %c ascii character value", rval);
    $display("current scope is %m");
    $display("%s is ascii value for 101", 101);
    #101;
    $display("rval = %h hex %d decimal", rval, rval);
    $stop;
end
endmodule
# rval = 00000065 hex 101 decimal
# rval = 65 hex  101 decimal
# rval = 00000000145 octal
# rval = 00000000000000000000000001100101 bin
# rval has e ascii character value
# current scope is testbench_top
# e is ascii value for 101
# simulation time is       105

默认情况下,输出显示的数值所占字符个数由输出信号的数值类型和位宽决定。例如该例子中32位寄存器rval以16进制显示时,其最大值是FFFFFFFF,所以即便显示数值是65,但在显示时也会占用8个字符位。除了十进制显示时会默认将高位0以空格填充,其它进制都会将高位0显示出来。在%和格式字符之间可以添加数字0,来隐藏前置的0或空格,使得第一个非0数字顶格显示。

 

二、监视任务$monitor

系统监视任务$monitor可以在仿真测试脚本中实现对任何变量或表达式取值的监视和显示。$monitor和$display的语法结构与用法类似。

当$monitor任务中包含一个或多个监控信号并运行时,若参数列表中由任何的变量或表达式的值发生变化,所有参数列表中的信号值都将输出显示。同一时刻若有两个或多个参数发生变化,则合并一次输出显示。

$monitor任务在申明后默认开启,在其运行期间若调用系统任务$monitoroff则关闭$monitor,直到调用系统任务$monitoron后重新开启。

【语法结构】

【任务名】(“【可选字符串】+【格式】”,【信号1】,【信号2】,……)

// 监控每个时钟周期递增的4位计数器o_cnt

// 系统复位后,监控信号o_cnt的变化,输出最新数值和时间戳
initial begin
    @(posedge rst_n);
    $monitor("o_cnt is %d at %0dns", o_cnt, $time);
end

// 当o_cnt取值为6~12范围时,关闭监控
always @(posedge clk) begin
    if (o_cnt == 4'd5)  $monitoroff;
    else if (o_cnt == 4'd12) $monitoron;
end