Reset are "almost static" signals, so they do not need a special route as clocks, that works on high frequencies. So they are routed as normal signals in general.
AFAIK they're routed as regular boring signals on modern fpga's. The tip there is don't go overboard by generating 234976234 different control sets. Too many control sets can use up your routing resources. Well, that and you can only share resources in a slice if they don't have conflicting control signals (reset, clock enable, that sort).
A slice has only one input each for reset, clock enable (and clock for that matter). So you can only share the flip-flops in there if they use those same control signals.
As the clock frequency goes up the requirements on reset skew gets harder and harder, because we normally want all the registers to leave reset in the same clock cycle. It can help to use a global clock net for the reset signal. For Xilinx, this is achieved by using a BUFG to drive the reset signal.
The resources for routing signals from the clock nets to the "normal" logic are very limited, so this can not be done for many non-clock signals.
The other option is to create a reset tree, with locally generated resets in the lower level modules (has to be done in all modules if you want the reset across all modules to release in the same clock cycle), that are fed by a top level reset circuit. You just have to make sure the reset generator uses attributes such as dont_touch, keep, etc to keep the synthesis/place&route tools from removing the duplicate registers that make up the different branches of the tree. This avoids using a BUFG that might be better used by critical logic like a high fanout enable.
The other option is to create a reset tree, with locally generated resets in the lower level modules (has to be done in all modules if you want the reset across all modules to release in the same clock cycle), that are fed by a top level reset circuit
Let's say you have something like this where there are a whole bunch of things being reset
Code:
process(Clock)
begin
if rising_edge(Clock) then
if (Reset = '1') then
Whole_Bunch_Of_Things_That_Need_To_Get_Reset <= ...
else
...
end if;
end process;
Now rewrite it like this...
Code:
process(Clock)
begin
if rising_edge(Clock) then
Local_Reset <= Reset;
if ([COLOR="#FF0000"]Local_Reset[/COLOR] = '1') then
Whole_Bunch_Of_Things_That_Need_To_Get_Reset <= ...
else
...
end if;
end process;
Now this process has only one thing that is getting reset by the signal 'Reset'. The 'Whole_Bunch_Of_Things_That_Need_To_Get_Reset' are getting reset by a different signal 'Local_Reset'. If you imagine a large design with 100s of things that need to get reset, do they all really need to get reset by a global reset? Or can a chunk of them get reset one or more clock cycles later. That is the basic idea behind a 'reset tree'...although I'm not sure I would call it that, but I don't have a better name for it either.
Hello Kevin thanks for your reply does above technique applicable to asynchronous resets ? ( i dont think ) if not what is the way of 'reset tree' for asynchronous resets....
For Xilinx FPGAs I use something similar to this in a separate module I just instantiate in a bunch of places. Usually in each module the top level reset generator goes to.
Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
(* IOB="FALSE", SHREG_EXTRACT="NO", DONT_TOUCH="TRUE", ASYNC_REG="TRUE"*)reg[RESET_CLOCKS-1:0] rstSyncReg;// synchronization pipeline registers// active high input resetalways@(posedge CLK orposedge ARESET )beginif( ARESET )begin
rstSyncReg <={RESET_CLOCKS{1'b0}};endelseif( ENB )begin
rstSyncReg <={rstSyncReg[RESET_CLOCKS-2:0],1'b1};endendassign SR = rstSyncReg[RESET_CLOCKS-1];
For all destinations on the same clock domain (as long as the number of these modules in the reset path are the same for each destination) the reset will get released synchronous to the clock and on the same edge.
The leaf resets l1-l10 are the only resets used by the logic. The other ones are just there to fanout the reset generator. This is why I referred to it as a reset tree. I normally only add resets to specific control logic that must be reset to force design back to a known state and sometimes because of simulation problems with signals that become X's because of something like an uninitialized RAM. I normally don't ever add resets to any of my datapath logic.
Hello Kevin thanks for your reply does above technique applicable to asynchronous resets ? ( i dont think ) if not what is the way of 'reset tree' for asynchronous resets....
No, but I don't use asynchronous resets since all resets need to be synchronized anyway in order to meet timing requirements.
Also, the whole 'reset tree' thing can be turned right back into a single net by a synthesis tool. If you imagine that you had five entities each with a locally generated 'Local_Reset' signal generated as I showed previously, then the synthesis tool can optimize all five of the 'Local_Reset' signals into a single signal and distribute that to each of the five entities. The reason it can do this is because each of the five 'Local_Reset' signals are all logically identical.
Synthesis tools may also have a setting to limit the fanout on a signal. Simply using that setting will cause the tool to replicate the single reset signal into multiple resets throughout the design.
Typically, this is not really worth thinking about too much. If the design meets the functional requirements and passes static timing analysis it doesn't much matter whether or not some reset signal fans out to 100+ places or not. If you find that you're not passing static timing analysis and the fundamental reason is because of a reset signal that goes all over the place then the above technique can sometimes be used to cut down the number of places it goes. More importantly, don't bother to reset everything just because you want it to reset. Control signals and state machines need a reset, data path logic does not. Typically, the easiest thing to do though would be the synthesis tool fanout limit setting.