【问题标题】:Trouble understanding simulation/module behavior无法理解模拟/模块行为
【发布时间】:2022-01-21 16:40:59
【问题描述】:

我用预设功能实现了一个非常简单的计数器(代码复制如下)。

module counter
#(
    parameter mod = 4
) (
    input wire clk,
    input wire rst,
    input wire pst,
    input wire en,
    input wire [mod - 1:0] data,
    output reg [mod - 1:0] out,
    output reg rco
);

    parameter max = (2 ** mod) - 1;

    always @* begin
        if(out == max) begin
            rco = 1;
        end else begin
            rco = 0;
        end
    end

    always @(posedge clk) begin
        if(rst) begin
            out <= 0;
        end else if(pst) begin
            out <= data;
        end else if(en) begin
            out <= out + 1;
        end else begin
            out <= out;
        end
    end

endmodule

我无法理解以下模拟结果。在时钟上升沿断言pstdata 设置为7 时,计数器的out 设置为data,正如预期的那样(下面的第一张图片。out 是最后一个信号,data 是信号就在上面,上面是pst.)。在下一个上升沿,我保持预设置位并将data 设置为0。但是,out 这次没有跟随data。这种行为的原因是什么?

我的想法

在我将data 设置为0 的时钟上升沿,我注意到out 保持在7,并且不会增加到8。所以我相信计数器正在预设,但值为7,不是 0。如果我及时将 data 转换从 7 移动到 0,out 会按预期设置为 0(下图)。我遇到了竞态条件吗?

测试台

我生成第一张图片的初始测试台代码如下所示。我以 cmets 的形式展示了我为获得连贯结果所做的更改。

parameter mod = 4;
// ...
reg pst;
reg [mod - 1:0] data;
// ...
@(posedge clk); // ==> @(negedge clk)
data = 7;
pst = 1;
@(posedge clk); // ==> @(negedge clk)
data 0;
pst = 1;
@(posedge clk); // ==> @(negedge clk)
pst = 0;
@(posedge clk);
// ...

【问题讨论】:

  • 显然在第二个时钟沿 data 仍然是 7 并且仅在 时钟沿之后变为 0。
  • @mkrieger1 看起来确实如此。但是,为什么第一个预设周期在时钟上升沿看到data 为 7 而不是 0(在那之前data 为 0)?
  • 因为在第一个时钟边沿 data 显然已经是 7。
  • @mkrieger1 我试图理解为什么从一个时钟沿到下一个时钟沿的行为不同。在我的测试平台中,我只是这样做:data = 7; @(posedge clk); data = 0; @(posedge clk) 来获取第一张图片。
  • 好的。我不知道它为什么会这样。

标签: verilog


【解决方案1】:

您有一个比赛条件测试台。允许 Verilog 调度程序以它选择的任何顺序评估在时间步中触发的任何@。授予@ 之后的所有代码都将执行,直到遇到另一个时间阻塞语句。在您的波形中,来自测试台的datapst 有时是在设计采样之前分配的,有时是在之后分配的。

解决方案很简单,使用非阻塞赋值 (&lt;=)。参考What is the difference between = and <= in Verilog?

@(posedge clk);
data <= 7;
pst <= 1;
@(posedge clk);
data <= 0;
pst <= 1;
@(posedge clk);
pst <= 0;
@(posedge clk);

【讨论】:

    【解决方案2】:

    如果我修改我的测试台以仅在时钟下降沿而不是在时钟上升沿修改输入信号到我的计数器,我能够获得正确、可预测的行为(无论如何都应该如此)。关于为什么会发生上述行为,我的最佳猜测是,在对计数器模块进行编程以对其输入进行采样的同时更改输入信号会导致未定义的模拟器行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-02
      • 1970-01-01
      相关资源
      最近更新 更多