掌握 Verilog 显示任务:高效调试与日志记录
显示系统任务主要用于输出信息和调试消息,跟踪仿真流程,加速调试。有不同组别的显示任务和打印格式。
显示/写入任务
语法
$display 和 $write 均按参数列表顺序显示参数。
$display(<list_of_arguments>); $write(<list_of_arguments>);
$write 不在字符串末尾追加换行符 \n,而 $display 会自动换行,如下例所示。
示例
module tb; initial begin $display ("This ends with a new line "); $write ("This does not,"); $write ("like this. To start new line, use newline char "); $display ("This always start on a new line !"); end endmodule
仿真日志
ncsim> run This ends with a new line This does not,like this. To start new line, use newline char Hi there ! ncsim: *W,RNQUIE: Simulation is complete.
Verilog 选通显示
$strobe 在当前增量时间步结束时打印变量最终值,格式类似 $display。
module tb; initial begin reg [7:0] a; reg [7:0] b; a = 8'h2D; b = 8'h2D; #10; b <= a + 1; $display ("[$display] time=%0t a=0x%0h b=0x%0h", $time, a, b); $strobe ("[$strobe] time=%0t a=0x%0h b=0x%0h", $time, a, b); #1; $display ("[$display] time=%0t a=0x%0h b=0x%0h", $time, a, b); $strobe ("[$strobe] time=%0t a=0x%0h b=0x%0h", $time, a, b); end endmodule
注意 $strobe 在 10ns 显示变量 b 的最终更新值 0x2E,而 $display 要在下一仿真增量 11ns 才捕获到。
仿真日志
ncsim> run [$display] time=10 a=0x2d b=0x2d [$strobe] time=10 a=0x2d b=0x2e [$display] time=11 a=0x2d b=0x2e [$strobe] time=11 a=0x2d b=0x2e ncsim: *W,RNQUIE: Simulation is complete. ncsim> exit
Verilog 持续监视
$monitor 自动打印参数列表中变量或表达式的值,每当其变化即输出,效果等同于每次参数更新后调用 $display。
module tb; initial begin reg [7:0] a; reg [7:0] b; a = 8'h2D; b = 8'h2D; #10; b <= a + 1; $monitor ("[$monitor] time=%0t a=0x%0h b=0x%0h", $time, a, b); #1 b <= 8'hA4; #5 b <= a - 8'h33; #10 b <= 8'h1; end endmodule
$monitor 如同在主线程后台生成的任务,监视并显示参数变量的值变化。仿真中可多次发起 $monitor 任务。
仿真日志
ncsim> run [$monitor] time=10 a=0x2d b=0x2e [$monitor] time=11 a=0x2d b=0xa4 [$monitor] time=16 a=0x2d b=0xfa [$monitor] time=26 a=0x2d b=0x1 ncsim: *W,RNQUIE: Simulation is complete.
Verilog 格式说明符
在显示函数中打印变量需为每个变量给出适当的格式说明符。
| 参数 | 描述 |
|---|---|
| %h, %H | 十六进制显示 |
| %d, %D | 十进制显示 |
| %b, %B | 二进制显示 |
| %m, %M | 显示层次名称 |
| %s, %S | 字符串显示 |
| %t, %T | 时间格式显示 |
| %f, %F | 实数十进制显示 |
| %e, %E | 实数指数格式显示 |
module tb; initial begin reg [7:0] a; reg [39:0] str = "Hello"; time cur_time; real float_pt; a = 8'h0E; float_pt = 3.142; $display ("a = %h", a); $display ("a = %d", a); $display ("a = %b", a); $display ("str = %s", str); #200 cur_time = $time; $display ("time = %t", cur_time); $display ("float_pt = %f", float_pt); $display ("float_pt = %e", float_pt); end endmodule
仿真日志
ncsim> run a = 0e a = 14 a = 00001110 str = Hello time = 200 float_pt = 3.142000 float_pt = 3.142000e+00 ncsim: *W,RNQUIE: Simulation is complete.
Verilog 转义序列
某些字符因代表其他显示用途(如换行、制表、换页)而被视为特殊字符。要打印这些特殊字符,每次出现都必须转义。
| 参数 | 描述 |
|---|---|
| \n | 换行符 |
| \t | 制表符 |
| \\ | 反斜杠字符 |
| \" | 双引号字符 |
| %% | 百分号字符 |
module tb; initial begin $write ("Newline character \n"); $display ("Tab character \tstop"); $display ("Escaping \" %%"); /* // 编译错误 $display ("Without escaping \n"); // ERROR: Unterminated string $display ("Without escaping \""); // ERROR: Unterminated string */ end endmodule
仿真日志
ncsim> run Newline character Tab character stop Escaping " % ncsim: *W,RNQUIE: Simulation is complete.
Verilog
- Verilog 入门:数字电路设计完整教程
- 掌握 Verilog 拼接操作:实用指南
- 深入理解 Verilog 赋值语句:类型、语法与最佳实践
- Verilog阻塞与非阻塞赋值:关键区别详解
- 掌握Verilog函数:高效RTL设计的复用利器
- 理解Verilog任务:函数vs任务、语法与用法全解析
- Verilog `ifdef 条件编译详解:宏控制代码包含与排除
- 掌握 Verilog 层次引用作用域:避免模块与块中的名称冲突
- Verilog 时钟发生器设计与实现指南
- 掌握 Verilog 显示任务:高效调试与日志记录
- 掌握 Verilog 数学函数:高效硬件设计的利器
- 掌握 Verilog $timeformat:精度控制与显示格式化