]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
cahit sfp interface
authorpalka <palka>
Fri, 18 Sep 2009 15:33:43 +0000 (15:33 +0000)
committerpalka <palka>
Fri, 18 Sep 2009 15:33:43 +0000 (15:33 +0000)
sfp_interface.vhd [new file with mode: 0644]

diff --git a/sfp_interface.vhd b/sfp_interface.vhd
new file mode 100644 (file)
index 0000000..afcda39
--- /dev/null
@@ -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;