Search code examples
verilogflip-flop

Correct way of modelling a Flip Flop


I was going through a document from Microsemi website (Actel HDL Code) and I found a few implementations of flip-flop (Synchronous, Asynchronous etc.).In all the cases the author has modelled the flip-flops with blocking statements.

I want to know are these implementations correct, because I have always used non blocking to model sequential logic? Am I missing something or is it just a way to model only flip flop and not a sequential circuit in general?

// Rising Edge Flip-Flop with Asynchronous Reset
module dff_async_rst (data, clk, reset, q);
  input data, clk, reset;
  output q;
  reg q;

   always @(posedge clk or negedge reset)
     if (~reset)
       q = 1'b0;
     else
       q = data;

   endmodule

//Rising Edge Flip-Flop with Synchronous Reset
module dff_sync_rst (data, clk, reset, q);
  input data, clk, reset;
  output q;
  reg q;

  always @ (posedge clk)
    if (~reset)
      q = 1'b0;
    else 
      q = data;

endmodule

NOTE : Blocking assignments used in always block to get a sequential logic


Solution

  • Flip-flops should be modelled with non-blocking (<=) as you previously thought.

    If your using any version of verilog after 1995 then your port declarations can be tidied up a little. NB I add begin ends for clarity and _n to designate active low signals.

    Rising Edge Flip-Flop with Asynchronous Reset

    module dff_async_rst (
      input  data,
      input  clk, 
      input  reset_n,
      output reg q    //SystemVerilog logic is preferred over reg
    );
    
    always @(posedge clk or negedge reset_n) begin
      if (~reset_n) begin
        q <= 1'b0;
      end
      else begin
        q <= data;
      end
    end
    
    endmodule
    

    Rising Edge Flip-Flop with Synchronous Reset

    module dff_sync_rst(
      input  data,
      input  clk, 
      input  reset_n,
      output reg q    //SystemVerilog logic is preferred over reg
    );
    
    
    always @(posedge clk) begin
      if (~reset_n) begin
        q <= 1'b0;
      end
      else begin
        q <= data;
      end
    end
    
    endmodule