From: palka Date: Fri, 18 Sep 2009 15:33:43 +0000 (+0000) Subject: cahit sfp interface X-Git-Tag: oldGBE~374 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=2d83c3d7e68c79b78897b9daa3ca8befadd63303;p=trbnet.git cahit sfp interface --- diff --git a/sfp_interface.vhd b/sfp_interface.vhd new file mode 100644 index 0000000..afcda39 --- /dev/null +++ b/sfp_interface.vhd @@ -0,0 +1,557 @@ +library IEEE; +use IEEE.STD_LOGIC_UNSIGNED.ALL; +library ieee; +library work; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.all; + +entity Sfp_Interface is + generic ( + I2C_SPEED : std_logic_vector(15 downto 0) + ); + port( + CLK_IN : in std_logic; -- System clock + RST_IN : in std_logic; -- System reset +-- + START_PULSE : in std_logic; -- System start pulse + DEVICE_ADDRESS : in std_logic_vector(7 downto 0); +-- + DATA_OUT : out std_logic_vector(15 downto 0); -- Data read from optical transmitter +-- + SCL : inout std_logic; -- I2C Serial clock I/O + SDA : inout std_logic; -- I2C Serial data I/O +-- + EN_RESET : in std_logic; -- Enable signal for reset sequence +-- + READ_DONE : out std_logic; -- Reading process done + DEBUG : out std_logic_vector(31 downto 0); -- Debug output + SFP_ADDRESS : in std_logic_vector(31 downto 0) -- SFP addresses + ); + +end Sfp_Interface; +------------------------------------------------------------------------------- + +architecture behavioral of Sfp_Interface is +------------------------------------------------------------------------------- +-- Internal Lines +------------------------------------------------------------------------------- + signal scl_int : std_logic := '1'; + signal sda_int : std_logic := '1'; + signal sda_int_mem : std_logic := '1'; + signal byte_2_send : std_logic_vector(7 downto 0) := X"00"; + signal byte_2_send_mem : std_logic_vector(7 downto 0) := X"00"; + signal byte_2_read : std_logic_vector(15 downto 0) := X"0000"; + signal data_out_int : std_logic_vector(15 downto 0) := X"0000"; + signal data_out_int_mem : std_logic_vector(15 downto 0) := X"0000"; + signal bit_read : std_logic := '0'; + signal bit_read_mem : std_logic := '0'; + signal read_done_int : std_logic := '0'; +-- + signal debug_int : std_logic_vector(31 downto 0) := X"00000000"; +-- + signal en_reset_cnt : std_logic := '0'; + signal stop_reset_cnt : std_logic := '0'; + signal rst_reset_cnt : std_logic := '0'; + signal reset_cnt : std_logic_vector(3 downto 0) := "0001"; + signal reset_done : std_logic := '0'; + signal reset_done_mem : std_logic := '0'; +-- + signal en_bit_cnt : std_logic := '0'; + signal stop_bit_cnt : std_logic := '0'; + signal rst_bit_cnt : std_logic := '0'; + signal bit_cnt : std_logic_vector(5 downto 0) := "000000"; +-- + signal stop_fre_cnt : std_logic := '0'; + signal rst_fre_cnt : std_logic := '0'; + signal fre_cnt : std_logic_vector(9 downto 0) := "0000000000"; +-- + signal en_shift_reg : std_logic := '0'; + signal en_FSM : std_logic := '0'; + signal sfp_address_i : std_logic_vector(31 downto 0) := X"00000000"; + signal device_address_i : std_logic_vector(7 downto 0) := X"00"; + signal start_pulse_i : std_logic := '0'; +------------------------------------------------------------------------------- + type STATES is (IDLE, RESET_A, RESET_B, RESET_C, RESET_D, START_A, START_B, START_C, START_D, STOP_A, STOP_B, STOP_C, STOP_D, SEND_BYTE_A, SEND_BYTE_B, SEND_BYTE_C, + SEND_BYTE_D, READ_BYTE_A, READ_BYTE_B, READ_BYTE_C, READ_BYTE_D, SEND_ACK_A, SEND_ACK_B, SEND_ACK_C, SEND_ACK_D, READ_ACK_A, READ_ACK_B, READ_ACK_C, + READ_ACK_D); + signal STATE_CURRENT : STATES; + signal STATE_NEXT : STATES; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- + component up_down_counter + generic ( + NUMBER_OF_BITS : positive + ); + port ( + CLK : in std_logic; + RESET : in std_logic; + COUNT_OUT : out std_logic_vector(NUMBER_OF_BITS-1 downto 0); + UP_IN : in std_logic; + DOWN_IN : in std_logic + ); + end component; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +begin + stop_reset_cnt <= rst_in or rst_reset_cnt; + stop_bit_cnt <= rst_in or rst_bit_cnt; + stop_fre_cnt <= rst_in or rst_fre_cnt; +------------------------------------------------------------------------------- + Reset_Counter : up_down_counter + generic map ( + NUMBER_OF_BITS => 4) + port map ( + CLK => CLK_IN, + RESET => stop_reset_cnt, + COUNT_OUT => reset_cnt, + UP_IN => en_reset_cnt, + DOWN_IN => '0'); +------------------------------------------------------------------------------- + Bit_Counter : up_down_counter + generic map ( + NUMBER_OF_BITS => 6) + port map ( + CLK => CLK_IN, + RESET => stop_bit_cnt, + COUNT_OUT => bit_cnt, + UP_IN => en_bit_cnt, + DOWN_IN => '0'); +------------------------------------------------------------------------------- + Frequency_Counter : up_down_counter + generic map ( + NUMBER_OF_BITS => 10) + port map ( + CLK => CLK_IN, + RESET => stop_fre_cnt, + COUNT_OUT => fre_cnt, + UP_IN => '1', + DOWN_IN => '0'); +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- + Frequency_Division : process (CLK_IN, RST_IN, fre_cnt) + begin + if rising_edge(CLK_IN) then + if RST_IN = '1' then + en_FSM <= '0'; + rst_fre_cnt <= '0'; + elsif fre_cnt = I2C_SPEED then + en_FSM <= '1'; + rst_fre_cnt <= '1'; + else + en_FSM <= '0'; + rst_fre_cnt <= '0'; + end if; + end if; + end process Frequency_Division; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- + Address_Assingment : process (CLK_IN, RST_IN, START_PULSE) + begin + if rising_edge(CLK_IN) then + if RST_IN = '1' then + sfp_address_i <= X"00000000"; + device_address_i <= X"00"; + start_pulse_i <= '0'; + elsif START_PULSE = '1' then + sfp_address_i <= SFP_ADDRESS; + device_address_i <= DEVICE_ADDRESS; + start_pulse_i <= START_PULSE; + else + start_pulse_i <= '0'; + end if; + end if; + end process Address_Assingment; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- + Syncronising : process (CLK_IN, RST_IN) + begin + if rising_edge(CLK_IN) then + if RST_IN = '1' then + STATE_CURRENT <= IDLE; + DATA_OUT <= X"0000"; + READ_DONE <= '0'; + data_out_int_mem <= X"0000"; + byte_2_send_mem <= X"00"; + reset_done_mem <= '0'; + bit_read_mem <= '0'; + SCL <= 'Z'; + SDA <= 'Z'; + sda_int_mem <= '1'; + DEBUG <= X"00000000"; + else + STATE_CURRENT <= STATE_NEXT; + DATA_OUT <= data_out_int; + READ_DONE <= read_done_int; + data_out_int_mem <= data_out_int; + byte_2_send_mem <= byte_2_send; + reset_done_mem <= reset_done; + sda_int_mem <= sda_int; + bit_read_mem <= bit_read; + SCL <= scl_int; + SDA <= sda_int; + DEBUG <= debug_int; + end if; + end if; + end process Syncronising; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- + Shift_Register : process (CLK_IN, RST_IN, en_shift_reg) + begin + if rising_edge(CLK_IN) then + if RST_IN = '1' then + byte_2_read <= X"0000"; + elsif en_shift_reg = '1' then + byte_2_read <= byte_2_read(14 downto 0) & bit_read; + end if; + end if; + end process Shift_Register; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +-- The generation of the state machine +------------------------------------------------------------------------------- + State_Decoder : process (start_pulse_i, device_address_i, STATE_CURRENT, reset_cnt, reset_done, reset_done_mem, bit_cnt, SDA, byte_2_send_mem, byte_2_read, data_out_int_mem, en_FSM, + sda_int_mem, sfp_address_i, bit_read_mem, en_reset) + begin + en_reset_cnt <= '0'; + rst_reset_cnt <= '0'; + en_bit_cnt <= '0'; + rst_bit_cnt <= '0'; + en_shift_reg <= '0'; + sda_int <= 'Z'; + scl_int <= 'Z'; + byte_2_send <= byte_2_send_mem; + data_out_int <= data_out_int_mem; + reset_done <= reset_done_mem; + bit_read <= bit_read_mem; + read_done_int <= '0'; + STATE_NEXT <= STATE_CURRENT; + + case (STATE_CURRENT) is +--IDLE + when IDLE => + debug_int(7 downto 0) <= x"01"; + if device_address_i = X"06" and start_pulse_i = '1' and EN_RESET = '1' and reset_done = '0' then + STATE_NEXT <= RESET_C; + elsif device_address_i = X"06" and start_pulse_i = '1' and (reset_done = '1' or EN_RESET = '0') then + STATE_NEXT <= START_A; + else + STATE_NEXT <= IDLE; + end if; +--RESET + when RESET_A => + debug_int(7 downto 0) <= x"02"; + scl_int <= '0'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= RESET_B; + end if; +-- + when RESET_B => + debug_int(7 downto 0) <= x"03"; + scl_int <= '0'; + sda_int <= '1'; + if reset_cnt = "1000" and en_FSM = '1' then + STATE_NEXT <= START_C; + rst_reset_cnt <= '1'; + reset_done <= '1'; + elsif en_FSM = '1' then + STATE_NEXT <= RESET_C; + en_reset_cnt <= '1'; + end if; +-- + when RESET_C => + debug_int(7 downto 0) <= x"04"; + scl_int <= '1'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= RESET_D; + end if; +-- + when RESET_D => + debug_int(7 downto 0) <= x"05"; + scl_int <= '1'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= RESET_A; + end if; +--START + when START_A => + debug_int(7 downto 0) <= x"07"; + scl_int <= '0'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= START_B; + end if; +-- + when START_B => + debug_int(7 downto 0) <= x"08"; + scl_int <= '0'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= START_C; + end if; +-- + when START_C => + debug_int(7 downto 0) <= x"09"; + scl_int <= '1'; + sda_int <= '1'; + if en_FSM = '1' then + STATE_NEXT <= START_D; + end if; +-- + when START_D => + debug_int(7 downto 0) <= x"0A"; + scl_int <= '1'; + sda_int <= '0'; + if bit_cnt = "010011" and en_FSM = '1' then + byte_2_send <= sfp_address_i(7 downto 1) & '1'; + STATE_NEXT <= SEND_BYTE_A; + en_bit_cnt <= '1'; + elsif bit_cnt = "000000" and en_FSM = '1' then + byte_2_send <= sfp_address_i(7 downto 1) & '0'; + STATE_NEXT <= SEND_BYTE_A; + en_bit_cnt <= '1'; + elsif en_FSM = '0' then + STATE_NEXT <= STATE_CURRENT; + else + byte_2_send <= X"00"; + STATE_NEXT <= IDLE; + end if; +--STOP + when STOP_A => + debug_int(7 downto 0) <= x"0B"; + scl_int <= '0'; + sda_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= STOP_B; + end if; +-- + when STOP_B => + debug_int(7 downto 0) <= x"0C"; + scl_int <= '0'; + sda_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= STOP_C; + end if; +-- + when STOP_C => + debug_int(7 downto 0) <= x"0D"; + scl_int <= '1'; + sda_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= STOP_D; + end if; +-- + when STOP_D => + debug_int(7 downto 0) <= x"0E"; + scl_int <= '1'; + sda_int <= '1'; + rst_bit_cnt <= '1'; + if en_FSM = '1' then + STATE_NEXT <= IDLE; + end if; +--SEND_BYTE + when SEND_BYTE_A => + debug_int(7 downto 0) <= x"0F"; + scl_int <= '0'; + sda_int <= byte_2_send(7); + if en_FSM = '1' then + STATE_NEXT <= SEND_BYTE_B; + end if; +-- + when SEND_BYTE_B => + debug_int(7 downto 0) <= x"10"; + scl_int <= '0'; + sda_int <= byte_2_send(7); + if en_FSM = '1' then + STATE_NEXT <= SEND_BYTE_C; + end if; +-- + when SEND_BYTE_C => + debug_int(7 downto 0) <= x"11"; + scl_int <= '1'; + sda_int <= byte_2_send(7); + if en_FSM = '1' then + STATE_NEXT <= SEND_BYTE_D; + end if; +-- + when SEND_BYTE_D => + debug_int(7 downto 0) <= x"12"; + scl_int <= '1'; + sda_int <= byte_2_send(7); + if (bit_cnt = "001000" or bit_cnt = "010001" or bit_cnt = "011011") and en_FSM = '1' then + STATE_NEXT <= READ_ACK_A; + byte_2_send <= byte_2_send_mem(6 downto 0) & byte_2_send_mem(7); + en_bit_cnt <= '1'; + en_shift_reg <= '1'; + elsif en_FSM = '1' then + STATE_NEXT <= SEND_BYTE_A; + byte_2_send <= byte_2_send_mem(6 downto 0) & byte_2_send_mem(7); + en_bit_cnt <= '1'; + en_shift_reg <= '1'; + else + STATE_NEXT <= STATE_CURRENT; + end if; +--READ_BYTE + when READ_BYTE_A => + debug_int(7 downto 0) <= x"13"; + scl_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= READ_BYTE_B; + end if; +-- + when READ_BYTE_B => + debug_int(7 downto 0) <= x"14"; + scl_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= READ_BYTE_C; + end if; +-- + when READ_BYTE_C => + debug_int(7 downto 0) <= x"15"; + scl_int <= '1'; + bit_read <= SDA; + if en_FSM = '1' then + STATE_NEXT <= READ_BYTE_D; + end if; +-- + when READ_BYTE_D => + debug_int(7 downto 0) <= x"16"; + scl_int <= '1'; + if (bit_cnt = "100100" or bit_cnt = "101100") and en_FSM = '1' then + STATE_NEXT <= SEND_ACK_A; + en_bit_cnt <= '1'; + en_shift_reg <= '1'; + elsif en_FSM = '1' then + STATE_NEXT <= READ_BYTE_A; + en_bit_cnt <= '1'; + en_shift_reg <= '1'; + else + STATE_NEXT <= STATE_CURRENT; + end if; +--SEND_ACK + when SEND_ACK_A => + debug_int(7 downto 0) <= x"17"; + scl_int <= '0'; + if bit_cnt = "101101" then + sda_int <= '1'; + elsif bit_cnt = "100101" then + sda_int <= '0'; + else + sda_int <= 'X'; + end if; + if en_FSM = '1' then + STATE_NEXT <= SEND_ACK_B; + end if; +-- + when SEND_ACK_B => + debug_int(7 downto 0) <= x"18"; + scl_int <= '0'; + if bit_cnt = "101101" then + sda_int <= '1'; + elsif bit_cnt = "100101" then + sda_int <= '0'; + else + sda_int <= 'X'; + end if; + if en_FSM = '1' then + STATE_NEXT <= SEND_ACK_C; + end if; +-- + when SEND_ACK_C => + debug_int(7 downto 0) <= x"19"; + scl_int <= '1'; + if bit_cnt = "101101" then + sda_int <= '1'; + elsif bit_cnt = "100101" then + sda_int <= '0'; + else + sda_int <= 'X'; + end if; + if en_FSM = '1' then + STATE_NEXT <= SEND_ACK_D; + end if; +-- + when SEND_ACK_D => + debug_int(7 downto 0) <= x"1A"; + scl_int <= '1'; + if bit_cnt = "101101" and en_FSM = '1' then + sda_int <= '1'; + STATE_NEXT <= STOP_A; + data_out_int <= byte_2_read; + read_done_int <= '1'; + elsif bit_cnt = "100101" and en_FSM = '1' then + sda_int <= '0'; + STATE_NEXT <= READ_BYTE_A; + elsif en_FSM = '0' then + sda_int <= sda_int_mem; + STATE_NEXT <= STATE_CURRENT; + else + sda_int <= 'X'; + STATE_NEXT <= IDLE; + end if; +--READ_ACK + when READ_ACK_A => + debug_int(7 downto 0) <= x"1B"; + scl_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= READ_ACK_B; + end if; +-- + when READ_ACK_B => + debug_int(7 downto 0) <= x"1C"; + scl_int <= '0'; + if en_FSM = '1' then + STATE_NEXT <= READ_ACK_C; + end if; +-- + when READ_ACK_C => + debug_int(7 downto 0) <= x"1D"; + scl_int <= '1'; + bit_read <= SDA; + if en_FSM = '1' then + STATE_NEXT <= READ_ACK_D; + end if; +-- + when READ_ACK_D => + debug_int(7 downto 0) <= x"1E"; + scl_int <= '1'; + if bit_read = '0' and bit_cnt = "001001" and en_FSM = '1' then + STATE_NEXT <= SEND_BYTE_A; + byte_2_send <= sfp_address_i(15 downto 8); + en_bit_cnt <= '1'; + elsif bit_read = '0' and bit_cnt = "010010" and en_FSM = '1' then + STATE_NEXT <= START_A; + en_bit_cnt <= '1'; + elsif bit_read = '0' and bit_cnt = "011100" and en_FSM = '1' then + STATE_NEXT <= READ_BYTE_A; + en_bit_cnt <= '1'; + elsif bit_read = '1' and en_FSM = '1' then + STATE_NEXT <= STOP_A; + en_bit_cnt <= '1'; + elsif en_FSM = '0' then + STATE_NEXT <= STATE_CURRENT; + else + STATE_NEXT <= IDLE; + end if; +--OTHERS + when others => + debug_int(7 downto 0) <= x"1F"; + scl_int <= '1'; + sda_int <= '1'; + byte_2_send <= X"00"; + STATE_NEXT <= IDLE; + + end case; +end process State_Decoder; +------------------------------------------------------------------------------- + +end behavioral;