02 Resets - alex-aleyan/xilinx GitHub Wiki

Sources:

Resets

  • System reset is required in order to put the logic into a known state.
  • Most Resets are active low since the CMOS transistors can easier sink the current than to source the current.
  • Most FPGAs provide elements with both Synch Resets (preferred) and Async Resets. Always check the device documentation for details.
  • The Reset level (active high vs active low) is vendor specific to avoid utilizing extra logic from data path. Always check the device documentation for details.
  • Try to minimize usage of control signals (Set, Reset, Clear) as much as possible.
  • Minimum Recover Time (RT; a.k.a. Reset Recovery Time) is the time between the de-assertion of the reset and the next triggering edge of the clock.
  • Violation of RT may leave a circuit in metastable state (the data did not have enough time to "settle"). Utilize double flops to drive the Async Reset on a flip flop (insert the double flop between the source of the reset signal and the Async Pin on the flop thus synchronizing it before it reaches the flop - see figure at 36:00 of Lecture 11).
  • Tools are tuned for synchronous logic/resets.
  • Asynchronous logic used to be popular due to lower power consumption (fewer voltage switching yields less power consumption; typically clock consumes 50% of the power on a chip).
    • Async logic utilizes hand shaking which essentially consumes almost as much power as clocks.
    • Async logic is utilized seldomly but maybe implemented due to protocol requirements, to meet speed requirements, or solve special problems like implementing a frequency divider if low-skew buffer in unavailable.
    • Async Reset - a reset independent of the clock.
    • The advantage of Async Resets is that datapath is guaranteed to be clean (no extra logic is utilized to implement an Async Reset; this comes straight from Cummings papers by the way).
  • Sync Reset - a reset is considered synchronous if assertion and desertion are both synchronous with the clock.
    • Synchronous Resets are automatically timed and don't require special timing constraints.
    • Synchronous Resets don't require switches/settings to analyze timing.
  • Some FPGA components (BRAM's output registers) utilize Synchronous Resets only - thus using Async Resets in you code will prevent the tool from utilizing the BRAM thus worsening the place&route effort.
  • Instead of using Async Reset, it has become a common technique to make at least the de-assertion of the Reset synchronous to the clock thus assuring that the reset is captured and maximum Reset Recovery Time is achieved:
    process(clk; rst_n) then
        if (rst_n = '0') then
            rff1 <= '0';
            rff2 <= '0';
        elsif ( rising_edge(clk) ) then -- notice we wait for the clock edge to deassert the rff1 and propogate to rff2
            rff1 <= '1';
            rff2 <= rff1 ;
        end if;
    end
    
  • FPGAs have dedicated reset trees and most things are already taken care of for you. On older FPGAs, the reset trees were implemented in HDL to allow all modules to come out of a reset on the same clock cycle.
  • Utilize Reset Synchronizer to controls the number of clock cycles to hold active the reset for:
    process (Async_Reset, Clock)
    begin
    if (Async_Reset = ‘1’) then
    	Reset_reg <= (others => ‘1’);
    	Reset <= ‘1’;
    elsif ( rising_edge(Clock) ) then
    	Reset_reg <= Reset_reg(RESET_WIDTH-2 downto 0) & ‘0’;
    	Reset     <= Reset_reg(RESET_WIDTH-1);
    end if;
    end process;
    
  • When data is evaluated only when VALID signal is set, no need to implement resets (this strategy will yield reduced fan out):
    process(Clock)
    begin
        if (rising_edge(Clock)) then
            if (Reset = ‘1’) then -- BAD: Unnecessary Reset!!!
                Data_Out <= (others => ‘0’);
            else
                if (Data_Valid = ‘1’) then
                    Data_Out <= Data_In;
                end if;
            end if;
        end if;
    end process;
    
    process(Clock)
    begin
        if (rising_edge(Clock)) then
            if (Data_Valid = ‘1’) then
                Data_Out <= Data_In;
            end if;
        end if;
    end process;
    
  • Two philosophies for follower flip flops (shift registers):
    • Don't mix follower flip flops and reset-able flip flops under a single process (otherwise extra logic is utilized to reset the follower FFs). Separate them as shown below! (straight from cummings). In this case, better just reset all flipflops including the "follower" flipflops.
      // Splitting resettable and follower flops into two separate always blocks!
      // Such mix bag is an indication of congested design being optimized/patched here and there; bad practice but works.
      // Possibly no longer an issue with current tools and devices.
      // Resettable follower FF:
      always @(posedge clk) begin
          if (!rst_n) begin
              rff1 <= 1'b0;
              rff2 <= 1'b0;
          end else begin
              rff1 <= d;
              rff2 <= rff1 ;
          end
      end
      // Follower FF without Reset:
      always @(posedge clk) begin
          rff3 <= rff2 ;
          rff4 <= rff3 ;
      end
      
    • BETTER: Don't reset shift registers at all! Instead, hold the reset long enough for the reset values to propagate thru the shift registers. I like this one better since it would utilize less logic thus easing the optimization effort of the tool! Removing reset signal can save resources and improve timing tremendously.