Search code examples
verilogsynthesisregister-transfer-level

D-flip flop with 2 reset: synthesis error


I'm doing a synthesis of a digital block and I need a D-Flip-Flop with 2 asynchronous resets. The reason is that I will drive one reset with an available clock, and I will use the second one to reset all the registers of my digital block. I prepared the following code:

module dff_2rst(q,qn,clk,d, rst,clear);
    input  clk,d, rst, clear ;
    output q,qn;
    reg q,qn;

    always @(posedge clk or posedge rst or posedge clear)    //asynchronous reset    
    begin 
    (* full_case, parallel_case *)  
    case({rst, clear})  
        2'b00: begin 
                q <= d; 
                qn<=~d;
               end
        default: begin     
                    q <= 1'b0;  
                    qn <=1'b1;
                end 
    endcase
    end                     
endmodule     

But I get the following error:

The statements in this 'always' block are outside the scope of the synthesis policy. Only an 'if' statement is allowed at the top level in this always block. (ELAB-302)
*** Presto compilation terminated with 1 errors. ***

I also tried with

if(~rst & ~clear)

but I have errors too.

Do you have an idea to correct my code?


Solution

  • The standard way to write a async reset, set (clear) flip-flop in Verilog RTL is:

    always @(posedge clk or posedge rst or posedge clear) begin
      if (rst) begin
        // Aysnc Reset
        q <= 'b0 ;
      end
      else if (clear) begin
        // Async Clear 
        q <= 'b0 ;
      end
      else begin
        // Sync logic here
        q <= d;
      end
    end
    
    assign qn = ~n;
    

    The little trick for qn requires it to be a wire, currently defined as a reg. reg q,qn; should just be reg q;

    Also for cleaner code a new header type is cleaner and avoids repetition:

    module dff_2rst(
        input      clk,
        input      d,
        input      rst,
        input      clear,
        output reg q,
        output     qn );