Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my D Flip Flop not waiting for the positive edge of the clock?

Tags:

verilog

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

dff no delay

My D flip flop functions like a combinational circuit here.

like image 312
e19293001 Avatar asked Jul 26 '12 15:07

e19293001


1 Answers

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
like image 133
Marty Avatar answered Sep 24 '22 20:09

Marty