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.
The simulator is probably doing something like this:
Since the clock event is occurring last in each time step from your testbench, it looks like the flop is being assigned immediately. You likely want your testbench to be entirely slaved off the clock so Marty’s suggestion of using @(posedge…) will achieve this. You could also simply delay your assignments once at the very beginning: