4 generate clock and control signals
1 -- architecture 2 signal iscl_oen, isda_oen : std_logic; -- internal I2C lines 3 signal sda_chk : std_logic; -- check SDA status (multi-master arbitration) 4 signal dscl_oen : std_logic; -- delayed scl_oen signals 5 signal sSCL, sSDA : std_logic; -- synchronized SCL and SDA inputs 6 signal dSCL, dSDA : std_logic; -- delayed versions ofsSCL and sSDA 7 signal clk_en : std_logic; -- statemachine clock enable 8 signal scl_sync, slave_wait : std_logic; -- clock generation signals 9 signal ial : std_logic; -- internal arbitration lost signal 10 signal cnt : unsigned(15 downto 0); -- clock divider counter (synthesis) 11 12 -- whenever the slave is not ready it can delay the cycle by pulling SCL low 13 -- delay scl_oen 14 process (clk, nRst) 15 begin 16 if (nRst = '0') then 17 dscl_oen <= '0'; 18 elsif (clk'event and clk = '1') then 19 dscl_oen <= iscl_oen; 20 end if; 21 end process; 22 23 -- slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low 24 -- slave_wait remains asserted until the slave releases SCL 25 process (clk, nRst) 26 begin 27 if (nRst = '0') then 28 slave_wait <= '0'; 29 elsif (clk'event and clk = '1') then 30 slave_wait <= (iscl_oen and not dscl_oen and not sSCL) or (slave_wait and not sSCL); 31 end if; 32 end process; 33 34 -- master drives SCL high, but another master pulls it low 35 -- master start counting down its low cycle now (clock synchronization) 36 scl_sync <= dSCL and not sSCL and iscl_oen; 37 38 -- generate clk enable signal 39 gen_clken: process(clk, nRst) 40 begin 41 if (nRst = '0') then 42 cnt <= (others => '0'); 43 clk_en <= '1'; 44 elsif (clk'event and clk = '1') then 45 if ((rst = '1') or (cnt = 0) or (ena = '0') or (scl_sync = '1')) then 46 cnt <= clk_cnt; 47 clk_en <= '1'; 48 elsif (slave_wait = '1') then 49 cnt <= cnt; 50 clk_en <= '0'; 51 else 52 cnt <= cnt -1; 53 clk_en <= '0'; 54 end if; 55 end if; 56 end process gen_clken;