Hello,I'm looking for the proper way to constrain an asynchronous reset path, with a reset synchronizer. The Quartus Standard (and Pro) handbook touches this subject but barely, in the recommended practices ("Use Synchronized Asynchronous Reset" page 11-26 or 826 in version 2016.05.03). Wherever I looked, there was only a mention of a set_false_path on the async reset, but in order to avoid metastability, the reset should also be released in a synchronous fashion (hence the resynchronizer). And for this to succeed, there should be a constrain to make sure the output, resynchronized reset (rst_n on the attached figure) is not violating the setup/hold time of the registers that are reset (reg1, reg2), correct? So on the schematic in attachment, or the code below, - reset_n is coming from an uncontrolled environment and its timing is unknown - the path between reg3 and reg4 should be as short as possible, perhaps a min delay constraint must be added to maximize the recovery time before the setup of reg4 in case of metastability - reg4's output should be stable when reset_n is released, and outputs a '1' synchronously to release the aclrn of the system registers reg1 and reg2 If there is no constraint, and I try to analyze the timing in TimeQuest, I see that the rst_n path is not producing any output, so this tool disregard any timing violation on the asynchronous reset of the system registers. Has anyone faced the same problem, and found a good solution? A set_false_path on those paths seems a little careless in my opinion. I'm quoting the Verilog code and the constraints given as example in the handbook:
module sync_async_reset ( input clock, input reset_n, input data_a, input data_b, output out_a, output out_b ); reg reg1, reg2; reg reg3, reg4; assign out_a = reg1; assign out_b = reg2; assign rst_n = reg4; always @ (posedge clock, negedge reset_n) begin if (!reset_n) begin reg3 <= 1’b0; reg4 <= 1’b0; end else begin reg3 <= 1’b1; reg4 <= reg3; end end always @ (posedge clock, negedge rst_n) begin if (!rst_n) begin reg1 <= 1’b0; reg2 <= 1;b0; end else begin reg1 <= data_a; reg2 <= data_b; end end endmodule // sync_async_reset To minimize the metastability eﬀect between the two synchronization registers, and to increase the MTBF, the registers should be located as close as possible in the device to minimize routing delay. If possible, locate the registers in the same logic array block (LAB). Te input reset signal (reset_n) must be excluded with a set_false_path command: set_false_path -from -to
Thats pretty much how Ive seen it done in several altera projects. I think you can leave the false path out, as the tool should be analysing for recovery and removal violations on rst_n, as it should see that rst_n is a synchronised async reset (basically similar to setup and hold violations for registers).If the fanout of rst_n gets large, you may need to force it into a ALTCLKCTRL to ensure it's on a global net, but bare in mind there are not many of these so with lots of clocks in the design these may be limited.
Just to add - remember that all of the registers in Altera fabric have asynchronous resets on the regsiters, which is why this is the recommended way to do a reset. Synchronous resets are only emulated, unlike xilinx where all resets are synchronous.Another tip is to only reset those that need it rather than all of them, as this can help the fanout and reduce routing resources.
Thanks for your answers, Tricky!--- Quote Start --- Just to add - remember that all of the registers in Altera fabric have asynchronous resets on the regsiters, which is why this is the recommended way to do a reset. Synchronous resets are only emulated, unlike xilinx where all resets are synchronous. Another tip is to only reset those that need it rather than all of them, as this can help the fanout and reduce routing resources. --- Quote End --- Actually that depends on the device and is not always entirely clear in Altera's documentation. For example, the Arria 10 is supposed to have both synchronous and asynchronous resets on its registers. The number of CC resources is much higher when using synchronous reset, but that's due to the local routing, apparently. So while the asynchronous reset will take one additional global routing (when the fanout justifies it), it relieves the non-global routing a lot, especially when resetting all registers. Same for the older Stratix 5, although the documentation states "The ALM directly supports an asynchronous clear function" and a few lines below, also specifies that each register has synchronous/asynchronous clear signals.