verilog 中的 $display vs $strobe vs $monitor?
$display vs $strobe vs $monitor in verilog?
verilog中的$display vs $strobe vs $monitor有什么区别?每个在事件队列中何时应用,语句如何交互?任何陈述都可以抑制另一个吗?
我会很好地总结 LRM (Language Reference Manual), but you should read it. Everything is in IEEE Std 1800-2012 § 21.2 显示系统任务(从技术上讲是 SystemVerilog,但这些功能是相同的。)
$display
:打印立即数
- § 21.2.1 显示和写入任务
$strobe
:打印当前时间步结束时的值
- § 21.2.2 频闪监控
$monitor
:如果任何值发生变化,则打印当前时间步结束时的值。 $monitor
只能调用一次;顺序调用将覆盖前一个。
- § 21.2.3 持续监控
$write
:与 $display
相同,但不以换行符结尾 (\n
)
- § 21.2.1 显示和写入任务
示例:
reg [3:0] a,b;
integer i;
initial begin
$monitor("monitor a:%h b:%h @ %0t", a, b, $time);
for(i=0; i<4; i=i+1) begin
$strobe("strobe a:%h b:%h @ %0t", a, b, $time);
$display("display a:%h b:%h @ %0t", a, b, $time);
case(i)
0 : a = 4;
1 : b = 1;
2 : begin end // do nothing
3 : {a,b} = 9;
endcase
$display("display a:%h b:%h @ %0t", a, b, $time);
#1;
end
end
输出:(注意打印顺序,并且监视器在时间 2 时未显示)
display a:x b:x @ 0
display a:4 b:x @ 0
monitor a:4 b:x @ 0
strobe a:4 b:x @ 0
display a:4 b:x @ 1
display a:4 b:1 @ 1
monitor a:4 b:1 @ 1
strobe a:4 b:1 @ 1
display a:4 b:1 @ 2
display a:4 b:1 @ 2
strobe a:4 b:1 @ 2
display a:4 b:1 @ 3
display a:0 b:9 @ 3
monitor a:0 b:9 @ 3
strobe a:0 b:9 @ 3
Verilog/SystemVerilog 包含组织良好的事件队列。每个时间戳中的所有语句都根据这个队列执行。
- $display 在 ACTIVE 区域 中执行,所以如果有任何非阻塞赋值(在 INACTIVE 区域中执行),它不会被 $display 显示。
- $write 也在 ACTIVE 区域 中执行,但需要显式调用换行符 (\n) 才能插入另一行。这个系统任务一般用在用for循环显示多维数组的时候。
- $strobe在MONITOR/POSTPONE区域执行,也就是时间戳的末尾。因此更新后的值显示为 $strobe.
- $monitor 每次其显示参数之一发生变化时都会显示。每个模拟只能使用一个 $monitor。
看看这张图片:VERILOG EVENT REGIONS
示例代码位于:Display/Strobe/Monitor
希望这段代码能说明问题。
verilog中的$display vs $strobe vs $monitor有什么区别?每个在事件队列中何时应用,语句如何交互?任何陈述都可以抑制另一个吗?
我会很好地总结 LRM (Language Reference Manual), but you should read it. Everything is in IEEE Std 1800-2012 § 21.2 显示系统任务(从技术上讲是 SystemVerilog,但这些功能是相同的。)
$display
:打印立即数- § 21.2.1 显示和写入任务
$strobe
:打印当前时间步结束时的值- § 21.2.2 频闪监控
$monitor
:如果任何值发生变化,则打印当前时间步结束时的值。$monitor
只能调用一次;顺序调用将覆盖前一个。- § 21.2.3 持续监控
$write
:与$display
相同,但不以换行符结尾 (\n
)- § 21.2.1 显示和写入任务
示例:
reg [3:0] a,b;
integer i;
initial begin
$monitor("monitor a:%h b:%h @ %0t", a, b, $time);
for(i=0; i<4; i=i+1) begin
$strobe("strobe a:%h b:%h @ %0t", a, b, $time);
$display("display a:%h b:%h @ %0t", a, b, $time);
case(i)
0 : a = 4;
1 : b = 1;
2 : begin end // do nothing
3 : {a,b} = 9;
endcase
$display("display a:%h b:%h @ %0t", a, b, $time);
#1;
end
end
输出:(注意打印顺序,并且监视器在时间 2 时未显示)
display a:x b:x @ 0
display a:4 b:x @ 0
monitor a:4 b:x @ 0
strobe a:4 b:x @ 0
display a:4 b:x @ 1
display a:4 b:1 @ 1
monitor a:4 b:1 @ 1
strobe a:4 b:1 @ 1
display a:4 b:1 @ 2
display a:4 b:1 @ 2
strobe a:4 b:1 @ 2
display a:4 b:1 @ 3
display a:0 b:9 @ 3
monitor a:0 b:9 @ 3
strobe a:0 b:9 @ 3
Verilog/SystemVerilog 包含组织良好的事件队列。每个时间戳中的所有语句都根据这个队列执行。
- $display 在 ACTIVE 区域 中执行,所以如果有任何非阻塞赋值(在 INACTIVE 区域中执行),它不会被 $display 显示。
- $write 也在 ACTIVE 区域 中执行,但需要显式调用换行符 (\n) 才能插入另一行。这个系统任务一般用在用for循环显示多维数组的时候。
- $strobe在MONITOR/POSTPONE区域执行,也就是时间戳的末尾。因此更新后的值显示为 $strobe.
- $monitor 每次其显示参数之一发生变化时都会显示。每个模拟只能使用一个 $monitor。
看看这张图片:VERILOG EVENT REGIONS
示例代码位于:Display/Strobe/Monitor
希望这段代码能说明问题。