I ran into a problem that buffer in my simulation does not work as I expected. I tried some test and got the following results. I created code in Verilog that generates two buffers in different ways:
module buffer(
input wire clk,
input wire ena,
output wire buffer,
output wire buffer2
);
reg buffer_reg = 1'b0;
reg buffer_next = 1'b0;
reg buffer2_reg = 1'b0;
assign buffer = buffer_reg;
assign buffer2 = buffer2_reg;
always @(*) begin
buffer_next = ena;
end
always @(posedge clk) begin
buffer_reg <= buffer_next;
buffer2_reg <= ena;
end
endmodule
Then I simulate it in Modelsim with the following testbench:
`timescale 1ns / 1ns
module buffer_tb();
localparam CLK_CYCLE = 8;
reg clk;
reg ena;
wire buffer;
wire buffer2;
buffer dut(
.clk(clk),
.ena(ena),
.buffer(buffer),
.buffer2(buffer2)
);
// Clock generation
initial begin
clk = 1'b0;
end
always #(CLK_CYCLE/2) clk = ~clk;
// Test sequence
initial begin
// Initialize signals
ena = 0;
// change ena values based on the posedge clk
@(posedge clk) ena = 1;
@(posedge clk) ena = 0;
repeat(5) @(posedge clk);
@(posedge clk) ena = 1;
@(posedge clk) ena = 0;
repeat(2) #CLK_CYCLE;
// change ena values based on the CLK_CYCLE
#(CLK_CYCLE) ena = 1;
#CLK_CYCLE ena = 0;
repeat(5) #CLK_CYCLE;
#CLK_CYCLE ena = 1;
#CLK_CYCLE ena = 0;
// Allow simulation to run for a while
#50 $stop; // Stop simulation
end
endmodule
and I get the following result in the simulation:
Can someone explain why I get different results for buffer2
when I use posedge clk
and when I use CLK_CYCLE
?
The problem is due to a Verilog simulation race condition in the testbench code.
If you want to model synchronous behavior, you need to drive the design input signals in the same way that you drive the buffer
signals in the design, namely:
@(posedge clk)
<=
)Change the testbench code:
initial begin
// Initialize signals
ena = 0;
// change ena values based on the posedge clk
@(posedge clk) ena <= 1;
@(posedge clk) ena <= 0;
repeat(5) @(posedge clk);
@(posedge clk) ena <= 1;
@(posedge clk) ena <= 0;
repeat(5) @(posedge clk);
@(posedge clk) ena <= 1;
@(posedge clk) ena <= 0;