FPGA proven, AISC proven, I2C controller core from OpenCores
http://opencores.org/project,i2c
Bit-controller
5 block
1) capture SCL and SDA
1 -- port 2 scl_i : in std_logic; 3 sda_i : in std_logic; 4 5 -- architecture 6 7 -- block 8 bus_status_ctrl : block 9 singal cSCL, cSDA : std_logic_vector(1 downto 0); 10 11 capture_scl_sda: process(clk, nRst) 12 begin 13 if (nRst = '0') then 14 cSCL <= "00"; 15 cSDA <= "00"; 16 elsif (clk'event and clk = '1') then 17 if (rst = '1') then 18 cSCL <= "00"; 19 cSDA <= "00"; 20 else 21 cSCL <= (cSCL(0) & scl_i); 22 cSDA <= (cSDA(0) & sda_i); 23 endif; 24 endif; 25 end process capture_scl_sda;
2) filter SCL and SDA (glitch-free)
1 -- port 2 ena : in std_logic; -- core enable signal 3 clk_cnt : in unsigned(15 downto 0); -- clock prescale value 4 5 -- block 6 signal fSCL : std_logic_vector(2 downto 0); -- filter inputs for SCL 7 signal fSDA : std_logic_vector(2 downto 0); -- filter inputs for SDA 8 signal filter_cnt : unsigned(13 downto 0); -- clock divider for filter 9 10 filter_divider: process(clk, nRst) 11 begin 12 if (nRst = '0') then 13 filter_cnt <= (others => '0'); 14 elsif (clk'event and clk = '1') then 15 if ( (rst = '1') or (ena = '0') ) then 16 filter_cnt <= (others => '0'); 17 elsif (filter_cnt = 0) then 18 filter_cnt <= clk_cnt(15 downto 2); 19 else 20 filter_cnt <= filter_cnt -1; 21 end if; 22 end if; 23 end process filter_divider; 24 25 26 filter_scl_sda: process(clk, nRst) 27 begin 28 if (nRst = '0') then 29 fSCL <= (others => '1'); 30 fSDA <= (others => '1'); 31 elsif (clk'event and clk = '1') then 32 if (rst = '1') then 33 fSCL <= (others => '1'); 34 fSDA <= (others => '1'); 35 elsif (filter_cnt = 0) then 36 fSCL <= (fSCL(1 downto 0) & cSCL(1)); 37 fSDA <= (fSDA(1 downto 0) & cSDA(1)); 38 end if; 39 end if; 40 end process filter_scl_sda;
3) generate filtered SCL and SDA signals
1 -- architecture 2 signal sSCL, sSDA : std_logic; -- synchronized SCL and SDA inputs 3 signal dSCL, dSDA : std_logic; -- delayed versions ofsSCL and sSDA 4 5 -- block 6 scl_sda: process(clk, nRst) 7 begin 8 if (nRst = '0') then 9 sSCL <= '1'; 10 sSDA <= '1'; 11 12 dSCL <= '1'; 13 dSDA <= '1'; 14 elsif (clk'event and clk = '1') then 15 if (rst = '1') then 16 sSCL <= '1'; 17 sSDA <= '1'; 18 19 dSCL <= '1'; 20 dSDA <= '1'; 21 else 22 sSCL <= (fSCL(2) and fSCL(1)) or 23 (fSCL(2) and fSCL(0)) or 24 (fSCL(1) and fSCL(0)); 25 sSDA <= (fSDA(2) and fSDA(1)) or 26 (fSDA(2) and fSDA(0)) or 27 (fSDA(1) and fSDA(0)); 28 29 dSCL <= sSCL; 30 dSDA <= sSDA; 31 end if; 32 end if; 33 end process scl_sda;