As I have known, D flipflop samples its input value at every positive edge of the clock.
Thus, it will produce a 1 cycle delay. Right?
But why does my D flip flop does not produce a 1 cycle delay?
module flipflop(
input clk,
input rstn,
input [7:0] i_data,
output reg [7:0] o_data
);
always @(posedge clk) begin
if (~rstn) begin
o_data <= 0;
end
else begin
o_data <= i_data;
end
end
endmodule
module test;
reg clk;
reg [7:0] i_data;
reg rstn;
wire [7:0] o_data;
initial begin
clk = 0;
rstn = 1;
i_data = 0;
#20;
rstn = 0;
#30;
rstn = 1;
#20;
i_data = 8'hFA;
#20;
i_data = 8'hF0;
#20
i_data = 8'hF1;
#20
#10 $finish;
end
always #10 clk = !clk;
flipflop flipflop(
.clk (clk),
.rstn(rstn),
.i_data(i_data),
.o_data(o_data)
);
initial begin
$dumpfile("flipflop.vcd");
$dumpvars();
end
endmodule
My D flip flop functions like a combinational circuit here.
You've run up against Verilog simulator event scheduling subtleties! Changing the data assignments to use nonblocking assignments is probably the easiest fix.
#20;
i_data <= 8'hFA;
#20;
i_data <= 8'hF0;
#20
i_data <= 8'hF1;
#20
What was happening in your original version is that the clock and the input data were scheduled to happen at the same time. Since the simulator can only do one thing at a time, it has to decide if it will change the clock or the data first. It changed the data first, so when the clock edge comes along, the input data has already changed to the next value so it looks like the data is slipping through the FF.
Nonblocking assignments (<=
) are scheduled to happen after all the blocking assignments (=
) have been done. So making the data assignments nonblocking ensures that they happen after the blocking-assigned clock edges.
Another way to rewrite things to work would be:
initial begin
@(posedge clk) i_data = 8'hFA;
@(posedge clk) i_data = 8'hF0;
@(posedge clk) i_data = 8'hF1;
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With