在verilog中使用显示

Using display in verilog

我是 verilog 的新手,我知道它不是一种顺序语言。所以,我想问有没有什么方法可以在模块执行后显示结果?因为 display 应该总是在 initial 块内,所以我无法使用 display 进行调试。这是一个示例代码,可以更好地解释我的问题-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
module A(a,b,c);
    input a,b;
    output c;

    assign c=a&b;

    initial
      $display("%b",c);
endmodule

module testbench11;
   reg a,b;
   wire c;

   A a1(a,b,c);

   initial
      $monitor(,$time,"a=%b,b=%b,c=%b",a,b,c);

   initial
      begin
         #0 a=1'b0;b=1'b0;        
         #3 a=1'b0;b=1'b0;
         #3 a=1'b0;b=1'b0;
      end
endmodule

所以我想在每次实例之后显示 c 的结果,以检查我是否获得了所需的输出。在这种情况下,它似乎在最后显示结果,但在一些复杂的问题中,我想使用 display 进行调试,就像我在 C 中使用 printf 一样。在 verilog 中有什么方法可以做到这一点吗?


Because display should always be inside initial block and so there is no way I can use display for debugging purposes.

我不知道你是从哪里得到这个的,除了 assign 之外它几乎和所有东西都一样,因为它必须在一个块内使用,intialalways

使用它在模块内部进行调试:

1
2
3
4
5
6
7
8
9
module A(a,b,c);
  input  a,b;
  output c;

  assign c = a&b;

  always @*
    $display("%b",c);
endmodule

最好从顶层显示和检查,保持模块代码干净。在 testench 中使用 display 你可以这样做:

和模块里面的格式一样:

1
2
3
always @* begin
  $display("%b",c);
end

或者要知道你在每个刺激步骤之后显示:

1
2
3
4
5
6
7
8
9
10
initial begin
  #0 a=1'b0;b=1'b0;        
  #1 $display("%b",c);

  #3 a=1'b0;b=1'b0;
  #1 $display("%b",c);

  #3 a=1'b0;b=1'b0;
  #1 $display("%b",c);
end

Verilog/SystemVerilog 包含一个组织良好的事件队列。每个时间戳中的所有语句都根据该队列执行。以下是一些不同的显示系统任务。

  • $display 在 ACTIVE 区域执行,所以如果有任何非阻塞赋值(在 INACTIVE 区域执行),它不会被 $display 显示。这将显示单个输出行。

  • $write 也在 ACTIVE 区域中执行,但显式调用换行符(\\
    ) 需要插入另一行。当您想使用 for 循环显示多维数组时,通常使用此系统任务。这类似于显示,除了 (\\
    ) 字符。

  • $strobe 在 MONITOR/POSTPONED 区域执行,即在时间戳结束时。因此,更新后的值由 $strobe.

    显示

  • $monitor 每次显示参数之一更改时都会显示。每个模拟只使用一个 $monitor。 Monitor,顾名思义,持续监控信号,如果有任何信号值发生变化,就会执行。

对于您的代码,要在各个点显示,可以进行以下代码更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    initial
    #5 $display("%b",c);  // display after some arbitrary time.

    initial
    begin
    repeat(5)
    begin
     wait(c);
     $display("%b",c);  // display after   change in c 5 times.
    end
    end

    initial
    begin
    forever
    begin
     #1;
     $display("%b",c);  // display c at every timestamp
    end
    end

    always @(c)
    $display("%b",c);  // display after any change in c

    always @(a,b,c)
    $display("%b",c);  // display after any change in a or b or c

为了在每次更改时显示,$monitor 很有用。 $display 可以像上面那样使用,但这会使你的代码混乱。请记住,您的代码中必须只有一个 $monitor。 $display 中没有这样的限制。

这些只是其中的一些方法,还有许多其他方法可用。更多信息可以在这里找到
和这个链接。