06-27-2018 01:06 PM
06-27-2018 01:57 PM
06-27-2018 02:39 PM
Here you are.
I know it's a bit long and contains debug-comments as well as debug-loop - sorry for that.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.MATH_REAL.ALL; --24Cxx Fmax = 100 kHz (up to 3,3V), p_ClockDivider sets ClockEEPROM always to 100 kHz --Device address: 1 0 1 0 A2 A1 A0 RnW when addressing memory array entity EEPROM_24Cxx is Generic ( MEM_SIZE : INTEGER := 12; --24C32: 12, 24C64: 13 MEM_ADDR : STD_LOGIC_VECTOR := "001"; --I2C memory address CLOCK_FREQ : INTEGER := 100000000 ); Port ( Reset : in STD_LOGIC; Clock : in STD_LOGIC; f_MemBusy : out STD_LOGIC; f_DataReady : out STD_LOGIC; f_TransmissionTrig : in STD_LOGIC; --triggers I2C transmission f_TransmissionDone : out STD_LOGIC; f_TransmissionRnW : in STD_LOGIC; --0 - Write, 1 - Read DataAddr : in STD_LOGIC_VECTOR(MEM_SIZE-1 downto 0); DataIn : in STD_LOGIC_VECTOR(7 downto 0); DataOut : out STD_LOGIC_VECTOR(7 downto 0); f_MemNotResponding : out STD_LOGIC; A : out STD_LOGIC_VECTOR(2 downto 0); -- WP : out STD_LOGIC; SCL : out STD_LOGIC; --max 100 kHz SDA : inout STD_LOGIC ); end EEPROM_24Cxx; architecture Behavioral of EEPROM_24Cxx is constant EEPROM_MAX_FREQ : INTEGER := 100000; constant DIVIDER : INTEGER := (integer(ceil(real(CLOCK_FREQ)/real(EEPROM_MAX_FREQ)))/8-1); -- 4 stany na 1 ck + polowa okresu --(integer(ceil(real(CLOCK_FREQ)/real(EEPROM_MAX_FREQ)))/2-1); constant MEM_ADDR_MSB : STD_LOGIC_VECTOR(3 downto 0) := "1010"; constant MemAddr : STD_LOGIC_VECTOR(6 downto 0) := "1010001"; --MEM_ADDR_MSB & MEM_ADDR; type StateMem_type is (Idle, Start1, Start2, Addr1, Addr2, Addr3, Addr4, RnW1, RnW2, RnW3, RnW4, CheckAck1, CheckAck2, CheckAck3, CheckAck4, WriteAddr1, WriteAddr2, WriteAddr3, WriteAddr4, WriteAddr5, WriteAddr6, WriteAddr7, WriteAddr8, WriteAddrAck1, WriteAddrAck2, WriteAddrAck3, WriteAddrAck4, WriteAddrAck20, WriteAddrAck21, WriteAddrAck22, WriteAddrAck23, WriteAddrAck24, ReadDataStart1, ReadDataStart2, ReadDataStart3, ReadDevAddr1, ReadDevAddr2, ReadDevAddr3, ReadDevAddr4, ReadRnW1, ReadRnW2, ReadRnW3, ReadRnW4, ReadCheckAck1, ReadCheckAck2, ReadCheckAck3, ReadCheckAck4, ReadData1, ReadData2, ReadData3, ReadData4, WriteData1, WriteData2, WriteData3, WriteData4, WriteDataAck31, WriteDataAck32, WriteDataAck33, WriteDataAck34, StopReadAck, StopReadAck2, StopReadAck3, StopReadAck4, Stop1, Stop2, Stop3, Stop4, Stop5 ); signal StateMem : StateMem_type; -- attribute fsm_encoding of StateMem : signal is "gray"; signal ClockEEPROM : STD_LOGIC := '0'; --4x SCL (StateMemHigh, StateMemLow) signal CounterBits : STD_LOGIC_VECTOR(4 downto 0) := (others => '0'); signal f_MemBusy_int : STD_LOGIC := '0'; signal f_DataReady_int : STD_LOGIC := '0'; signal f_MemNotResponding_int : STD_LOGIC := '0'; signal MemAck : STD_LOGIC := '0'; signal RnW_int : STD_LOGIC := '0'; --signal MemAddr : STD_LOGIC_VECTOR(6 downto 0) := MEM_ADDR_MSB & MEM_ADDR; signal DataAddr_int : STD_LOGIC_VECTOR(15 downto 0) := (others => '0'); signal DataIn_int : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal DataOut_int : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); signal Countertymczasowy : STD_LOGIC_VECTOR(7 downto 0) := (others => '0'); begin p_MemData : process(Reset, Clock, ClockEEPROM, f_TransmissionTrig, DataAddr_int, DataIn_int) begin if (Reset = '0') then --f_DataReady_int <= '0'; SDA <= '1'; SCL <= '1'; MemAck <= '0'; DataOut_int <= (others => '0'); -- MemAddr <= MEM_ADDR_MSB & MEM_ADDR; elsif (ClockEEPROM'Event and ClockEEPROM = '1') then --process defaults -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; --f_DataReady_int <= '0'; case StateMem is when Idle => SDA <= 'Z'; --'1'; SCL <= 'Z'; --'1'; -- RnW_int <= RnW_int; -- DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; -- if (f_TransmissionTrig = '1') then DataAddr_int <= x"81AF"; --"0000" & DataAddr; --(15 downto MEM_SIZE => '0') x"FA0F"; -- DataIn_int <= x"A9"; --DataIn; --x"85"; --x"FF"; -- RnW_int <= '0'; --f_TransmissionRnW; if (Countertymczasowy = x"08") then StateMem <= Start1; Countertymczasowy <= (others => '0'); else Countertymczasowy <= Countertymczasowy + 1; StateMem <= Idle; end if; -- else -- DataAddr_int <= x"80AF"; --(15 downto MEM_SIZE => '0') & DataAddr; -- DataIn_int <= x"AA"; --DataIn; -- RnW_int <= '0'; --f_TransmissionRnW; -- StateMem <= Start1; --Idle; -- end if; --I2C start sequence when Start1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Start2; when Start2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= Addr1; --I2C device addr when Addr1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '0'; CounterBits <= CounterBits; StateMem <= Addr2; when Addr2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= Addr3; when Addr3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= Addr4; when Addr4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '0'; if (CounterBits < "00110") then CounterBits <= CounterBits + 1; StateMem <= Addr1; else CounterBits <= (others => '0'); StateMem <= RnW1; end if; --I2C Read/Write when RnW1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= RnW_int; --'0'; -- SCL <= '0'; CounterBits <= (others => '0'); StateMem <= RnW2; when RnW2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= RnW_int; --'0'; -- SCL <= '1'; StateMem <= RnW3; CounterBits <= (others => '0'); when RnW3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= RnW_int; --'0'; -- SCL <= '1'; StateMem <= RnW4; CounterBits <= (others => '0'); when RnW4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= RnW_int; --'0'; -- SCL <= '0'; StateMem <= CheckAck1; CounterBits <= (others => '0'); --I2C acknowledge check when CheckAck1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; -- MemAck <= SDA; SDA <= 'Z'; SCL <= '0'; StateMem <= CheckAck2; CounterBits <= (others => '0'); when CheckAck2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; -- StateMem <= CheckAck3; CounterBits <= (others => '0'); if (MemAck = '0') then StateMem <= CheckAck4; else -- f_MemNotResponding_int <= '1'; StateMem <= CheckAck3; --Idle; end if; --petla blokujaca przy braku potwierdzenia when CheckAck3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; CounterBits <= (others => '0'); -- if (MemAck = '0') then StateMem <= CheckAck4; -- else ---- f_MemNotResponding_int <= '1'; -- StateMem <= CheckAck3; --Idle; -- end if; when CheckAck4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '0'; CounterBits <= (others => '0'); -- if (RnW_int = '0') then -- StateMem <= Read1; -- else StateMem <= WriteAddr1; --ok Idle; -- -- end if; --I2C memory addr write when WriteAddr1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(15 - to_integer(unsigned(CounterBits))); SCL <= '0'; CounterBits <= CounterBits; StateMem <= WriteAddr2; when WriteAddr2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(15 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteAddr3; when WriteAddr3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(15 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteAddr4; when WriteAddr4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(15 - to_integer(unsigned(CounterBits))); SCL <= '0'; if (CounterBits < "00111") then --01000 CounterBits <= CounterBits + 1; StateMem <= WriteAddr1; else StateMem <= WriteAddrAck1; end if; when WriteAddrAck1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; --MemAck <= SDA; SCL <= '0'; StateMem <= WriteAddrAck2; CounterBits <= (others => '0'); when WriteAddrAck2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; -- SDA <= 'Z'; MemAck <= SDA; SCL <= '1'; StateMem <= WriteAddrAck3; CounterBits <= (others => '0'); when WriteAddrAck3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; CounterBits <= (others => '0'); if (MemAck = '0') then --debug StateMem <= WriteAddr5; --WriteAddrAck4; --srednik else -- f_MemNotResponding_int <= '1'; StateMem <= WriteAddrAck4; --Idle; -- WriteAddrAck3; --Idle; end if; when WriteAddrAck4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= MemAck; SDA <= 'Z'; SCL <= '0'; CounterBits <= (others => '0'); if (MemAck = '0') then --debug StateMem <= WriteAddr5; else -- f_MemNotResponding_int <= '1'; StateMem <= WriteAddrAck3; --Idle; end if; when WriteAddr5 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(7 - to_integer(unsigned(CounterBits))); --15 SCL <= '0'; CounterBits <= CounterBits; StateMem <= WriteAddr6; when WriteAddr6 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(7 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteAddr7; when WriteAddr7 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(7 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteAddr8; when WriteAddr8 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataAddr_int(7 - to_integer(unsigned(CounterBits))); SCL <= '0'; if (CounterBits < "00111") then -- CounterBits <= CounterBits + 1; StateMem <= WriteAddr5; else CounterBits <= (others => '0'); StateMem <= WriteAddrAck21; ---> trzy zera SCL Idle; --WriteAddrAck21; -- end if; -- when WriteAddrAck20 => --numeracja: drugie sprawdzanie, stany 1-4: 21, 22, 23, 24 -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; -- SDA <= 'Z'; --'0'; -- SCL <= '0'; -- StateMem <= WriteAddrAck21; -- CounterBits <= (others => '0'); when WriteAddrAck21 => --numeracja: drugie sprawdzanie, stany 1-4: 21, 22, 23, 24 RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; SCL <= '0'; StateMem <= WriteAddrAck22; CounterBits <= (others => '0'); when WriteAddrAck22 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; StateMem <= WriteAddrAck23; --nie ok CounterBits <= (others => '0'); when WriteAddrAck23 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; CounterBits <= (others => '0'); if (MemAck = '0') then if (RnW_int = '0') then --write data StateMem <= WriteData1; --WriteAddrAck24; elsif (RnW_int = '1') then --read data -- rozgalezienie read/write StateMem <= ReadDataStart1; --Start1; -- end if; else -- f_MemNotResponding_int <= '1'; StateMem <= WriteAddrAck24; --Idle; Idle; -- end if; when WriteAddrAck24 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= MemAck; SDA <= 'Z'; SCL <= '0'; CounterBits <= (others => '0'); if (MemAck = '0') then if (RnW_int = '0') then --write data StateMem <= WriteData1; --WriteAddrAck24; elsif (RnW_int = '1') then --read data -- rozgalezienie read/write StateMem <= ReadDataStart1; --Start1; -- end if; else -- f_MemNotResponding_int <= '1'; StateMem <= WriteAddrAck23; --Idle;Idle; -- end if; -- if (MemAck = '0') then -- StateMem <= WriteData1; -- else -- f_MemNotResponding_int <= '1'; -- StateMem <= WriteAddrAck24; --Idle; -- end if; --read: here device address one more time -- start -- device addr + R=1 -- ack check -- read 8 bits -- stop --I2C start sequence when ReadDataStart1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= ReadDataStart2; when ReadDataStart2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= ReadDataStart3; when ReadDataStart3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= ReadDevAddr1; --I2C device addr when ReadDevAddr1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '0'; CounterBits <= CounterBits; StateMem <= ReadDevAddr2; when ReadDevAddr2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= ReadDevAddr3; when ReadDevAddr3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= ReadDevAddr4; when ReadDevAddr4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= MemAddr(6 - to_integer(unsigned(CounterBits))); SCL <= '0'; if (CounterBits < "00110") then CounterBits <= CounterBits + 1; StateMem <= ReadDevAddr1; else CounterBits <= (others => '0'); StateMem <= ReadRnW1; end if; --I2C Read/Write when ReadRnW1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; --nRW; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= ReadRnW2; when ReadRnW2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; --nRW; SCL <= '1'; StateMem <= ReadRnW3; CounterBits <= (others => '0'); when ReadRnW3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; --nRW; SCL <= '1'; StateMem <= ReadRnW4; CounterBits <= (others => '0'); when ReadRnW4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; --nRW; SCL <= '0'; StateMem <= ReadCheckAck1; CounterBits <= (others => '0'); --I2C acknowledge check when ReadCheckAck1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; --MemAck <= SDA; SCL <= '0'; StateMem <= ReadCheckAck2; CounterBits <= (others => '0'); when ReadCheckAck2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; -- StateMem <= ReadCheckAck3; CounterBits <= (others => '0'); if (MemAck = '0') then StateMem <= ReadData1; else -- f_MemNotResponding_int <= '1'; StateMem <= ReadCheckAck3; --Idle; end if; when ReadCheckAck3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; CounterBits <= (others => '0'); -- StateMem <= ReadCheckAck4; if (MemAck = '0') then StateMem <= ReadData1; else -- f_MemNotResponding_int <= '1'; StateMem <= ReadCheckAck4; --Idle; end if; when ReadCheckAck4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '0'; CounterBits <= (others => '0'); if (MemAck = '0') then StateMem <= ReadData1; else -- f_MemNotResponding_int <= '1'; StateMem <= ReadCheckAck4; --Idle; end if; when ReadData1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; DataOut_int(7 - to_integer(unsigned(CounterBits))) <= SDA; SCL <= '0'; CounterBits <= CounterBits; StateMem <= ReadData2; when ReadData2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; DataOut_int(7 - to_integer(unsigned(CounterBits))) <= SDA; SCL <= '1'; CounterBits <= CounterBits; StateMem <= ReadData3; when ReadData3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; DataOut_int(7 - to_integer(unsigned(CounterBits))) <= SDA; SCL <= '1'; CounterBits <= CounterBits; StateMem <= ReadData4; when ReadData4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; DataOut_int(7 - to_integer(unsigned(CounterBits))) <= SDA; SCL <= '0'; if (CounterBits < "0111") then CounterBits <= CounterBits + 1; StateMem <= ReadData1; else -- f_DataReady_int <= '1'; CounterBits <= (others => '0'); StateMem <= StopReadAck; --Stop1; end if; --I2C data write when WriteData1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataIn_int(7 - to_integer(unsigned(CounterBits))); SCL <= '0'; CounterBits <= CounterBits; StateMem <= WriteData2; when WriteData2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataIn_int(7 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteData3; when WriteData3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataIn_int(7 - to_integer(unsigned(CounterBits))); SCL <= '1'; CounterBits <= CounterBits; StateMem <= WriteData4; when WriteData4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= DataIn_int(7 - to_integer(unsigned(CounterBits))); SCL <= '0'; if (CounterBits < "0111") then --1000 CounterBits <= CounterBits + 1; StateMem <= WriteData1; else CounterBits <= (others => '0'); StateMem <= WriteDataAck31; --Idle;-- here end if; when WriteDataAck31 => --numeracja: trzecie sprawdzanie RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; -- MemAck <= SDA; SCL <= '0'; -- if (MemAck = '0') then -- StateMem <= Idle; -- Stop1;StopReadAck; -- -- else -- StateMem <= WriteDataAck31; --Idle; -- -- end if; StateMem <= WriteDataAck32; --Idle; -- CounterBits <= (others => '0'); when WriteDataAck32 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; -- SDA <= 'Z'; MemAck <= SDA; SCL <= '1'; StateMem <= WriteDataAck33; CounterBits <= (others => '0'); when WriteDataAck33 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= SDA; SCL <= '1'; CounterBits <= (others => '0'); if (MemAck = '0') then StateMem <= Idle; --StopReadAck; --Stop1; --WriteDataAck34; --Stop2; -- else -- f_MemNotResponding_int <= '1'; StateMem <= WriteDataAck34; --Idle; --Stop1; --Idle; --WriteDataAck34; --Stop2; --Idle; --WriteDataAck34; --WriteDataAck33; end if; when WriteDataAck34 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; MemAck <= MemAck; SDA <= 'Z'; SCL <= '0'; CounterBits <= (others => '0'); -- if (MemAck = '0') then StateMem <= Stop2; --Idle; --chyba ok, trzyma ack w dole po przejsciu do idle -- else ---- f_MemNotResponding_int <= '1'; -- StateMem <= WriteDataAck34; --debugStop1; -- -- end if; --I2C stop sequence when StopReadAck => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= StopReadAck2; when StopReadAck2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= StopReadAck3; when StopReadAck3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Stop2; --StopReadAck4; when StopReadAck4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= 'Z'; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= Stop1; -- when StopReadAck => -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; -- SDA <= 'Z'; -- SCL <= '0'; -- CounterBits <= (others => '0'); -- StateMem <= StopReadAck2; -- when StopReadAck2 => -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; -- SDA <= 'Z'; -- SCL <= '1'; -- CounterBits <= (others => '0'); -- StateMem <= StopReadAck3; -- when StopReadAck3 => -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; -- SDA <= 'Z'; -- SCL <= '1'; -- CounterBits <= (others => '0'); -- StateMem <= Stop4; --StopReadAck4; -- when StopReadAck4 => -- RnW_int <= RnW_int; -- DataAddr_int <= DataAddr_int; -- DataIn_int <= DataIn_int; -- DataOut_int <= DataOut_int; -- SDA <= 'Z'; -- SCL <= '0'; -- CounterBits <= (others => '0'); -- StateMem <= Stop1; when Stop1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '0'; CounterBits <= (others => '0'); StateMem <= Stop2; --Idle; -- when Stop2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Stop3; --Idle; -- when Stop3 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Idle; --Stop4; when Stop4 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Stop5; when Stop5 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Idle; --Idle; -- when others => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '1'; SCL <= '1'; CounterBits <= (others => '0'); StateMem <= Idle; end case; end if; end process p_MemData; p_Flagger : process(Reset, Clock, StateMem, CounterBits) begin if (Reset = '0') then f_MemBusy_int <= '0'; elsif (Clock'Event and Clock = '1') then case StateMem is when Idle => f_MemBusy_int <= '0'; f_TransmissionDone <= '0'; f_DataReady_int <= '0'; when StopReadAck => f_MemBusy_int <= '1'; f_TransmissionDone <= '0'; --if (CounterBits = "01110") then f_DataReady_int <= '1'; when Stop5 => f_MemBusy_int <= '1'; f_TransmissionDone <= '1'; --if (CounterBits = "01110") then f_DataReady_int <= '0'; -- when ReadData4 => -- f_MemBusy_int <= '1'; -- --if (CounterBits = "01110") then -- f_DataReady_int <= '1'; --else -- f_DataReady_int <= '0'; --end if; when others => f_MemBusy_int <= '1'; f_TransmissionDone <= '0'; f_DataReady_int <= '0'; end case; end if; end process p_Flagger; p_ClockDivider : process(Reset, Clock) variable CounterDivider : INTEGER := 0; begin if (Reset = '0') then CounterDivider := 0; ClockEEPROM <= '0'; elsif (Clock'Event and Clock = '1') then if (CounterDivider = DIVIDER) then ClockEEPROM <= not ClockEEPROM; CounterDivider := 0; else CounterDivider := CounterDivider + 1; end if; end if; end process p_ClockDivider; A <= MEM_ADDR; DataOut <= DataOut_int; f_MemBusy <= f_MemBusy_int; f_DataReady <= f_DataReady_int; f_MemNotResponding <= f_MemNotResponding_int; end Behavioral;
06-28-2018 12:09 AM
One Big issue - You have a generated clock. Using logic to generate clocks is generally bad as your new clock can have high skew and be heavily affected by temperature, voltage etc. It is much better to use a clock enable rather than a generated clock.
06-28-2018 12:27 AM
06-28-2018 09:06 AM
Another question arises - how to clock a state machine with ~100 kHz clock in FPGA? It is much slower than what I can achieve with ClockingWizard from 100 MHz source.
06-28-2018 11:07 AM
07-03-2018 04:40 AM
Okay, I changed state switching to code below (with TickEEPROM as EN), what resulted in synthesized registers with EN (checked it in synthesized schematic).
Signal TickEEPROM is generated as '1' for 1ck as below.
Result is the same as with previous code - code latches in the same place.
According to your advice, I wondered how to use clock enable directly on SCL, but I can't actually imagine now how to generate and synchronise 100 kHz clock with state machine. Anybody could give another clue?
when Start1 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '1'; CounterBits <= (others => '0'); -- StateMem <= Start2; if (TickEEPROM = '1') then StateMem <= Start2; else StateMem <= Start1; end if; when Start2 => RnW_int <= RnW_int; DataAddr_int <= DataAddr_int; DataIn_int <= DataIn_int; DataOut_int <= DataOut_int; SDA <= '0'; SCL <= '0'; CounterBits <= (others => '0'); -- StateMem <= Addr1; if (TickEEPROM = '1') then StateMem <= Addr1; else StateMem <= Start2; end if;
p_ClockDivider : process(Reset, Clock) variable CounterDivider : INTEGER range 0 to DIVIDER := 0; begin if (Reset = '0') then CounterDivider := 0; ClockEEPROM <= '0'; elsif (Clock'Event and Clock = '1') then if (CounterDivider = DIVIDER) then TickEEPROM <= '1'; CounterDivider := 0; else TickEEPROM <= '0'; CounterDivider := CounterDivider + 1; end if; end if; end process p_ClockDivider;
07-05-2018 02:05 AM
If SCL is only 100Kz you should be able to sample that with your system clock (assuming safe CDC). Then you can use an edge detector to generate the enable for your registers.