]> jspc29.x-matter.uni-frankfurt.de Git - vhdlbasics.git/commitdiff
add I2C files from MB
authorJan Michel <j.michel@gsi.de>
Thu, 22 Nov 2018 16:28:03 +0000 (17:28 +0100)
committerJan Michel <j.michel@gsi.de>
Thu, 22 Nov 2018 16:28:03 +0000 (17:28 +0100)
interface/i2c_gstart.vhd [new file with mode: 0644]
interface/i2c_sendb.vhd [new file with mode: 0644]
interface/i2c_slim.vhd [new file with mode: 0644]

diff --git a/interface/i2c_gstart.vhd b/interface/i2c_gstart.vhd
new file mode 100644 (file)
index 0000000..a8b3119
--- /dev/null
@@ -0,0 +1,244 @@
+library IEEE;\r
+use IEEE.STD_LOGIC_1164.ALL;\r
+use IEEE.STD_LOGIC_ARITH.ALL;\r
+use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
+\r
+--library work;\r
+--use work.adcmv3_components.all;\r
+\r
+entity I2C_GSTART is\r
+port(\r
+       CLK_IN          : in    std_logic;\r
+       RESET_IN        : in    std_logic;\r
+       START_IN        : in    std_logic;\r
+       DOSTART_IN      : in    std_logic;\r
+       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+       SDONE_OUT       : out   std_logic;\r
+       SOK_OUT         : out   std_logic;\r
+       SDA_IN          : in    std_logic;\r
+       SCL_IN          : in    std_logic;\r
+       R_SCL_OUT       : out   std_logic;\r
+       S_SCL_OUT       : out   std_logic;\r
+       R_SDA_OUT       : out   std_logic;\r
+       S_SDA_OUT       : out   std_logic;\r
+       BSM_OUT         : out   std_logic_vector(3 downto 0)\r
+);\r
+end entity;\r
+\r
+architecture Behavioral of I2C_GSTART is\r
+\r
+-- Signals\r
+type STATES is (SLEEP,P_SCL,WCTR0,P_SDA,WCTR1,P_CHK,S_CHK0,RS_SDA,S_CHK1,ERROR,DONE,WCTR2);\r
+signal CURRENT_STATE, NEXT_STATE: STATES;\r
+\r
+signal bsm          : std_logic_vector(3 downto 0);\r
+signal cctr         : std_logic_vector(8 downto 0); -- counter for bit length\r
+\r
+signal cycdone_x    : std_logic;\r
+signal cycdone      : std_logic; -- one counter period done\r
+\r
+signal load_cyc_x   : std_logic;\r
+signal load_cyc     : std_logic;\r
+signal dec_cyc_x    : std_logic;\r
+signal dec_cyc      : std_logic;\r
+signal sdone_x      : std_logic;\r
+signal sdone        : std_logic; -- Start/Stop done\r
+signal sok_x        : std_logic;\r
+signal sok          : std_logic; -- Start/Stop OK\r
+\r
+signal r_scl_x                 : std_logic;\r
+signal r_scl                           : std_logic;\r
+signal s_scl_x                 : std_logic;\r
+signal s_scl                           : std_logic;\r
+signal r_sda_x                 : std_logic;\r
+signal r_sda                           : std_logic;\r
+signal s_sda_x                 : std_logic;\r
+signal s_sda                           : std_logic;\r
+\r
+-- Moduls\r
+\r
+begin\r
+\r
+-- Countdown for one half of SCL (adjustable clock width)\r
+THE_CYC_CTR_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       cctr <= (others => '0');\r
+               elsif( load_cyc = '1' ) then\r
+                       cctr <= i2c_speed_in;\r
+               elsif( dec_cyc = '1' ) then\r
+                       cctr <= cctr - 1;\r
+               end if;\r
+       end if;\r
+end process THE_CYC_CTR_PROC;\r
+\r
+-- end of cycle recognition\r
+cycdone_x <= '1' when (cctr = x"00") else '0';\r
+\r
+-- The main state machine\r
+-- State memory process\r
+STATE_MEM: process( clk_in )\r
+begin\r
+       if ( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       CURRENT_STATE <= SLEEP;\r
+                       load_cyc      <= '0';\r
+                       dec_cyc       <= '0';\r
+                       sdone         <= '0';\r
+                       sok           <= '0';\r
+                       cycdone       <= '0';\r
+                       r_scl         <= '0';\r
+                       s_scl         <= '0';\r
+                       r_sda         <= '0';\r
+                       s_sda         <= '0';\r
+               else\r
+                       CURRENT_STATE <= NEXT_STATE;\r
+                       load_cyc      <= load_cyc_x;\r
+                       dec_cyc       <= dec_cyc_x;\r
+                       sdone         <= sdone_x;\r
+                       sok           <= sok_x;\r
+                       cycdone       <= cycdone_x;\r
+                       r_scl         <= r_scl_x;\r
+                       s_scl         <= s_scl_x;\r
+                       r_sda         <= r_sda_x;\r
+                       s_sda         <= s_sda_x;\r
+               end if;\r
+       end if;\r
+end process STATE_MEM;\r
+\r
+-- Transition matrix\r
+TRANSFORM: process(CURRENT_STATE, dostart_in, start_in, sda_in, scl_in, cycdone)\r
+begin\r
+       NEXT_STATE <= SLEEP;\r
+       load_cyc_x <= '0';\r
+       dec_cyc_x  <= '0';\r
+       sdone_x    <= '0';\r
+       sok_x      <= '1';\r
+       r_sda_x    <= '0';\r
+       s_sda_x    <= '0';\r
+       r_scl_x    <= '0';\r
+       s_scl_x    <= '0';\r
+       case CURRENT_STATE is\r
+               when SLEEP =>  \r
+                               if   ( (dostart_in = '1') and (start_in = '1') ) then\r
+                                       NEXT_STATE <= S_CHK0; -- generate a start condition\r
+                                       load_cyc_x <= '1';\r
+                               elsif( (dostart_in = '1') and (start_in = '0') ) then\r
+                                       NEXT_STATE <= WCTR2; -- generate a stop condition\r
+                                       load_cyc_x <= '1';\r
+                               else\r
+                                       NEXT_STATE <= SLEEP;\r
+--                                     load_cyc_x <= '1';\r
+                               end if;\r
+               when WCTR2 =>\r
+                               if( (cycdone = '1') ) then\r
+                                       NEXT_STATE <= P_SCL;\r
+                                       load_cyc_x <= '1';\r
+                                       s_scl_x    <= '1';\r
+                               else\r
+                                       NEXT_STATE <= WCTR2;\r
+                                       dec_cyc_x  <= '1';\r
+                               end if;\r
+               when P_SCL => \r
+                               NEXT_STATE <= WCTR0;\r
+                               dec_cyc_x  <= '1';\r
+               when S_CHK0 =>\r
+                               if( (sda_in = '1') and (scl_in = '1') ) then\r
+                                       NEXT_STATE <= RS_SDA;\r
+                                       r_sda_x    <= '1';\r
+                               else\r
+                                       NEXT_STATE <= ERROR;\r
+                                       sok_x      <= '0';\r
+                               end if;\r
+               when RS_SDA =>\r
+                               NEXT_STATE <= WCTR0;\r
+                               dec_cyc_x  <= '1';\r
+               when WCTR0 =>\r
+                               if   ( (cycdone = '1') and (start_in = '1') ) then\r
+                                       NEXT_STATE <= S_CHK1;\r
+                               elsif( (cycdone = '1') and (start_in = '0') ) then\r
+                                       NEXT_STATE <= P_SDA;\r
+                                       load_cyc_x <= '1';\r
+                                       s_sda_x    <= '1';\r
+                               else\r
+                                       NEXT_STATE <= WCTR0;\r
+                                       dec_cyc_x  <= '1';\r
+                               end if;\r
+               when S_CHK1 =>\r
+                               if( (sda_in = '0') and (scl_in = '1') ) then\r
+                                       NEXT_STATE <= DONE;\r
+                               else\r
+                                       NEXT_STATE <= ERROR;\r
+                                       sok_x      <= '0';\r
+                               end if;\r
+               when P_SDA =>\r
+                               NEXT_STATE <= WCTR1;\r
+                               dec_cyc_x  <= '1';\r
+               when WCTR1 =>\r
+                               if( (cycdone = '1') ) then\r
+                                       NEXT_STATE <= P_CHK;\r
+                               else\r
+                                       NEXT_STATE <= WCTR1;\r
+                                       dec_cyc_x  <= '1';\r
+                               end if;\r
+               when P_CHK =>\r
+                               if( (sda_in = '1') and (scl_in = '1') ) then\r
+                                       NEXT_STATE <= DONE;\r
+                                       sdone_x    <= '1';\r
+                               else\r
+                                       NEXT_STATE <= ERROR;\r
+                                       sok_x      <= '0';\r
+                               end if;\r
+               when ERROR =>\r
+                               if( dostart_in = '0' ) then\r
+                                       NEXT_STATE <= SLEEP;\r
+                               else\r
+                                       NEXT_STATE <= ERROR;\r
+                                       sdone_x    <= '1';\r
+                                       sok_x      <= '0';\r
+                               end if;\r
+               when DONE =>\r
+                               if( dostart_in = '0' ) then\r
+                                       NEXT_STATE <= SLEEP;\r
+                               else\r
+                                       NEXT_STATE <= DONE;\r
+                                       sdone_x    <= '1';\r
+                               end if;\r
+               when others =>\r
+                               NEXT_STATE <= SLEEP;\r
+       end case;\r
+end process TRANSFORM;\r
+\r
+-- Output decoding\r
+DECODE: process(CURRENT_STATE)\r
+begin\r
+       case CURRENT_STATE is\r
+               when SLEEP  =>  bsm <= x"0";\r
+               when S_CHK0 =>  bsm <= x"1";\r
+               when RS_SDA =>  bsm <= x"2";\r
+               when P_SCL  =>  bsm <= x"3";\r
+               when WCTR0  =>  bsm <= x"4";\r
+               when S_CHK1 =>  bsm <= x"5";\r
+               when P_SDA  =>  bsm <= x"6";\r
+               when WCTR1  =>  bsm <= x"7";\r
+               when P_CHK  =>  bsm <= x"8";\r
+               when DONE   =>  bsm <= x"9";\r
+               when WCTR2  =>  bsm <= x"a";\r
+               when ERROR  =>  bsm <= x"e";\r
+               when others =>  bsm <= x"f";\r
+       end case;\r
+end process DECODE;\r
+\r
+-- Outputs\r
+r_scl_out <= r_scl;\r
+s_scl_out <= s_scl;\r
+r_sda_out <= r_sda;\r
+s_sda_out <= s_sda;\r
+sdone_out <= sdone;\r
+sok_out   <= sok;\r
+\r
+-- Debug\r
+bsm_out <= bsm;\r
+\r
+end Behavioral;\r
diff --git a/interface/i2c_sendb.vhd b/interface/i2c_sendb.vhd
new file mode 100644 (file)
index 0000000..be4e338
--- /dev/null
@@ -0,0 +1,297 @@
+library IEEE;\r
+use IEEE.STD_LOGIC_1164.ALL;\r
+use IEEE.STD_LOGIC_ARITH.ALL;\r
+use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
+\r
+entity i2c_sendb is\r
+port(\r
+       CLK_IN          : in    std_logic;\r
+       RESET_IN        : in    std_logic;\r
+       DOBYTE_IN       : in    std_logic;\r
+       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+       I2C_BYTE_IN     : in    std_logic_vector(8 downto 0);\r
+       I2C_BACK_OUT    : out   std_logic_vector(8 downto 0);\r
+       SDA_IN          : in    std_logic;\r
+       R_SDA_OUT       : out   std_logic;\r
+       S_SDA_OUT       : out   std_logic;\r
+--  SCL_IN          : in    std_logic;\r
+       R_SCL_OUT       : out   std_logic;\r
+       S_SCL_OUT       : out   std_logic;\r
+       BDONE_OUT       : out   std_logic;\r
+       BOK_OUT         : out   std_logic;\r
+       BSM_OUT         : out   std_logic_vector(3 downto 0)\r
+);\r
+end entity;\r
+\r
+architecture Behavioral of i2c_sendb is\r
+\r
+-- Signals\r
+type STATES is (SLEEP,LCL,WCL,LCH,WCH,FREE,DONE);\r
+signal CURRENT_STATE, NEXT_STATE: STATES;\r
+\r
+signal bsm          : std_logic_vector( 3 downto 0 );\r
+\r
+signal inc_bit_x    : std_logic;\r
+signal inc_bit      : std_logic; -- increment bit counter for byte to send\r
+signal rst_bit_x    : std_logic;\r
+signal rst_bit      : std_logic; -- reset bit counter for byte to send\r
+signal load_cyc_x   : std_logic;\r
+signal load_cyc     : std_logic; -- load cycle counter (SCL length)\r
+signal dec_cyc_x    : std_logic;\r
+signal dec_cyc      : std_logic; -- decrement cycle counter (SCL length)\r
+signal load_sr_x    : std_logic;\r
+signal load_sr      : std_logic; -- load output shift register\r
+signal shift_o_x    : std_logic;\r
+signal shift_o      : std_logic; -- output shift register control\r
+signal shift_i_x    : std_logic;\r
+signal shift_i      : std_logic; -- input shift register control\r
+signal bdone_x      : std_logic;\r
+signal bdone        : std_logic;\r
+signal r_scl_x      : std_logic;\r
+signal r_scl        : std_logic; -- output for SCL\r
+signal s_scl_x      : std_logic;\r
+signal s_scl        : std_logic; -- output for SCL\r
+\r
+signal bctr         : std_logic_vector(3 downto 0); -- bit counter    (1...9)\r
+signal cctr         : std_logic_vector(8 downto 0); -- counter for bit length\r
+signal bok          : std_logic;\r
+signal cycdone      : std_logic; -- one counter period done\r
+signal bytedone     : std_logic; -- all bits sents\r
+signal in_sr        : std_logic_vector(8 downto 0); -- shift register for byte in\r
+signal out_sr       : std_logic_vector(8 downto 0); -- shift register for byte out\r
+signal i2c_back     : std_logic_vector(8 downto 0); -- shift register for byte in\r
+signal r_sda        : std_logic; -- output for SDA\r
+signal s_sda        : std_logic; -- output for SDA\r
+signal load         : std_logic; -- delay register\r
+signal i2c_d        : std_logic; -- auxiliary register\r
+\r
+-- Moduls\r
+\r
+begin\r
+\r
+-- Bit counter  (for byte to send)\r
+THE_BIT_CTR_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       bctr <= (others => '0');\r
+               elsif( rst_bit = '1' ) then\r
+                       bctr <= (others => '0');\r
+               elsif( inc_bit = '1' ) then\r
+                       bctr <= bctr + 1;\r
+               end if;\r
+       end if;\r
+end process THE_BIT_CTR_PROC;\r
+\r
+-- end of byte recognition\r
+bytedone <= '1' when (bctr = x"9") else '0';\r
+\r
+-- Countdown for one half of SCL (adjustable clock width)\r
+THE_CYC_CTR_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       cctr <= (others => '0');\r
+               elsif( load_cyc = '1' ) then\r
+                       cctr <= i2c_speed_in;\r
+               elsif( dec_cyc = '1' ) then\r
+                       cctr <= cctr - 1;\r
+               end if;\r
+       end if;\r
+end process THE_CYC_CTR_PROC;\r
+\r
+-- end of cycle recognition\r
+cycdone <= '1' when (cctr = x"00") else '0';\r
+\r
+-- Bit output\r
+THE_BIT_OUT_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       out_sr <= (others => '0');\r
+                       i2c_d <= '1';\r
+               elsif( load_sr = '1' ) then\r
+                       out_sr <= i2c_byte_in;\r
+                       i2c_d  <= '1';\r
+               elsif( shift_o = '1' ) then\r
+                       i2c_d <= out_sr(8);\r
+                       out_sr(8 downto 0) <= out_sr(7 downto 0) & '0';\r
+               end if;\r
+       end if;\r
+end process THE_BIT_OUT_PROC;\r
+\r
+-- Bit input\r
+THE_BIT_IN_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if   ( reset_in = '1' ) then\r
+                       in_sr <= (others => '1');\r
+               elsif( shift_o = '1' ) then\r
+                       in_sr(8 downto 1) <= in_sr(7 downto 0);\r
+                       in_sr(0) <= sda_in;\r
+               end if;\r
+       end if;\r
+end process THE_BIT_IN_PROC;\r
+\r
+-- Output register for readback data (could be reduced to SR_IN_INT)\r
+THE_I2C_BACK_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       i2c_back <= (others => '1');\r
+               elsif( shift_i = '1' ) then\r
+                       i2c_back(8 downto 1) <= in_sr(7 downto 0);\r
+                       i2c_back(0) <= sda_in;\r
+               end if;\r
+       end if;\r
+end process THE_I2C_BACK_PROC;\r
+\r
+-- ByteOK is the inverted ACK bit from readback data.\r
+bok <= not i2c_back(0); -- BUG\r
+\r
+-- The main state machine\r
+-- State memory process\r
+STATE_MEM: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1') then\r
+                       CURRENT_STATE <= SLEEP;\r
+                       inc_bit       <= '0';\r
+                       rst_bit       <= '0';\r
+                       load_cyc      <= '0';\r
+                       dec_cyc       <= '0';\r
+                       load_sr       <= '0';\r
+                       shift_o       <= '0';\r
+                       shift_i       <= '0';\r
+                       bdone         <= '0';\r
+                       r_scl         <= '0';\r
+                       s_scl         <= '0';\r
+               else\r
+                       CURRENT_STATE <= NEXT_STATE;\r
+                       inc_bit       <= inc_bit_x;\r
+                       rst_bit       <= rst_bit_x;\r
+                       load_cyc      <= load_cyc_x;\r
+                       dec_cyc       <= dec_cyc_x;\r
+                       load_sr       <= load_sr_x;\r
+                       shift_o       <= shift_o_x;\r
+                       shift_i       <= shift_i_x;\r
+                       bdone         <= bdone_x;\r
+                       r_scl         <= r_scl_x;\r
+                       s_scl         <= s_scl_x;\r
+               end if;\r
+       end if;\r
+end process STATE_MEM;\r
+\r
+-- Transition matrix\r
+TRANSFORM: process(CURRENT_STATE, dobyte_in, cycdone, bytedone)\r
+begin\r
+       NEXT_STATE <= SLEEP;\r
+       inc_bit_x  <= '0';\r
+       rst_bit_x  <= '0';\r
+       load_cyc_x <= '0';\r
+       dec_cyc_x  <= '0';\r
+       load_sr_x  <= '0';\r
+       shift_o_x  <= '0';\r
+       shift_i_x  <= '0';\r
+       bdone_x    <= '0';\r
+       r_scl_x    <= '0';\r
+       s_scl_x    <= '0';\r
+       case CURRENT_STATE is\r
+               when SLEEP  =>  if( dobyte_in = '1' ) then\r
+                                                       NEXT_STATE <= LCL;\r
+                                                       inc_bit_x  <= '1';\r
+                                                       load_cyc_x <= '1';\r
+                                                       shift_o_x  <= '1';\r
+                                                       r_scl_x    <= '1';\r
+                                               else\r
+                                                       NEXT_STATE <= SLEEP;\r
+                                                       load_sr_x  <= '1';\r
+                                               end if;\r
+               when LCL    =>  NEXT_STATE <= WCL;\r
+                                               dec_cyc_x  <= '1';\r
+               when WCL    =>  if( cycdone = '1' ) then\r
+                                                       NEXT_STATE <= LCH;\r
+                                                       load_cyc_x <= '1';\r
+                                                       s_scl_x    <= '1';\r
+                                               else\r
+                                                       NEXT_STATE <= WCL;\r
+                                                       dec_cyc_x  <= '1';\r
+                                               end if;\r
+               when LCH    =>  NEXT_STATE <= WCH;\r
+                                               dec_cyc_x  <= '1';\r
+               when WCH    =>  if   ( (cycdone = '1') and (bytedone = '0') ) then\r
+                                                       NEXT_STATE <= LCL;\r
+                                                       inc_bit_x  <= '1';\r
+                                                       load_cyc_x <= '1';\r
+                                                       shift_o_x  <= '1';\r
+                                                       r_scl_x    <= '1';\r
+                                               elsif( (cycdone = '1') and (bytedone = '1') ) then\r
+                                                       NEXT_STATE <= FREE;\r
+                                                       shift_o_x  <= '1';\r
+                                                       shift_i_x  <= '1';\r
+                                                       r_scl_x    <= '1';\r
+                                               else\r
+                                                       NEXT_STATE <= WCH;\r
+                                                       dec_cyc_x  <= '1';\r
+                                               end if;\r
+               when FREE   =>  NEXT_STATE <= DONE;\r
+                                               rst_bit_x  <= '1';\r
+                                               bdone_x    <= '1';\r
+               when DONE   =>  if( dobyte_in = '0' ) then\r
+                                                       NEXT_STATE <= SLEEP;\r
+                                               else\r
+                                                       NEXT_STATE <= DONE;\r
+                                                       rst_bit_x  <= '1';\r
+                                                       bdone_x    <= '1';\r
+                                               end if;\r
+                               -- Just in case...\r
+               when others =>  NEXT_STATE <= SLEEP;\r
+       end case;\r
+end process TRANSFORM;\r
+\r
+-- Output decoding\r
+DECODE: process(CURRENT_STATE)\r
+begin\r
+       case CURRENT_STATE is\r
+               when SLEEP  =>  bsm <= x"0";\r
+               when LCL    =>  bsm <= x"1";\r
+               when WCL    =>  bsm <= x"2";\r
+               when LCH    =>  bsm <= x"3";\r
+               when WCH    =>  bsm <= x"4";\r
+               when FREE   =>  bsm <= x"5";\r
+               when DONE   =>  bsm <= x"6";\r
+               when others =>  bsm <= x"f";\r
+       end case;\r
+end process DECODE;\r
+\r
+-- SCL and SDA output pulses\r
+THE_SDA_OUT_PROC: process( clk_in )\r
+begin\r
+       if( rising_edge(clk_in) ) then\r
+               if( reset_in = '1' ) then\r
+                       load  <= '0'; -- was a bug, found 081008\r
+                       r_sda <= '0';\r
+                       s_sda <= '0';\r
+               else\r
+                       load  <= shift_o;\r
+                       r_sda <= load and not i2c_d;\r
+                       s_sda <= load and     i2c_d;\r
+               end if;\r
+       end if;\r
+end process THE_SDA_OUT_PROC;\r
+\r
+-- Outputs\r
+r_scl_out    <= r_scl;\r
+s_scl_out    <= s_scl;\r
+r_sda_out    <= r_sda;\r
+s_sda_out    <= s_sda;\r
+\r
+i2c_back_out <= i2c_back;\r
+\r
+bdone_out    <= bdone;\r
+bok_out      <= bok;\r
+\r
+-- Debugging\r
+bsm_out      <= bsm;\r
+\r
+end Behavioral;\r
diff --git a/interface/i2c_slim.vhd b/interface/i2c_slim.vhd
new file mode 100644 (file)
index 0000000..8a34616
--- /dev/null
@@ -0,0 +1,579 @@
+library IEEE;\r
+use IEEE.STD_LOGIC_1164.ALL;\r
+use IEEE.STD_LOGIC_ARITH.ALL;\r
+use IEEE.STD_LOGIC_UNSIGNED.ALL;\r
+\r
+--library work;\r
+--use work.adcmv3_components.all;\r
+\r
+-- BUG: does alway set bit 0 of address byte to zero !!!!\r
+-- REMARK: this is not a bug, but a feature....\r
+\r
+entity i2c_slim is\r
+port(\r
+       CLOCK                                           : in            std_logic;\r
+       RESET                                           : in            std_logic;\r
+       -- I2C command / setup\r
+       I2C_GO_IN                               : in            std_logic; -- startbit to trigger I2C actions\r
+       ACTION_IN                               : in            std_logic; -- '0' -> write, '1' -> read\r
+       WORD_IN                                 : in            std_logic; -- '0' -> byte, '1' -> word\r
+       I2C_SPEED_IN            : in            std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
+       I2C_ADDR_IN                     : in            std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
+       I2C_CMD_IN                      : in            std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
+       I2C_DW_IN                               : in            std_logic_vector(15 downto 0); -- data word for write command\r
+       I2C_DR_OUT                      : out           std_logic_vector(15 downto 0); -- data word from read command\r
+       STATUS_OUT                      : out           std_logic_vector(7 downto 0); -- status and error bits\r
+       VALID_OUT                               : out           std_logic;\r
+       I2C_BUSY_OUT            : out           std_logic;\r
+       I2C_DONE_OUT            : out           std_logic;\r
+       -- I2C connections\r
+       SDA_IN                                  : in            std_logic;\r
+       SDA_OUT                                 : out           std_logic;\r
+       SCL_IN                                  : in            std_logic;\r
+       SCL_OUT                                 : out           std_logic;\r
+       -- Debug\r
+       BSM_OUT                                 : out           std_logic_vector(4 downto 0)\r
+);\r
+end i2c_slim;\r
+\r
+architecture Behavioral of i2c_slim is\r
+\r
+-- Signals\r
+type STATES is (SLEEP, LOADA, GSTART, SENDA, LOADC, SENDC, LOADD, SENDD, GSTOP, INC,\r
+                               E_START, E_ADDR, E_CMD, E_WD, E_WD2, E_RSTART, E_RADDR, DONE, FAILED, CLRERR, LOADD2, SENDD2);\r
+signal CURRENT_STATE, NEXT_STATE: STATES;\r
+\r
+signal bsm          : std_logic_vector( 4 downto 0 );\r
+signal phase        : std_logic; -- '0' => first phase, '1' => second phase of read cycle\r
+\r
+signal start_x      : std_logic;\r
+signal start        : std_logic; -- '0' => generate STOP, '1' => generate START\r
+signal dostart_x    : std_logic;\r
+signal dostart      : std_logic; -- trigger the GenStart module\r
+signal dobyte_x     : std_logic;\r
+signal dobyte       : std_logic; -- trigger the ByteSend module\r
+signal i2c_done_x   : std_logic;\r
+signal i2c_done     : std_logic; -- acknowledge signal to the outside world\r
+signal running_x    : std_logic;\r
+signal running      : std_logic; -- legacy\r
+signal valid_x                 : std_logic; \r
+signal valid                           : std_logic;\r
+\r
+signal load_dh_x    : std_logic;\r
+signal load_dh      : std_logic;\r
+signal load_dl_x    : std_logic;\r
+signal load_dl      : std_logic;\r
+\r
+signal sdone        : std_logic; -- acknowledge signal from GenStart module\r
+signal sok          : std_logic; -- status signal from GenStart module\r
+signal bdone        : std_logic; -- acknowledge signal from SendByte module\r
+signal bok          : std_logic; -- status signal from SendByte module\r
+signal e_sf         : std_logic; -- Start failed\r
+signal e_anak       : std_logic; -- Adress byte NAK\r
+signal e_cnak       : std_logic; -- Command byte NAK\r
+signal e_dnak       : std_logic; -- First data byte NAK\r
+signal e_dnak2      : std_logic; -- Second data byte NAK\r
+signal e_rsf        : std_logic; -- Repeated Start failed\r
+signal e_ranak      : std_logic; -- Repeated Adress NAK\r
+signal i2c_byte     : std_logic_vector(8 downto 0);\r
+signal i2c_dr       : std_logic_vector(8 downto 0);\r
+\r
+signal i2c_drw                 : std_logic_vector(15 downto 0);\r
+\r
+signal s_scl        : std_logic;\r
+signal r_scl        : std_logic;\r
+signal s_sda        : std_logic;\r
+signal r_sda        : std_logic;\r
+signal r_scl_gs     : std_logic;\r
+signal s_scl_gs     : std_logic;\r
+signal r_sda_gs     : std_logic;\r
+signal s_sda_gs     : std_logic;\r
+signal r_scl_sb     : std_logic;\r
+signal s_scl_sb     : std_logic;\r
+signal r_sda_sb     : std_logic;\r
+signal s_sda_sb     : std_logic;\r
+\r
+signal scl_q                           : std_logic_vector(2 downto 0);\r
+signal sda_q                           : std_logic_vector(2 downto 0);\r
+\r
+signal i2c_speed    : std_logic_vector(8 downto 0);\r
+\r
+-- Components\r
+component i2c_gstart is\r
+port( \r
+       CLK_IN                          : in    std_logic;\r
+       RESET_IN                        : in    std_logic;\r
+       START_IN                        : in    std_logic;\r
+       DOSTART_IN              : in    std_logic;\r
+       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+       SDONE_OUT                       : out   std_logic;\r
+       SOK_OUT                         : out   std_logic;\r
+       SDA_IN                          : in    std_logic;\r
+       SCL_IN                          : in    std_logic;\r
+       R_SCL_OUT                       : out   std_logic;\r
+       S_SCL_OUT                       : out   std_logic;\r
+       R_SDA_OUT                       : out   std_logic;\r
+       S_SDA_OUT                       : out   std_logic;\r
+       BSM_OUT                         : out   std_logic_vector(3 downto 0)\r
+);\r
+end component i2c_gstart;\r
+\r
+component i2c_sendb is\r
+port( \r
+       CLK_IN                          : in    std_logic;\r
+       RESET_IN                        : in    std_logic;\r
+       DOBYTE_IN                       : in    std_logic;\r
+       I2C_SPEED_IN    : in    std_logic_vector(8 downto 0);\r
+       I2C_BYTE_IN             : in    std_logic_vector(8 downto 0);\r
+       I2C_BACK_OUT    : out   std_logic_vector(8 downto 0);\r
+       SDA_IN                          : in    std_logic;\r
+       R_SDA_OUT                       : out   std_logic;\r
+       S_SDA_OUT                       : out   std_logic;\r
+--     SCL_IN                  : in    std_logic;\r
+       R_SCL_OUT                       : out   std_logic;\r
+       S_SCL_OUT                       : out   std_logic;\r
+       BDONE_OUT                       : out   std_logic;\r
+       BOK_OUT                         : out   std_logic;\r
+       BSM_OUT                         : out   std_logic_vector(3 downto 0)\r
+);\r
+end component i2c_sendb;\r
+\r
+begin\r
+\r
+THE_SYNC_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               sda_q(2 downto 0) <= sda_q(1 downto 0) & SDA_IN;\r
+               scl_q(2 downto 0) <= scl_q(1 downto 0) & SCL_IN;                \r
+       end if;\r
+end process THE_SYNC_PROC;\r
+\r
+-- lower limit of speed\r
+i2c_speed <= i2c_speed_in & "000";\r
+\r
+-- Read phase indicator\r
+THE_PHASE_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if( RESET = '1' ) then\r
+                       phase <= '0';\r
+               elsif( CURRENT_STATE = INC ) then\r
+                       phase <= '1';\r
+               elsif( (CURRENT_STATE = DONE) or (CURRENT_STATE = SLEEP) ) then\r
+                       phase <= '0';\r
+               end if;\r
+       end if;\r
+end process THE_PHASE_PROC;\r
+\r
+-- The main state machine\r
+-- State memory process\r
+STATE_MEM: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if( RESET = '1' ) then\r
+                       CURRENT_STATE <= SLEEP;\r
+                       start         <= '0';\r
+                       dostart       <= '0';\r
+                       dobyte        <= '0';\r
+                       i2c_done      <= '0';\r
+                       running       <= '0';\r
+                       load_dh       <= '0';\r
+                       load_dl       <= '0';\r
+                       valid         <= '0';\r
+               else\r
+                       CURRENT_STATE <= NEXT_STATE;\r
+                       start         <= start_x;\r
+                       dostart       <= dostart_x;\r
+                       dobyte        <= dobyte_x;\r
+                       i2c_done      <= i2c_done_x;\r
+                       running       <= running_x;\r
+                       load_dh       <= load_dh_x;\r
+                       load_dl       <= load_dl_x;\r
+                       valid         <= valid_x;\r
+               end if;\r
+       end if;\r
+end process STATE_MEM;\r
+\r
+-- Transition matrix\r
+TRANSFORM: process(CURRENT_STATE, i2c_go_in, sdone, sok, phase, bdone, bok, action_in, word_in)\r
+begin\r
+       NEXT_STATE <= SLEEP;\r
+       start_x    <= '0';\r
+       dostart_x  <= '0';\r
+       dobyte_x   <= '0';\r
+       i2c_done_x <= '0';\r
+       running_x  <= '1';\r
+       load_dh_x  <= '0';\r
+       load_dl_x  <= '0';\r
+       valid_x    <= '0';\r
+       case CURRENT_STATE is\r
+               when SLEEP      =>  \r
+                               if( i2c_go_in = '1' ) then\r
+                                       NEXT_STATE <= CLRERR;\r
+                               else\r
+                                       NEXT_STATE <= SLEEP;\r
+                                       running_x  <= '0';\r
+                               end if;\r
+               when CLRERR     =>  \r
+                               NEXT_STATE <= LOADA;\r
+               when LOADA      =>  \r
+                               NEXT_STATE <= GSTART;\r
+                               start_x    <= '1';\r
+                               dostart_x  <= '1';\r
+               when GSTART     =>  \r
+                               if   ( (sdone = '1') and (sok = '1') ) then\r
+                                       NEXT_STATE <= SENDA; -- generating START did succeed\r
+                                       dobyte_x   <= '1';\r
+                               elsif( (sdone = '1') and (sok = '0') and (phase = '0') ) then\r
+                                       NEXT_STATE <= E_START; -- first START condition failed\r
+                               elsif( (sdone = '1') and (sok = '0') and (phase = '1') ) then\r
+                                       NEXT_STATE <= E_RSTART; -- second START condition failed\r
+                               else\r
+                                       NEXT_STATE <= GSTART; -- wait for START generation ending\r
+                                       start_x    <= '1';\r
+                                       dostart_x  <= '1';\r
+                               end if;\r
+               when E_START    =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when E_RSTART   =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when SENDA      =>  \r
+                               if   ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
+                                       NEXT_STATE <= LOADC; -- I2C write, send command\r
+                               elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '0') ) then\r
+                                       NEXT_STATE <= LOADC; -- I2C read, send command\r
+                               elsif( (bdone = '1') and (bok = '1') and (action_in = '1') and (phase = '1') ) then\r
+                                       NEXT_STATE <= LOADD; -- I2C read, send 0xff dummy byte\r
+                               elsif( (bdone = '1') and (bok = '0') and (phase = '0') ) then\r
+                                       NEXT_STATE <= E_ADDR; -- first address phase failed\r
+                               elsif( (bdone = '1') and (bok = '0') and (phase = '1') ) then\r
+                                       NEXT_STATE <= E_RADDR; -- second address phase failed\r
+                               else\r
+                                       NEXT_STATE <= SENDA; -- wait for send address ending\r
+                                       dobyte_x   <= '1';\r
+                               end if;\r
+               when E_ADDR     =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when E_RADDR    =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when LOADC      =>  \r
+                               NEXT_STATE <= SENDC;\r
+               when SENDC      =>  \r
+                               if   ( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '0') ) then\r
+                                       NEXT_STATE <= LOADD2; -- I2C byte write, prepare data\r
+                               elsif( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '1') ) then\r
+                                       NEXT_STATE <= LOADD; -- I2C word write, prepare data\r
+                               elsif( (bdone = '1') and (bok = '1') and (action_in = '1') ) then\r
+                                       NEXT_STATE <= GSTOP; -- I2C read, first phase ends\r
+                                       dostart_x  <= '1';\r
+                               elsif( (bdone = '1') and (bok = '0') ) then\r
+                                       NEXT_STATE <= E_CMD; -- command phase failed\r
+                               else\r
+                                       NEXT_STATE <= SENDC; -- wait for send command ending\r
+                                       dobyte_x   <= '1';\r
+                               end if;\r
+               when E_CMD      =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when LOADD      =>  \r
+                               NEXT_STATE <= SENDD;\r
+               when SENDD      =>  \r
+                               if   ( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '0') ) then\r
+                                       NEXT_STATE <= GSTOP;    -- I2C write, byte access, done\r
+                                       dostart_x  <= '1';\r
+                               elsif( (bdone = '1') and (bok = '1') and (action_in = '0') and (word_in = '1') ) then\r
+                                       NEXT_STATE <= LOADD2;    -- I2C write, word access, last byte to send\r
+                               elsif( (bdone = '1') and                 (action_in = '1') and (word_in = '0') ) then\r
+                                       NEXT_STATE <= GSTOP; -- I2C read, byte access, data phase\r
+                                       dostart_x  <= '1';\r
+                                       load_dl_x  <= '1';\r
+                               elsif( (bdone = '1') and                 (action_in = '1') and (word_in = '1') ) then\r
+                                       NEXT_STATE <= LOADD2; -- I2C read, word access, last byte to receive\r
+                                       load_dh_x  <= '1';\r
+                               elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
+                                       NEXT_STATE <= E_WD; -- I2C write, first data phase failed\r
+                               else\r
+                                       NEXT_STATE <= SENDD; -- wait for send data ending\r
+                                       dobyte_x   <= '1';\r
+                               end if;\r
+               when LOADD2     =>  \r
+                               NEXT_STATE <= SENDD2;\r
+               when SENDD2     =>  \r
+                               if   ( (bdone = '1') and (bok = '1') and (action_in = '0') ) then\r
+                                       NEXT_STATE <= GSTOP; -- I2C write, done\r
+                                       dostart_x  <= '1';\r
+                               elsif( (bdone = '1') and                 (action_in = '1') ) then\r
+                                       NEXT_STATE <= GSTOP; -- I2C read, data phase\r
+                                       dostart_x  <= '1';\r
+                                       load_dl_x  <= '1';\r
+                               elsif( (bdone = '1') and (bok = '0') and (action_in = '0') ) then\r
+                                       NEXT_STATE <= E_WD2; -- I2C write, data phase failed\r
+                               else\r
+                                       NEXT_STATE <= SENDD2;\r
+                                       dobyte_x   <= '1';\r
+                               end if;\r
+               when E_WD2      =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when E_WD       =>  \r
+                               NEXT_STATE <= FAILED;\r
+                               dostart_x  <= '1';\r
+               when GSTOP      =>  \r
+                               if   ( (sdone = '1') and (action_in = '0') ) then\r
+                                       NEXT_STATE <= DONE;\r
+                                       i2c_done_x <= '1';\r
+                                       valid_x    <= '1';\r
+                               elsif( (sdone = '1') and (action_in = '1') and (phase = '1') ) then\r
+                                       NEXT_STATE <= DONE;\r
+                                       i2c_done_x <= '1';\r
+                                       valid_x    <= '1';\r
+                               elsif( (sdone = '1') and (action_in = '1') and (phase = '0') ) then\r
+                                       NEXT_STATE <= INC;\r
+                               else\r
+                                       NEXT_STATE <= GSTOP;\r
+                                       dostart_x  <= '1';\r
+                               end if;\r
+               when INC        =>  \r
+                               NEXT_STATE <= LOADA;\r
+               when FAILED     =>  \r
+                               if( sdone = '1' ) then\r
+                                               NEXT_STATE <= DONE;\r
+                                               i2c_done_x <= '1';\r
+                                               running_x  <= '0';\r
+--                                             valid_x    <= '1';\r
+                                       else\r
+                                               NEXT_STATE <= FAILED;\r
+                                               dostart_x  <= '1';\r
+                                       end if;\r
+               when DONE       =>  \r
+                               if( i2c_go_in = '1' ) then\r
+                                               NEXT_STATE <= DONE;\r
+                                               i2c_done_x <= '1';\r
+                                               running_x  <= '0';\r
+                                       else\r
+                                               NEXT_STATE <= SLEEP;\r
+                                               running_x  <= '0';\r
+                                       end if;\r
+                               -- Just in case...\r
+               when others     =>  \r
+                               NEXT_STATE <= SLEEP;\r
+       end case;\r
+end process TRANSFORM;\r
+\r
+-- Output decoding\r
+DECODE: process(CURRENT_STATE)\r
+begin\r
+       case CURRENT_STATE is\r
+               when SLEEP      =>  bsm <= b"00000"; -- 00\r
+               when LOADA      =>  bsm <= b"00001"; -- 01\r
+               when GSTART     =>  bsm <= b"00010"; -- 02\r
+               when SENDA      =>  bsm <= b"00011"; -- 03\r
+               when LOADC      =>  bsm <= b"00100"; -- 04\r
+               when SENDC      =>  bsm <= b"00101"; -- 05\r
+               when LOADD      =>  bsm <= b"00110"; -- 06\r
+               when SENDD      =>  bsm <= b"00111"; -- 07\r
+               when GSTOP      =>  bsm <= b"01000"; -- 08\r
+               when INC        =>  bsm <= b"01001"; -- 09\r
+               when FAILED     =>  bsm <= b"01010"; -- 0a\r
+               when DONE       =>  bsm <= b"01011"; -- 0b\r
+               when CLRERR     =>  bsm <= b"01100"; -- 0c\r
+               when LOADD2                     =>      bsm <= b"01101"; -- 0d\r
+               when SENDD2                     =>      bsm <= b"01110"; -- 0e\r
+               when E_START    =>  bsm <= b"10000"; -- 10\r
+               when E_RSTART   =>  bsm <= b"10001"; -- 11\r
+               when E_ADDR     =>  bsm <= b"10010"; -- 12\r
+               when E_RADDR    =>  bsm <= b"10011"; -- 13\r
+               when E_CMD      =>  bsm <= b"10100"; -- 14\r
+               when E_WD       =>  bsm <= b"10101"; -- 15\r
+               when E_WD2      =>  bsm <= b"10110"; -- 16\r
+               when others     =>  bsm <= b"11111"; -- 1f\r
+       end case;\r
+end process DECODE;\r
+\r
+-- We need to load different data sets\r
+--LOAD_DATA_PROC: process( CLOCK, RESET, CURRENT_STATE, action_in, phase)\r
+LOAD_DATA_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if   ( RESET = '1' ) then\r
+                       i2c_byte <= (others => '1');\r
+               elsif( (CURRENT_STATE = LOADA) and (phase = '0') ) then\r
+                       i2c_byte <= i2c_addr_in(7 downto 1) & '0' & '1'; -- send write address, receive ACK\r
+               elsif( (CURRENT_STATE = LOADA) and (phase = '1') ) then\r
+                       i2c_byte <= i2c_addr_in(7 downto 1) & '1' & '1'; -- send read address, receive ACK\r
+               elsif( (CURRENT_STATE = LOADC) and (action_in = '0') ) then\r
+                       i2c_byte <= i2c_cmd_in(7 downto 0) & '1'; -- send command byte (WRITE), receive ACK\r
+               elsif( (CURRENT_STATE = LOADC) and (action_in = '1') ) then\r
+                       i2c_byte <= i2c_cmd_in(7 downto 0) & '1'; -- send command byte (READ), receive ACK\r
+               elsif( (CURRENT_STATE = LOADD) and (action_in = '0') ) then\r
+                       i2c_byte <= i2c_dw_in(15 downto 8) & '1'; -- send data byte, receive ACK\r
+               elsif( (CURRENT_STATE = LOADD2) and (action_in = '0') ) then\r
+                       i2c_byte <= i2c_dw_in(7 downto 0) & '1'; -- send data byte, receive ACK\r
+               elsif( (CURRENT_STATE = LOADD) and (action_in = '1') ) then\r
+                       i2c_byte <= x"ff" & '0'; -- send 0xff byte, send ACK\r
+               elsif( (CURRENT_STATE = LOADD2) and (action_in = '1') ) then\r
+                       i2c_byte <= x"ff" & '1'; -- send 0xff byte, send NACK\r
+               end if;\r
+       end if;\r
+end process LOAD_DATA_PROC;\r
+\r
+-- The SendByte module\r
+THE_I2C_SENDB: I2C_SENDB\r
+port map(\r
+       CLK_IN          => CLOCK,\r
+       RESET_IN        => RESET,\r
+       DOBYTE_IN       => dobyte,\r
+       I2C_SPEED_IN    => i2c_speed,\r
+       I2C_BYTE_IN     => i2c_byte,\r
+       I2C_BACK_OUT    => i2c_dr,\r
+       SDA_IN          => sda_q(2), -- changed\r
+       R_SDA_OUT       => r_sda_sb,\r
+       S_SDA_OUT       => s_sda_sb,\r
+--  SCL_IN          => scl_q(2), -- changes\r
+       R_SCL_OUT       => r_scl_sb,\r
+       S_SCL_OUT       => s_scl_sb,\r
+       BDONE_OUT       => bdone,\r
+       BOK_OUT         => bok,\r
+       BSM_OUT         => open\r
+);\r
+\r
+-- The GenStart module\r
+THE_I2C_GSTART: I2C_GSTART\r
+port map(\r
+       CLK_IN          => CLOCK,\r
+       RESET_IN        => RESET,\r
+       START_IN        => start,\r
+       DOSTART_IN      => dostart,\r
+       I2C_SPEED_IN    => i2c_speed,\r
+       SDONE_OUT       => sdone,\r
+       SOK_OUT         => sok,\r
+       SDA_IN          => sda_q(2), -- changed\r
+       SCL_IN          => scl_q(2), -- changed\r
+       R_SCL_OUT       => r_scl_gs,\r
+       S_SCL_OUT       => s_scl_gs,\r
+       R_SDA_OUT       => r_sda_gs,\r
+       S_SDA_OUT       => s_sda_gs,\r
+       BSM_OUT         => open\r
+);\r
+\r
+r_scl <= r_scl_gs or r_scl_sb;\r
+s_scl <= s_scl_gs or s_scl_sb;\r
+r_sda <= r_sda_gs or r_sda_sb;\r
+s_sda <= s_sda_gs or s_sda_sb;\r
+\r
+-- Output flipflop for SCL line\r
+THE_SCL_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if( RESET = '1' ) then\r
+                       SCL_OUT <= '1';\r
+               elsif( (r_scl = '1') and (s_scl = '0') ) then\r
+                       SCL_OUT <= '0';\r
+               elsif( (r_scl = '0') and (s_scl = '1') ) then\r
+                       SCL_OUT <= '1';\r
+               end if;\r
+       end if;\r
+end process THE_SCL_PROC;\r
+\r
+-- Output flipflop for SDA line\r
+THE_SDA_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if( RESET = '1' ) then\r
+                       SDA_OUT <= '1';\r
+               elsif( (r_sda = '1') and (s_sda = '0') ) then\r
+                       SDA_OUT <= '0';\r
+               elsif( (r_sda = '0') and (s_sda = '1') ) then\r
+                       SDA_OUT <= '1';\r
+               end if;\r
+       end if;\r
+end process THE_SDA_PROC;\r
+\r
+-- Error bits\r
+THE_ERR_REG_PROC: process( CLOCK )\r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if( RESET = '1' ) then\r
+                       e_sf        <= '0';\r
+                       e_anak      <= '0';\r
+                       e_cnak      <= '0';\r
+                       e_dnak      <= '0';\r
+                       e_dnak2     <= '0';\r
+                       e_rsf       <= '0';\r
+                       e_ranak     <= '0';\r
+               elsif( CURRENT_STATE = CLRERR ) then\r
+                       e_sf        <= '0';\r
+                       e_anak      <= '0';\r
+                       e_cnak      <= '0';\r
+                       e_dnak      <= '0';\r
+                       e_dnak2     <= '0';\r
+                       e_rsf       <= '0';\r
+                       e_ranak     <= '0';\r
+               elsif( CURRENT_STATE = E_START ) then\r
+                       e_sf        <= '1';\r
+               elsif( CURRENT_STATE = E_RSTART ) then\r
+                       e_rsf       <= '1';\r
+               elsif( CURRENT_STATE = E_ADDR ) then\r
+                       e_anak      <= '1';\r
+               elsif( CURRENT_STATE = E_RADDR ) then\r
+                       e_ranak     <= '1';\r
+               elsif( CURRENT_STATE = E_CMD ) then\r
+                       e_cnak      <= '1';\r
+               elsif( CURRENT_STATE = E_WD ) then\r
+                       e_dnak      <= '1';\r
+               elsif( CURRENT_STATE = E_WD2 ) then\r
+                       e_dnak2     <= '1';\r
+               end if;\r
+       end if;\r
+end process THE_ERR_REG_PROC;\r
+\r
+-- store data read from I2C (high byte)\r
+THE_STORE_READ_H_PROC: process( CLOCK ) \r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if   ( RESET = '1' ) then\r
+                       i2c_drw(15 downto 8) <= (others => '0');\r
+               elsif( rising_edge(CLOCK) ) then\r
+                       if( load_dh = '1' ) then\r
+                               i2c_drw(15 downto 8) <= i2c_dr(8 downto 1);\r
+                       end if;\r
+               end if;\r
+       end if;\r
+end process THE_STORE_READ_H_PROC;\r
+\r
+-- store data read from I2C (low byte)\r
+THE_STORE_READ_L_PROC: process( CLOCK ) \r
+begin\r
+       if( rising_edge(CLOCK) ) then\r
+               if   ( RESET = '1' ) then\r
+                       i2c_drw(7 downto 0) <= (others => '0');\r
+               elsif( rising_edge(CLOCK) ) then\r
+                       if( load_dl = '1' ) then\r
+                               i2c_drw(7 downto 0) <= i2c_dr(8 downto 1);\r
+                       end if;\r
+               end if;\r
+       end if;\r
+end process THE_STORE_READ_L_PROC;\r
+\r
+-- Status output\r
+status_out(7) <= e_sf;\r
+status_out(6) <= e_rsf;\r
+status_out(5) <= e_anak;\r
+status_out(4) <= e_ranak;\r
+status_out(3) <= e_cnak;\r
+status_out(2) <= e_dnak;\r
+status_out(1) <= e_dnak2;\r
+status_out(0) <= '0';\r
+\r
+-- Outputs\r
+I2C_DR_OUT      <= i2c_drw;\r
+I2C_BUSY_OUT    <= running;\r
+I2C_DONE_OUT    <= i2c_done;\r
+VALID_OUT       <= valid;\r
+BSM_OUT         <= bsm;\r
+\r
+end Behavioral;\r