Verilog 输出比预期晚 1 个时钟周期

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

我想测试一个简单的 Verilog 模块,如果在 3 变量输入中找到最小项

1
2
3
5
,则输出
7

模块如下所示:

module modified_prime_detector(
  input [2:0] in,
  input clk,
  output reg out
);
  
  always @ (posedge clk)
  begin
    out <= (~in[2] && in[1] && ~in[0]) || (~in[2] && in[1] && in[0]) || (in[2] && ~in[1] && in[0]) || (in[2] && in[1] && in[0]);
   end
endmodule

我还开发了一个测试平台,以便使用 EDA Playground 运行我的模拟:

module modified_prime_detector_tb();
    reg [2:0] in;
    reg clk;
    wire out;

    modified_prime_detector uut (
        .clk(clk),
        .in(in),
        .out(out)
    );

    always #5 clk = ~clk;

    always @(posedge clk) begin
        if (in == 3'b111)
            in <= 3'b000;
        else
            in <= in + 1'b1;
    end
  
  always @ (posedge clk) begin
        $display("Time: %t, in: %b, out: %b", $time, in, out);
  end

    initial begin
        $dumpfile("dump.vcd");
        $dumpvars(1, modified_prime_detector_tb);
      
        clk = 0;
        in = 0;
      
        #5;
        #100;
        $finish;
    end

endmodule

基本上,我在每个时钟周期增加

in
的 3 位值。然后,我希望看到
out
的值设置为
1
,其值包括:
010
011
101
111

但是,我看到模块针对以下值输出

1
011
100
110
000
?我不知道为什么会这样。我认为这可能与模拟有关,因为波形是这样的:

输出似乎“右移”了一位,而且我的模块似乎没有为输入提供输出

000
。不幸的是,我不确定为什么会发生这种情况以及如何进一步调查这个问题。

可能是什么问题?

verilog register-transfer-level
1个回答
0
投票

输出没有问题,它是正确的,但你的直觉是错误的。在您的模块中,您正在使用非阻塞语句

<=
,这是非阻塞语句的标准行为,输出在一个时钟周期后发生。

如果您希望输出在输入到达时发生,那么您应该使用组合逻辑,将敏感度列表中的

posedge clk
替换为
in

always @ (in) begin
    out <= (~in[2] && in[1] && ~in[0]) || (~in[2] && in[1] && in[0]) || (in[2] && ~in[1] && in[0]) || (in[2] && in[1] && in[0]);
end


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