08-10-2017 05:16 AM
I have reset synchronizer in my top block (attached file).
In my project I have blocks which get 125_clk, and others 250_clk.
In addition I have srstn_sm block which its output is input for srstn input of many blocks (attached file).
The code for the srstn_sm block:
entity srstn_sm is generic( reset_duration_cc_g : positive := 10 ); port( clk : in std_logic; sft_srst_in : in std_logic; srstn : in std_logic; srstn_out : out std_logic ); -- Declarations end srstn_sm; architecture behave of srstn_sm is type sm_states is (IDLE, RST); signal sm_state : sm_states; signal srstn_cnt : natural range 0 to reset_duration_cc_g; begin srstn_sm_proc : process(clk) begin if (rising_edge(clk)) then if (srstn = '0') then srstn_out <= '0'; srstn_cnt <= 0; sm_state <= IDLE; else case sm_state is when IDLE => srstn_out <= '1'; if (sft_srst_in = '1') then srstn_out <= '0'; srstn_cnt <= srstn_cnt + 1; sm_state <= RST; end if; when RST => if (srstn_cnt = reset_duration_cc_g-1) then srstn_out <= '1'; srstn_cnt <= 0; sm_state <= IDLE; else srstn_cnt <= srstn_cnt + 1; end if; end case; end if; end if; end process srstn_sm_proc; end architecture behave;
According which clock should I syncronize the reset in my reset synchronizer?
Should I inesrt 125_clk/250_clk to the srstn_sm block?
How the requirement time is calculated in each case?
08-10-2017 05:55 AM
Hey @sarit8 According which clock should I syncronize the reset in my reset synchronizer?
As both clocks are in phase and one clock is an integer division of the other, you want to synchronize the reset to the slower clock, because every rising edge on the slow clock will also be a rising edge on the fast one.
Hope that helps,
08-10-2017 06:04 AM
Thanks, that's what I though.
But the big question is what if this reset (which is syncronized by 125_clk) is an input for block which gets 250_clk.
It the requirement time will be 4ns or 8ns?
Should I handle this in a special way (multicycle_path or something else...)?
08-10-2017 07:04 AM
@sarit8 Should I handle this in a special way (multicycle_path or something else...)?
I don't think this requires any special handling ... it should just work fine.
But maybe somebody else has more insight here ...
08-14-2017 08:07 PM
So, first, make sure that your reset is properly synchronized. To do this, you need a synchronizer. If you are planning to use the output of the synchronizer to drive the asynchronous preset/clear input of flip-flops (an "asynchronous" global reset), then you should use a reset bridge. If you are planning on using the set/reset pins (a "synchronous" global reset), then you can use either the reset bridge or a conventional 2 stage (or more) flip-flop synchronizer. In either case, you need to set the ASYNC_REG property on the flip-flops in the synchronizer chain.
Second, we need to be sure that clk125 and clk250 are truly synchronous and in phase. The most common case for this is that they are both outputs of the same PLL/MMCM and they both drive the same kind of buffer (either both BUFG or both BUFH).
Next, you have to realize that a global reset can put a significant strain on your design - all the flip-flops in a given domain (or set of domains) need to get the reset fed to them, and the propagation time of that signal from the output of the synchronizer to all flip-flops is a constrained static timing path - a synchronous path. This is true regardless of whether you use a synchronous or (confusingly named) asynchronous reset methodology. Even if you are using the asynchronous preset/clear of your flip-flops, the deasserting edge of the reset must be synchronous to the clock.
So the reset fanout can often be the critical path in the design. It is for this reason that Xilinx suggests you not use a global reset methodology; the FPGA comes up in a known state, and for most of the design, this is sufficient in order to not have a global reset. However, there are caveats - any flip-flop that can change state spontaneously on the first clocks after the FPGA starts up needs an explicit reset - see this post on reset methodology.
So lets look at the consequence of having the synchronizer on each domain.
If the synchronizer is on clk125, then the path from the output of the synchronizer to the flip-flops on clk125 is 8ns. Furthermore the path from the output of the synchronizer to the flops on clk250 is 4ns - there is no way to make it more than this, and you cannot set a set_multicycle_path on this (this is really a 4ns path). So, on a given clock edge of clk125, reset will deassert. On the first clk250 edge after that (4ns later) all the flip-flops on clk250 will exit reset, and on the first clk125 edge after (which is 4ns later than the first clk250 edge) all the flops on clk125 will exit reset.
Now lets look at what happens if the synchronizer is on clk250. In this case, the path from the reset synchronizer to all the flip-flops (clk125 and clk250) are all 4ns. This is clearly worse. Furthermore, sometimes the clk125 flip-flops will exit reset at the same time as the ones on clk250 or 4ns later, depending on which clk250 edge the reset deasserts on. This too is clearly worse (having two possible behaviors is worse than one).
So lets assume the synchronizer is on clk125.The clk125 FFs have 8ns for reset, and the clk250 have 4ns.
But its a little more complicated than that. Even if clk125 and clk250 are properly generated (same MMCM/PLL, same buffers, there is more (in fact a fair bit more) clock skew between the two clocks then there is on a single clock domain. Clock skew within a single domain is generally around 200ps, so your clk125 reset path may actually be around 7.8ns. However, the skew between different clocks has skew due to the clock phase error of the MMCM (MMCM_TSTATPHAOFFSET = 120ps for Kintex-7) as well as some mismatch due to the fact that they use different clock buffers (maybe another 100ps). So, your paths on the clk250 domain have more like 3.58ns. This is not ideal.
So, a better solution is this:
Synchronize the reset to the clk125 domain using the synchronizer or reset bridge. Drive all the clk125 FFs directly from this synchronized reset.
For the clk250 domain, however, have a second reset root flop - this FF is clocked on clk250, and takes the synchronized reset from the clk125 domain as its input (never have two synchronizers in parallel). Drive all the clk250 flip-flops from this flip-flop. Now both clocks' reset root is coming from their own domain (so you don't pay the extra skew penalty, except on the one path from the synchronizer to the clk250 reset root flip-flop) and both domains will come out of reset on the same clock edge - for the clk125 domain the first clk125 edge after the reset synchronizer deasserts reset (8ns), and for the clk250 it is the second clk250 edge after the reset synchronizer deasserts reset (also 8ns!).