在 Quartus 波形中捕获正确的姿势时钟

Capturing the right posedge clock in Quartus waveform

我正在使用 Quartus Prime Lite 19.1.0。

module memory_address_register1 #(
    parameter                       ADDR_WIDTH = 4
)(
    input                           clk, rst, load,
    input       [ADDR_WIDTH-1:0]    add_in,
    output reg     [ADDR_WIDTH-1:0]    add_out
);


    always @(posedge clk) begin
        if (rst) begin
            add_out <= 4'b0000;
        end else if (load) begin
            add_out <= add_in;
        end else begin
            add_out <= add_out;
        end
    end
    
endmodule

module mmr_tb();
    reg clk, rst, load;
    reg [3:0] add_in;
    wire [3:0] add_out;
    
    initial begin
        clk <= 1'b0;
        rst <= 1'b0;
        load <= 1'b0;
    end
    
    memory_address_register1 mmr (.clk(clk), .rst(rst), .load(load), .add_in(add_in), .add_out(add_out));
    
    always #10 clk = ~clk;
    
    initial begin
        #20 add_in <= 4'd2;
        #10 add_in <= 4'd3;
        load <= 1'b1;
        #30 add_in <= 4'd6;
        #10 load <= 1'b1;
        
    end

endmodule

它的输出(add_out)准确吗? t=70.0ns 时的输出 (add_out) 应该是“6”还是“7”?

  1. 如果预期输出为“6”,谁能解释这是为什么?

img2: posedge clk output value from previous clk cycle

我 运行 使用 modelsim 的测试台,我能够得到我想要的预期输出(在确切的时钟边沿输出),但这是预期的吗? https://imgur.com/a/M85zPKT

您的测试平台代码中存在潜在的竞争条件。您应该以与在设计中驱动它们相同的方式在测试台中驱动所有输入:

  1. 使用非阻塞赋值 (<=) 而不是阻塞赋值 (=)
  2. 使用 @(posedge clk) 而不是 # 延迟

这将保证您的输入与时钟同步。这也确保输入的脉冲宽度是时钟 period 的倍数。您的某些信号宽度为半个周期或 1.5 个周期。

module mmr_tb();
    reg clk, rst, load;
    reg [3:0] add_in;
    wire [3:0] add_out;
    
    initial begin
        clk    <= 0;
        rst    <= 1;
        load   <= 0;
        add_in <= 0;
        repeat (2) @(posedge clk);
        rst <= 0;
        forever @(posedge clk) begin
            add_in <= add_in + 1;
        end
    end
    
    memory_address_register1 mmr (.clk(clk), .rst(rst), .load(load), .add_in(add_in), .add_out(add_out));
    
    always #10 clk = ~clk;
    
    initial begin
        repeat (4) @(posedge clk); load <= ~load;
        repeat (1) @(posedge clk); load <= ~load;
        repeat (4) @(posedge clk); load <= ~load;
        repeat (1) @(posedge clk); load <= ~load;
        repeat (3) @(posedge clk); $finish;
    end
endmodule