测试平台:无法监控内部模块的寄存器输出

问题描述 投票:0回答:1

我学习 Verilog 有一段时间了,但在测试我创建的模块(它是一个 4 位计数器)时遇到了麻烦。
这是我的代码:

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
    end

endmodule

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        $monitor("%t |clk = %d |output = %d",$time,clk,out);

        repeat(35) #50 clk = ~clk;

    end

endmodule

当我模拟这个时,除了 0 之外的所有值我都会在“out”上得到 X。如下图所示。

enter image description here

有趣的是,如果我将“$monitor”部分移到内部模块中,我将得到我想要的值。修改后的代码将是这样的:

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
        $monitor("%t |clk = %d |output = %d",$time,clk,o);
    end

endmodule

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        

        repeat(35) #50 clk = ~clk;

    end

endmodule

但是,如果我在外部模块中添加一个“out”的波形,它又会是X。

请告诉我问题出在哪里。

第一个代码:

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
    end

endmodule

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        $monitor("%t |clk = %d |output = %d",$time,clk,out);

        repeat(35) #50 clk = ~clk;

    end

endmodule

结果:

enter image description here

第二个代码:

module Counter4bit(input clk,rst,load, input[3:0] parallel_input,
 output reg[3:0] o);

    always @(posedge clk, posedge rst) begin
        if(rst) begin
            o <= 4'b0000;
        end
        else if(load)   o <= parallel_input;
        else begin
            o <= o + 4'b0001;
        end
        $monitor("%t |clk = %d |output = %d",$time,clk,o);
    end

endmodule

module CT4TB;

    reg[3:0] Pinp = 4'b0000;
    wire[3:0] out = 4'b0000;
    reg rst=0;
    reg ld=0;
    reg clk=0;

    Counter4bit ct(clk,rst,ld,Pinp,out);

    initial begin
        #15 rst = 1;
        #15 rst = 0;
        

        repeat(35) #50 clk = ~clk;

    end

endmodule

结果:

enter image description here

verilog system-verilog test-bench
1个回答
0
投票

有一些问题。

您的“输出”始终显示为 X 或 0,因为您在测试平台模块中存在争用。

out
信号有多个驱动器:

  1. wire
    声明连续将其赋值为0。
  2. 模块实例连接通过实例输出端口持续驱动它
    o

o
为0时,与
wire
值(0)匹配。这就是为什么您看到输出=0。当
o
是 0 以外的任何值(如 1、2 等)时,就会出现争用,并且您会看到输出=X。

要解决争用,请更改:

wire[3:0] out = 4'b0000;

至:

wire[3:0] out

使用

$monitor
并不是完成这项工作的最佳工具。它在每个时钟边沿都会发生变化,这通常没有多大意义。我建议删除
$monitor
行,并将此代码添加到测试台中:

always @(negedge clk) begin
    $display("%t |output = %d", $time, out);
end

我从显示屏上删除了

clk
信号。此代码将在每个时钟周期显示一次
out
信号。我选择
negedge
以避免竞争条件。

输出:

         130 |output =  1
         230 |output =  2
         330 |output =  3
         430 |output =  4
         530 |output =  5
         630 |output =  6
         730 |output =  7
         830 |output =  8
         930 |output =  9
        1030 |output = 10
        1130 |output = 11
        1230 |output = 12
        1330 |output = 13
        1430 |output = 14
        1530 |output = 15
        1630 |output =  0
        1730 |output =  1

虽然

$monitor
块中的
always
可以实现您想要的功能,但这不是一个好的做法。当您使用它时,您应该只在
$monitor
块中调用
initial
一次。

© www.soinside.com 2019 - 2024. All rights reserved.