entity Sfp_Interface is
generic (
- I2C_SPEED : std_logic_vector(15 downto 0)
+ I2C_SPEED : std_logic_vector(15 downto 0) := x"0200"
+--------------------------------------------------------------------------|
+-- I2C_SPEED = 100 MHz / working frequency |
+-- max working frequency 400 kHz |
+-- Example: for 400 kHz working frequency => I2C_SPEED = 100MHz / 400kHz |
+-- I2C_SPEED = 250 = x"FA" |
+--------------------------------------------------------------------------|
);
port(
CLK_IN : in std_logic; -- System clock
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);
---
- 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
---
+ DEVICE_ADDRESS : in std_logic_vector(7 downto 0); -- 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
- DEBUG : out std_logic_vector(31 downto 0); -- Debug output
- SFP_ADDRESS : in std_logic_vector(31 downto 0) -- SFP addresses
+ SFP_ADDRESS : in std_logic_vector(7 downto 0); -- SFP address
+--------------------------------------------------------------|
+-- SFP_ADDRESS values: |
+--------------------------------------------------------------|
+-- x"60" => Internally measured module temperature |
+-- x"62" => Internally measured supply voltage in transceiver |
+-- x"64" => Internally measured TX Bias Current |
+-- x"66" => Measured TX optical output power |
+-- 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
);
end Sfp_Interface;
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 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 stop_fre_cnt : std_logic := '0';
signal rst_fre_cnt : std_logic := '0';
- signal fre_cnt : std_logic_vector(9 downto 0) := "0000000000";
+ signal fre_cnt : std_logic_vector(15 downto 0) := x"0000";
--
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 sfp_address_i : std_logic_vector(7 downto 0) := x"00";
+ 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);
+ 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;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Frequency_Counter : up_down_counter
generic map (
- NUMBER_OF_BITS => 10)
+ NUMBER_OF_BITS => 16)
port map (
CLK => CLK_IN,
RESET => stop_fre_cnt,
UP_IN => '1',
DOWN_IN => '0');
-------------------------------------------------------------------------------
-
-------------------------------------------------------------------------------
Frequency_Division : process (CLK_IN, RST_IN, fre_cnt)
begin
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";
+ sfp_address_i <= x"00";
+ device_address_i <= x"00";
start_pulse_i <= '0';
elsif START_PULSE = '1' then
sfp_address_i <= SFP_ADDRESS;
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";
+ DATA_OUT <= x"0000";
READ_DONE <= '0';
- data_out_int_mem <= X"0000";
- byte_2_send_mem <= X"00";
+ 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;
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";
+ byte_2_read <= x"0000";
elsif en_shift_reg = '1' then
byte_2_read <= byte_2_read(14 downto 0) & bit_read;
end if;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--- The generation of the state machine
+-- 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)
+ 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)
begin
en_reset_cnt <= '0';
rst_reset_cnt <= '0';
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
+ if device_address_i = x"06" and 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' or EN_RESET = '0') then
+ elsif device_address_i = x"06" and start_pulse_i = '1' and reset_done = '1' 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
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
end if;
--
when RESET_C =>
- debug_int(7 downto 0) <= x"04";
scl_int <= '1';
sda_int <= '1';
if en_FSM = '1' then
end if;
--
when RESET_D =>
- debug_int(7 downto 0) <= x"05";
scl_int <= '1';
sda_int <= '1';
if en_FSM = '1' then
end if;
--START
when START_A =>
- debug_int(7 downto 0) <= x"07";
scl_int <= '0';
sda_int <= '1';
if en_FSM = '1' then
end if;
--
when START_B =>
- debug_int(7 downto 0) <= x"08";
scl_int <= '0';
sda_int <= '1';
if en_FSM = '1' then
end if;
--
when START_C =>
- debug_int(7 downto 0) <= x"09";
scl_int <= '1';
sda_int <= '1';
if en_FSM = '1' then
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';
+ byte_2_send <= x"A3";
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';
+ byte_2_send <= x"A2";
STATE_NEXT <= SEND_BYTE_A;
en_bit_cnt <= '1';
elsif en_FSM = '0' then
STATE_NEXT <= STATE_CURRENT;
else
- byte_2_send <= X"00";
+ 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
end if;
--
when STOP_B =>
- debug_int(7 downto 0) <= x"0C";
scl_int <= '0';
sda_int <= '0';
if en_FSM = '1' then
end if;
--
when STOP_C =>
- debug_int(7 downto 0) <= x"0D";
scl_int <= '1';
sda_int <= '0';
if en_FSM = '1' then
end if;
--
when STOP_D =>
- debug_int(7 downto 0) <= x"0E";
scl_int <= '1';
sda_int <= '1';
rst_bit_cnt <= '1';
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
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
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
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
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
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;
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';
end if;
--
when SEND_ACK_B =>
- debug_int(7 downto 0) <= x"18";
scl_int <= '0';
if bit_cnt = "101101" then
sda_int <= '1';
end if;
--
when SEND_ACK_C =>
- debug_int(7 downto 0) <= x"19";
scl_int <= '1';
if bit_cnt = "101101" then
sda_int <= '1';
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';
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
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);
+ byte_2_send <= sfp_address_i(7 downto 0);
en_bit_cnt <= '1';
elsif bit_read = '0' and bit_cnt = "010010" and en_FSM = '1' then
STATE_NEXT <= START_A;
end if;
--OTHERS
when others =>
- debug_int(7 downto 0) <= x"1F";
scl_int <= '1';
sda_int <= '1';
- byte_2_send <= X"00";
+ byte_2_send <= x"00";
STATE_NEXT <= IDLE;
end case;