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

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;