在 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”?
- 如果预期输出为“6”,谁能解释这是为什么?
img2: posedge clk output value from previous clk cycle
我 运行 使用 modelsim 的测试台,我能够得到我想要的预期输出(在确切的时钟边沿输出),但这是预期的吗?
https://imgur.com/a/M85zPKT
您的测试平台代码中存在潜在的竞争条件。您应该以与在设计中驱动它们相同的方式在测试台中驱动所有输入:
- 使用非阻塞赋值 (
<=
) 而不是阻塞赋值 (=
)
- 使用
@(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
我正在使用 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”?
- 如果预期输出为“6”,谁能解释这是为什么?
img2: posedge clk output value from previous clk cycle
我 运行 使用 modelsim 的测试台,我能够得到我想要的预期输出(在确切的时钟边沿输出),但这是预期的吗? https://imgur.com/a/M85zPKT
您的测试平台代码中存在潜在的竞争条件。您应该以与在设计中驱动它们相同的方式在测试台中驱动所有输入:
- 使用非阻塞赋值 (
<=
) 而不是阻塞赋值 (=
) - 使用
@(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