]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
reworked SFP I2C interface. Automatic reading, not yet working
authorJan Michel <j.michel@gsi.de>
Wed, 10 Jul 2013 17:19:53 +0000 (19:19 +0200)
committerJan Michel <j.michel@gsi.de>
Wed, 10 Jul 2013 17:19:53 +0000 (19:19 +0200)
sfp_interface.vhd
special/sfp_i2c_readout.vhd [new file with mode: 0644]
trb_net_components.vhd

index e7a2705d5a7e5028e03b9016cb2bee1ef7110e4e..3577341b538b36a5b028e67c4770bac458ffcef1 100644 (file)
@@ -22,7 +22,7 @@ entity Sfp_Interface is
     RST_IN            : in    std_logic;                        -- System reset
 -- host side
     START_PULSE       : in    std_logic;                        -- System start pulse
-    DEVICE_ADDRESS    : in    std_logic_vector(7 downto 0);     -- Device address input: x"06" for SFP_Interface
+    DEVICE_ADDRESS    : in    std_logic_vector(7 downto 0) :=x"06";     -- Device address input: x"06" for SFP_Interface
     DATA_OUT          : out   std_logic_vector(15 downto 0);    -- Data output from optical transmitter
     READ_DONE         : out   std_logic;                        -- Reading process done
     SFP_ADDRESS       : in    std_logic_vector(7 downto 0);     -- SFP address
@@ -34,8 +34,8 @@ entity Sfp_Interface is
 -- x"68" => Measured RX optical input power                   |
 ---------------------------------------------------------------
 -- optical transceiver side
-    SCL               : inout std_logic;                        -- I2C Serial clock I/O
-    SDA               : inout std_logic;                        -- I2C Serial data I/O
+    SCL               : out std_logic_vector(15 downto 0);                          -- I2C Serial clock I/O
+    SDA               : inout std_logic_vector(15 downto 0);                          -- I2C Serial data I/O
     DEBUG             : out   std_logic_vector(31 downto 0)
     );
 
@@ -77,10 +77,11 @@ architecture behavioral of Sfp_Interface is
   signal en_shift_reg     : std_logic                     := '0';
   signal en_FSM           : std_logic                     := '0';
   signal sfp_address_i    : std_logic_vector(7 downto 0)  := x"00";
-  signal device_address_i : std_logic_vector(7 downto 0)  := x"00";
+  signal device_address_i : std_logic_vector(7 downto 0)  := x"06";
   signal start_pulse_i    : std_logic                     := '0';
 --
   signal debug_signal     : std_logic_vector(31 downto 0) := x"00000000";
+  signal select_line      : integer range 0 to 15;
 -------------------------------------------------------------------------------
   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,
@@ -91,58 +92,37 @@ architecture behavioral of Sfp_Interface is
   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 => 16)
-    port map (
-        CLK            => CLK_IN,
-        RESET          => stop_fre_cnt,
-        COUNT_OUT      => fre_cnt,
-        UP_IN          => '1',
-        DOWN_IN        => '0');
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
+  select_line            <= to_integer(unsigned(DEVICE_ADDRESS(3 downto 0)));
+  
+  proc_counters : process begin
+    wait until rising_edge(CLK_IN);
+    if stop_fre_cnt = '1' then
+      fre_cnt <= x"0000";
+    else
+      fre_cnt <= std_logic_vector(unsigned(fre_cnt)+1);
+    end if;
+    
+    if stop_bit_cnt = '1' then
+      bit_cnt <= "000000";
+    elsif en_bit_cnt = '1' then
+      bit_cnt <= std_logic_vector(unsigned(bit_cnt)+1);
+    end if;
+
+    if stop_reset_cnt = '1' then
+      reset_cnt <= "0000";
+    elsif en_reset_cnt = '1' then
+      reset_cnt <= std_logic_vector(unsigned(reset_cnt)+1);
+    end if;
+    
+    
+  end process;
+
   Frequency_Division : process (CLK_IN, RST_IN, fre_cnt)
   begin
     if rising_edge(CLK_IN) then
@@ -187,8 +167,8 @@ begin
         byte_2_send_mem  <= x"00";
         reset_done_mem   <= '0';
         bit_read_mem     <= '0';
-        SCL              <= 'Z';
-        SDA              <= 'Z';
+        SCL              <= (others => 'Z');
+        SDA              <= (others => 'Z');
         sda_int_mem      <= '1';
         DEBUG            <= x"00000000";
       else
@@ -200,8 +180,8 @@ begin
         reset_done_mem   <= reset_done;
         sda_int_mem      <= sda_int;
         bit_read_mem     <= bit_read;
-        SCL              <= scl_int;
-        SDA              <= sda_int;
+        SCL              <= (others => scl_int);
+        SDA              <= (others => sda_int);
         DEBUG            <= debug_signal;
       end if;
     end if;
@@ -244,9 +224,9 @@ begin
     case (STATE_CURRENT) is
 --IDLE
       when IDLE        =>
-        if device_address_i = x"06" and start_pulse_i = '1' and reset_done = '0' then
+        if start_pulse_i = '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' then
+        elsif start_pulse_i = '1' and reset_done = '1' then
           STATE_NEXT    <= START_A;
         else
           STATE_NEXT    <= IDLE;
@@ -424,7 +404,7 @@ begin
 --
       when READ_BYTE_C =>
         scl_int         <= '1';
-        bit_read        <= SDA;
+        bit_read        <= SDA(select_line);
         if en_FSM = '1' then
           STATE_NEXT    <= READ_BYTE_D;
         end if;
@@ -522,7 +502,7 @@ begin
 --
       when READ_ACK_C  =>
         scl_int         <= '1';
-        bit_read        <= SDA;
+        bit_read        <= SDA(select_line);
         if en_FSM = '1' then
           STATE_NEXT    <= READ_ACK_D;
         end if;
diff --git a/special/sfp_i2c_readout.vhd b/special/sfp_i2c_readout.vhd
new file mode 100644 (file)
index 0000000..767b6e7
--- /dev/null
@@ -0,0 +1,165 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+
+
+entity sfp_i2c_readout is
+  generic(
+    SFP_NUMBER : integer := 6
+    );
+  port(
+    CLOCK     : in  std_logic;
+    RESET     : in  std_logic;
+    
+    BUS_DATA_IN   : in  std_logic_vector(31 downto 0);
+    BUS_DATA_OUT  : out std_logic_vector(31 downto 0);
+    BUS_ADDR_IN   : in  std_logic_vector(7 downto 0);
+    BUS_WRITE_IN  : in  std_logic;
+    BUS_READ_IN   : in  std_logic;
+    BUS_ACK_OUT   : out std_logic;
+    BUS_NACK_OUT  : out std_logic;
+    
+    SDA           : inout std_logic_vector(SFP_NUMBER-1 downto 0);
+    SCL           : out std_logic_vector(SFP_NUMBER-1 downto 0)
+    );
+end entity;
+
+architecture sfp_i2c_readout_arch of sfp_i2c_readout is
+
+---------------------------------------------------------------
+-- SFP_ADDRESS values:                                        |
+--------------------------------------------------------------|
+-- x"60" => Internally measured module temperature            |
+-- x"62" => Voltage                                           |
+-- x"64" => TX current                                        |
+-- x"66" => Measured TX optical output power                  |
+-- x"68" => Measured RX optical input power                   |
+---------------------------------------------------------------
+
+
+signal start_i   : std_logic;
+signal data_i    : std_logic_vector(15 downto 0);
+signal done_i    : std_logic;
+signal address_i : std_logic_vector(7 downto 0);
+
+signal sfp_i     : integer range 0 to 15;
+signal reg_i     : std_logic_vector(7 downto 0);
+signal override_i: std_logic;
+signal override_addr : std_logic_vector(7 downto 0);
+signal debug_i   : std_logic_vector(31 downto 0);
+signal devaddress_i : std_logic_vector(7 downto 0);
+
+type ram_t is array(0 to 255) of std_logic_vector(15 downto 0);
+signal ram : ram_t;
+
+type state_t is (IDLE, START_SFP, START_REG, GET_DATA,NEXT_REG);
+signal state : state_t;
+
+begin
+
+  debug_i(15 downto 12) <= std_logic_vector(to_unsigned(sfp_i,4));
+  debug_i(23 downto 16) <= reg_i;
+  debug_i(31 downto 24) <= data_i(7 downto 0);
+  
+  THE_I2C_CONTROLLER : Sfp_Interface
+    port map(
+      CLK_IN  => CLOCK,
+      RST_IN  => RESET,
+      START_PULSE => start_i,
+      DATA_OUT => data_i,
+      DEVICE_ADDRESS => devaddress_i,
+      READ_DONE => done_i,
+      SFP_ADDRESS => address_i,
+      SCL(SFP_NUMBER-1 downto 0) => SCL,
+      SDA(SFP_NUMBER-1 downto 0) => SDA,
+      DEBUG(7 downto 0) => debug_i(7 downto 0)
+      );
+
+
+
+  devaddress_i(7 downto 4) <= x"0";
+  devaddress_i(3 downto 0) <= std_logic_vector(to_unsigned(sfp_i,4));
+
+  proc_i2c_ctrl : process begin
+    wait until rising_edge(CLOCK);
+    address_i <= reg_i;
+    start_i   <= '0';
+    case state is
+      when IDLE =>
+        reg_i <= x"60";
+        sfp_i <= 0;
+        state <= START_REG;
+        debug_i(11 downto 8) <= x"1";
+        
+      when START_REG =>
+        debug_i(11 downto 8) <= x"2";
+        if debug_i(7 downto 0) = x"01" then
+          state   <= GET_DATA;
+          start_i <= '1';
+        end if;
+        
+      when GET_DATA =>
+        debug_i(11 downto 8) <= x"3";
+        if done_i = '1' then
+          state <= NEXT_REG;
+          if override_i = '0' then
+            ram(sfp_i*16+to_integer(unsigned(reg_i(3 downto 1)))) <= data_i;
+          else
+            ram(sfp_i*16+15) <= data_i;
+          end if;
+        end if;
+        
+      when NEXT_REG =>
+        debug_i(11 downto 8) <= x"4";
+        if override_i = '1' then
+          reg_i <= override_addr;
+        elsif reg_i >= x"68" then
+          reg_i <= x"60";
+        else
+          reg_i <= std_logic_vector(unsigned(reg_i) + 2);
+        end if;
+        if override_i = '1' or reg_i = x"68" then
+          if sfp_i = SFP_NUMBER -1 then
+            sfp_i <= 0;
+          else
+            sfp_i <= sfp_i + 1;
+          end if;
+        end if;
+        state <= START_REG;
+    end case;
+    if RESET = '1' then
+      state <= IDLE;
+    end if;
+  end process;
+  
+  
+  proc_sctrl : process begin
+    wait until rising_edge(CLOCK);
+    BUS_ACK_OUT  <= '0';
+    BUS_NACK_OUT <= '0';
+    BUS_DATA_OUT <= x"EE000000";
+    if BUS_READ_IN = '1' then
+      if BUS_ADDR_IN = x"FF" then
+        BUS_ACK_OUT <= '1';
+        BUS_DATA_OUT <= debug_i;
+      else
+        BUS_ACK_OUT <= '1';
+        BUS_DATA_OUT(31 downto 16) <= x"0000";
+        BUS_DATA_OUT(15 downto 0)  <= ram(to_integer(unsigned(BUS_ADDR_IN)));
+      end if;
+    elsif BUS_WRITE_IN = '1' then
+      if BUS_ADDR_IN = x"FF" then
+        BUS_ACK_OUT  <= '1';
+        override_i    <= BUS_DATA_IN(8);
+        override_addr <= BUS_DATA_IN(7 downto 0);
+      else
+        BUS_NACK_OUT <= '1';
+      end if;
+    end if;
+  end process;
+
+end architecture;
\ No newline at end of file
index 74add9dfd41008b4784e6ddc81b97d87576cbfb7..95b433e789b2c407d0d865ccfdd0c78f88f43638 100644 (file)
@@ -12,7 +12,49 @@ package trb_net_components is
 --This list of components is sorted alphabetically, ignoring the trb_net or trb_net16 prefix of some component names\r
 \r
 \r
+  component Sfp_Interface is\r
+    generic (\r
+      I2C_SPEED         :       std_logic_vector(15 downto 0) := x"0200"\r
+      );\r
+    port(\r
+      CLK_IN            : in    std_logic;                        -- System clock\r
+      RST_IN            : in    std_logic;                        -- System reset\r
+  -- host side\r
+      START_PULSE       : in    std_logic;                        -- System start pulse\r
+      DEVICE_ADDRESS    : in    std_logic_vector(7 downto 0);     -- Device address input: x"06" for SFP_Interface\r
+      DATA_OUT          : out   std_logic_vector(15 downto 0);    -- Data output from optical transmitter\r
+      READ_DONE         : out   std_logic;                        -- Reading process done\r
+      SFP_ADDRESS       : in    std_logic_vector(7 downto 0);     -- SFP address\r
+  -- optical transceiver side\r
+      SCL               : out   std_logic_vector(15 downto 0);                          -- I2C Serial clock I/O\r
+      SDA               : inout std_logic_vector(15 downto 0);                          -- I2C Serial data I/O\r
+      DEBUG             : out   std_logic_vector(31 downto 0)\r
+      );\r
 \r
+  end component;\r
+\r
+  component sfp_i2c_readout is\r
+    generic(\r
+      SFP_NUMBER : integer := 6\r
+      );\r
+    port(\r
+      CLOCK     : in  std_logic;\r
+      RESET     : in  std_logic;\r
+      \r
+      BUS_DATA_IN   : in  std_logic_vector(31 downto 0);\r
+      BUS_DATA_OUT  : out std_logic_vector(31 downto 0);\r
+      BUS_ADDR_IN   : in  std_logic_vector(7 downto 0);\r
+      BUS_WRITE_IN  : in  std_logic;\r
+      BUS_READ_IN   : in  std_logic;\r
+      BUS_ACK_OUT   : out std_logic;\r
+      BUS_NACK_OUT  : out std_logic;\r
+      \r
+      SDA           : out std_logic_vector(SFP_NUMBER-1 downto 0);\r
+      SDA_IN        : in  std_logic_vector(SFP_NUMBER-1 downto 0);\r
+      SCL           : out std_logic_vector(SFP_NUMBER-1 downto 0)\r
+      );\r
+  end component;\r
+  \r
   component trb_net16_med_scm_sfp_gbe is\r
     generic(\r
       SERDES_NUM  : integer range 0 to 3 := 0;     -- DO NOT CHANGE\r