Synchronous and Asynchronous Resets in an FPGA System

I am new to creating an FPGA system to control the I2C bus (although I think this problem applies to any FPGA system) using various modules, and they all use synchronous reset.

The modules are synchronized using a clock divider module that receives the system clock and outputs the lower frequency to the rest of the system.

The problem that I encountered is that when the reset signal drops, the clock divider is reset, and therefore the clock that other modules depend on the stop is why other modules do not register reset

An obvious solution would be to have an asynchronous reset, however in Xilinx ISE it does not seem to be like them, and it warns you that it is incompatible with Spartan-6 FPGAs (especially when the code after the asynchronous IS code is synchronous, which is due to that the I2C bus uses the bus clock to put the bits on the bus).

Another solution would be for the clock divider to simply not be reset -able, so the clock would never stop and all modules would reset correctly. However, this means that the clock divider registers cannot be initialized / reinitialized in a known state, which, as I was told, will be a big problem, although I know that you can use the operator := '0'/'1'; in the simulation, but this does not work programmed on the actual FPGA (?).

What is an agreement for synchronous flushes? Clock generators usually just don't reset? Or are they only reset on the instantaneous edge of the reset signal? Or my suggestions are not a real solution!

I put in a timeline, as well as my code, to illustrate what I mean and show the code I used.

Thank you very much!

David

enter image description here

 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; library UNISIM; use UNISIM.VComponents.all; ENTITY CLK_DIVIDER IS GENERIC(INPUT_FREQ : INTEGER; OUT1_FREQ : INTEGER; OUT2_FREQ : INTEGER ); PORT(SYSCLK : IN STD_LOGIC; RESET_N : IN STD_LOGIC; OUT1 : OUT STD_LOGIC; OUT2 : OUT STD_LOGIC); END CLK_DIVIDER; architecture Behavioral of Clk_Divider is constant divider1 : integer := INPUT_FREQ / OUT1_FREQ / 2; constant divider2 : integer := INPUT_FREQ / OUT2_FREQ / 2; signal counter1 : integer := 0; signal counter2 : integer := 0; signal output1 : std_logic := '0'; signal output2 : std_logic := '0'; begin output1_proc : process(SYSCLK) begin if rising_edge(SYSCLK) then if RESET_N = '0' then counter1 <= 0; output1 <= '1'; else if counter1 >= divider1 - 1 then output1 <= not output1; counter1 <= 0; else counter1 <= counter1 + 1; end if; end if; end if; end process; output2_proc : process(SYSCLK) begin if rising_edge(SYSCLK) then if RESET_N = '0' then counter2 <= 0; output2 <= '1'; else if counter2 >= divider2 - 1 then output2 <= not output2; counter2 <= 0; else counter2 <= counter2 + 1; end if; end if; end if; end process; OUT1 <= output1; OUT2 <= output2; end Behavioral; 
0
source share
3 answers

Do not create an internal clock with user logic, but use PLL / DCM for a specific device if a few hours are really needed. All user logic that runs on derivative clocks must then be held in reset until the clock is stable, and reset for user logic can then be released as required by the design. You can use either synchronous reset or asynchronous reset.

But in this case, it is likely that instead a synchronization enable signal is generated, and approve this enable signal for one cycle each time when signal updates are required to generate any protocol, for example. I2C protocol with appropriate time.

Using fewer clock pulses in combination with synchronous synchronization signals simplifies the setup of Static Timing Analysis (STA) , as well as avoiding problems with reset and Clock Crossover (CDC) .

+4
source

A sustainable way to handle drops in such a system is as follows:

To use DCM / PLL / MMCM in Xilinx FPGAs to process the input system clock and generate all the required clock frequencies for the output, given the very low frequencies, you should use the clock in the clock manager specifications and generate a synchronization enable signal for use in combination with it. This can be reset from the host system at startup or if at any time the input time is deleted and then applied again.

Invert the LOCKED signal from the clock manager to generate an active high reset when it is in reset or in the process of blocking the input. It must be transmitted via SRL16 or SRL32 in order to delay it. This SRL must be synchronized with the PLL output after it has been placed in the global routing of watches with BUFG. Use an additional trigger after SRL to improve time. This signal can then be used as an active, highly synchronous reset for the rest of the logic in the device, where necessary.

If you get clock synchronization signal synchronization errors because it is a high voltage network, it can also be transmitted via BUFG to access the fast global synchronization network to improve synchronization.

+2
source

@Stuart Vivian

(this should be posted as a comment, but I do not have enough reputation points for this, sorry for that)

Consider using a counter instead of a shift register to delay reset, because if the contents of the LUT are not cleared after loading the bitstream (some FPGA families have this behavior), the reset signal may bounce, leading to unpredictable results.

0
source

Source: https://habr.com/ru/post/1238384/


All Articles