Search code examples
verilogquartus

Prevent compiler from optimizing logic away


I'd like to generate a reset signal (active high) that will last for a short period of time. I achieved it by following code:

always @(posedge clk or negedge rst_n or posedge data) begin
  if(~rst_n | data)
    data <= 1'b0;
  else if(ena)
    data <= 1'b1;
  else
    data <= data;
end 

Which is synthesized to D flip-flop:

https://i.sstatic.net/ojqLy.png

My generated signal will be 1 only for time equal to propagation time through OR gate. Now I want to remove rst_n signal. But if I do that, I receive the following D flip-flop:

https://i.sstatic.net/PpcJH.png

In that case, my signal will never be high. The easiest way to solve that I came up with is to add 2 NOT gates between Q and CLR. Unfortunately, my software (Quartus II) will synthesize those two gates away.

tl;dr - how to remove rst_n so reset signal will be generated correctly?


Solution

  • Did you try using the "synthesis keep" tag for Quartus to insert buffers?

    http://quartushelp.altera.com/13.1/mergedProjects/hdl/vlog/vlog_file_dir_keep.htm

    try this:

    module test(clk,ena,data);
    input clk, ena;
    wire data_n /*synthesis keep*/;
    wire data_nn /*synthesis keep*/;
    output reg data;
    
    assign data_n = ~data; 
    assign data_nn = ~data_n; 
    
    always @(posedge clk or posedge data_nn) begin
      if(data_nn)
        data <= 1'b0;
      else if(ena)
        data <= 1'b1;
      else
        data <= data;
    end
    
    endmodule