I would like to delay an input signal by one complete clock cycle.
I have the code below which basically tries to change the signal at posedge of the clock.
However, the test bench shows that it doesn't always delay by 1 cycle.
In some cases, it changes at the same time the input signal changes.
Is there any way to solve this kind of problem?
module delay_one_cycle(
input clk,
input[3:0] original_signal,
output reg[3:0] delayed_signal
);
always @(posedge clk) begin
delayed_signal <= original_signal;
end
endmodule
module delay_one_cycle_tb();
reg clk;
reg[3:0] original_signal;
wire[3:0] delayed_signal;
delay_one_cycle doc_inst (clk, original_signal, delayed_signal);
// Initial setup
initial begin
clk = 0;
original_signal = 4'd9;
#5 original_signal = 4'd10;
#5 original_signal = 4'd11;
#4 original_signal = 4'd12;
#3 original_signal = 4'd13;
// finish the simulation
#5 $finish;
end
// clock
always begin
#1 clk = !clk;
end
endmodule
Here is the waveform:
The waveform shows, for example, when input signal changes on the clock edge to 1010, output also changes at the same time.
the delayed_signal is not actually delayed to next cycle!
This question is quite similar to your question Why is my D Flip Flop not waiting for the positive edge of the clock?
You might want to try this convention to avoid race condition:
@(posedge clk);
Try to avoid setting input signals to your RTL code with blocking assignments. Use non-blocking assignment instead as what @Morten Zilmer suggests.
Your test bench should somehow look something like this:
module delay_one_cycle(
input clk,
input[3:0] original_signal,
output reg[3:0] delayed_signal
);
always @(posedge clk) begin
delayed_signal <= original_signal;
end
endmodule
module delay_one_cycle_tb();
reg clk;
reg[3:0] original_signal;
wire[3:0] delayed_signal;
delay_one_cycle doc_inst (clk, original_signal, delayed_signal);
// Initial setup
initial begin
original_signal <= 4'd9;
repeat (5) @(posedge clk);
original_signal <= 4'd10;
repeat (5) @(posedge clk);
original_signal <= 4'd11;
repeat (4) @(posedge clk);
original_signal <= 4'd12;
repeat (3) @(posedge clk);
original_signal <= 4'd13;
// finish the simulation
repeat (5) @(posedge clk);
$finish;
end
initial begin
clk = 0;
forever begin
#1 clk = !clk;
end
end
endmodule
Hope that helps.