]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
added serdes for ecp2m
authorhadeshyp <hadeshyp>
Thu, 2 Apr 2009 14:04:29 +0000 (14:04 +0000)
committerhadeshyp <hadeshyp>
Thu, 2 Apr 2009 14:04:29 +0000 (14:04 +0000)
media_interfaces/trb_net16_lsm_sfp.vhd [new file with mode: 0644]
media_interfaces/trb_net16_med_ecp_fot_4.vhd [new file with mode: 0644]
media_interfaces/trb_net16_med_ecp_sfp.vhd [new file with mode: 0644]

diff --git a/media_interfaces/trb_net16_lsm_sfp.vhd b/media_interfaces/trb_net16_lsm_sfp.vhd
new file mode 100644 (file)
index 0000000..d3debd7
--- /dev/null
@@ -0,0 +1,435 @@
+-- LinkStateMachine for SFPs (2GBit)
+
+-- Still missing: link reset features, fifo full error handling, signals on stat_op
+-- Take care: all input signals must be synchronous to SYSCLK,
+--            all output signals are synchronous to SYSCLK.
+-- Clock Domain Crossing is in your responsibility!
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.std_logic_ARITH.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+
+entity trb_net16_lsm_sfp is
+port( SYSCLK      : in  std_logic; -- fabric clock (100MHz)
+    RESET        : in  std_logic; -- synchronous reset
+    CLEAR        : in  std_logic; -- asynchronous reset, connect to '0' if not needed / available
+    -- status signals
+    SFP_MISSING_IN  : in  std_logic; -- SFP Missing ('1' = no SFP mounted, '0' = SFP in place)
+    SFP_LOS_IN    : in  std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
+    SD_LINK_OK_IN    : in  std_logic; -- SerDes Link OK ('0' = not linked, '1' link established)
+    SD_LOS_IN      : in  std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost)
+    SD_TXCLK_BAD_IN  : in  std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked)
+    SD_RXCLK_BAD_IN  : in  std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked)
+    SD_RETRY_IN    : in  std_logic; -- '0' = handle byte swapping in logic, '1' = simply restart link and hope
+    SD_ALIGNMENT_IN  : in  std_logic_vector(1 downto 0); -- SerDes Byte alignment ("10" = swapped, "01" = correct)
+    SD_CV_IN      : in  std_logic_vector(1 downto 0); -- SerDes Code Violation ("00" = OK, everything else = BAD)
+    -- control signals
+    FULL_RESET_OUT  : out std_logic; -- full reset AKA quad_reset
+    LANE_RESET_OUT  : out std_logic; -- partial reset AKA lane_reset
+    TX_ALLOW_OUT    : out std_logic; -- allow normal transmit operation
+    RX_ALLOW_OUT    : out std_logic; -- allow normal receive operation
+    SWAP_BYTES_OUT  : out std_logic; -- bytes need swapping ('0' = correct order, '1' = swapped order)
+    -- debug signals
+    STAT_OP      : out std_logic_vector(15 downto 0);
+    CTRL_OP      : in  std_logic_vector(15 downto 0);
+    STAT_DEBUG    : out std_logic_vector(31 downto 0)
+   );
+end entity;
+
+architecture lsm_sfp of trb_net16_lsm_sfp is
+
+-- state machine signals
+type STATES is ( QRST, SLEEP, WPAR, WLOS, ALIGN, WRXA, WTXA, LINK, CVFND, CVBAD );
+signal CURRENT_STATE, NEXT_STATE: STATES;
+
+signal state_bits      : std_logic_vector(3 downto 0);
+
+signal next_med_error    : std_logic_vector(2 downto 0);
+signal med_error      : std_logic_vector(2 downto 0);
+signal next_ce_tctr      : std_logic;
+signal ce_tctr        : std_logic;
+signal next_rst_tctr    : std_logic;
+signal rst_tctr        : std_logic;
+signal next_quad_rst    : std_logic;
+signal quad_rst        : std_logic;
+signal next_lane_rst    : std_logic;
+signal lane_rst        : std_logic;
+signal next_rx_allow    : std_logic;
+signal rx_allow        : std_logic;
+signal next_tx_allow    : std_logic;
+signal tx_allow        : std_logic;
+signal next_align_me    : std_logic;
+signal align_me        : std_logic;
+signal next_resync      : std_logic;
+signal resync        : std_logic;
+signal next_reset_me    : std_logic;
+signal reset_me        : std_logic;
+signal next_ce_cctr      : std_logic;
+signal ce_cctr        : std_logic;
+signal next_rst_cctr    : std_logic;
+signal rst_cctr        : std_logic;
+
+signal buf_swap_bytes    : std_logic;
+
+signal timing_ctr      : std_logic_vector(28 downto 0);
+signal cv_ctr        : std_logic_vector(15 downto 0);
+
+signal link_status_led    : std_logic;
+
+begin
+
+--------------------------------------------------------------------------
+-- Main control state machine, startup control for SFP
+--------------------------------------------------------------------------
+
+-- "Swap Bytes" indicator
+THE_SWAP_BYTES_PROC: process( sysclk, clear )
+begin
+  if( clear = '1' ) then
+    buf_swap_bytes <= '0';
+  elsif( rising_edge(sysclk) ) then
+    if   ( (align_me = '1') and (sd_alignment_in = "10") ) then
+      buf_swap_bytes <= '1';
+    elsif( (align_me = '1') and (sd_alignment_in = "01") ) then
+      buf_swap_bytes <= '0';
+    end if;
+  end if;
+end process THE_SWAP_BYTES_PROC;
+
+-- Timing counter for reset sequencing
+THE_TIMING_COUNTER_PROC: process( sysclk, clear )
+begin
+  if( clear = '1' ) then
+    timing_ctr <= (others => '0');
+  elsif( rising_edge(sysclk) ) then
+    if   ( rst_tctr = '1' ) then
+      timing_ctr <= (others => '0');
+    elsif( ce_tctr = '1' ) then
+      timing_ctr <= timing_ctr + 1;
+    end if;
+  end if;
+end process THE_TIMING_COUNTER_PROC;
+
+-- CodeViolation counter for Michael Traxler
+THE_CV_COUNTER_PROC: process( sysclk, clear )
+begin
+  if( clear = '1' ) then
+    cv_ctr <= (others => '0');
+  elsif( rising_edge(sysclk) ) then
+    if   ( rst_cctr = '1' ) then
+      cv_ctr <= (others => '0');
+    elsif( ce_cctr = '1' ) then
+      cv_ctr <= cv_ctr + 1;
+    end if;
+  end if;
+end process THE_CV_COUNTER_PROC;
+
+-- State machine
+-- state registers
+STATE_MEM: process( sysclk, clear )
+begin
+  if( clear = '1' ) then
+    CURRENT_STATE  <= QRST;
+    ce_tctr        <= '0';
+    rst_tctr       <= '0';
+    ce_cctr        <= '0';
+    rst_cctr       <= '0';
+    quad_rst       <= '1';
+    lane_rst       <= '1';
+    rx_allow       <= '0';
+    tx_allow       <= '0';
+    align_me       <= '0';
+    reset_me       <= '1';
+    resync         <= '1';
+    med_error      <= ERROR_NC;
+  elsif( rising_edge(sysclk) ) then
+    CURRENT_STATE  <= NEXT_STATE;
+    ce_tctr        <= next_ce_tctr;
+    rst_tctr       <= next_rst_tctr;
+    ce_cctr        <= next_ce_cctr;
+    rst_cctr       <= next_rst_cctr;
+    quad_rst       <= next_quad_rst;
+    lane_rst       <= next_lane_rst;
+    rx_allow       <= next_rx_allow;
+    tx_allow       <= next_tx_allow;
+    align_me       <= next_align_me;
+    reset_me       <= next_reset_me;
+    resync         <= next_resync;
+    med_error      <= next_med_error;
+  end if;
+end process STATE_MEM;
+
+-- state transitions
+PROC_STATE_TRANSFORM: process( CURRENT_STATE, sfp_missing_in, sfp_los_in, timing_ctr, sd_alignment_in, cv_ctr,
+                 sd_los_in, sd_link_ok_in, sd_txclk_bad_in, sd_rxclk_bad_in, sd_retry_in, rst_tctr )
+begin
+  NEXT_STATE     <= QRST; -- avoid latches
+  next_ce_tctr   <= '0';
+  next_rst_tctr  <= '0';
+  next_ce_cctr   <= '0';
+  next_rst_cctr  <= '0';
+  next_quad_rst  <= '0';
+  next_lane_rst  <= '0';
+  next_rx_allow  <= '0';
+  next_tx_allow  <= '0';
+  next_align_me  <= '0';
+  next_reset_me  <= '1';
+  next_resync    <= '1';
+  next_med_error <= ERROR_NC;
+  case CURRENT_STATE is
+    when QRST  =>
+      if( (timing_ctr(4) = '1') and (rst_tctr = '0') ) then
+        NEXT_STATE    <= SLEEP; -- release QUAD_RST, wait for lock of RxClock and TxClock
+        next_lane_rst <= '1';
+      else
+        NEXT_STATE    <= QRST; -- count delay
+        next_ce_tctr  <= '1';
+        next_quad_rst <= '1';
+        next_lane_rst <= '1';
+      end if;
+    when SLEEP  =>
+      if( (sfp_missing_in = '0') and (sfp_los_in = '0') ) then
+        NEXT_STATE    <= WPAR; -- do a correctly timed QUAD reset (about 150ns)
+        next_rst_tctr <= '1';
+        next_lane_rst <= '1';
+        next_rst_cctr <= '1'; -- if we start the link, we clear the CV counter
+      else
+        NEXT_STATE    <= SLEEP; -- wait for SFP present signal
+        next_ce_tctr  <= '1';
+        next_lane_rst <= '1';
+      end if;
+    when WPAR  =>
+      if   ( (sfp_missing_in = '1') or ( sfp_los_in = '1') ) then
+        NEXT_STATE    <= SLEEP; -- SFP has been removed
+        next_lane_rst <= '1';
+        next_ce_tctr  <= '1';
+      elsif( (sd_rxclk_bad_in = '0') and (sd_txclk_bad_in = '0') ) then
+        NEXT_STATE    <= WLOS; -- PLLs locked, signal present
+        next_rst_tctr <= '1';
+      else
+        NEXT_STATE    <= WPAR; -- wait for RLOL and PLOL and incoming signal from SFP
+        next_lane_rst <= '1';
+        next_ce_tctr  <= '1';
+      end if;
+    when WLOS  =>
+      if   ( (timing_ctr(27) = '0') and (timing_ctr(26) = '0') and (rst_tctr = '0') ) then
+        NEXT_STATE    <= WLOS;
+        next_resync   <= '0';
+        next_ce_tctr  <= '1';
+      elsif( (timing_ctr(27) = '1') and (rst_tctr = '0') ) then
+        NEXT_STATE    <= ALIGN; -- debounce before aligning
+        next_align_me <= '1';
+        next_reset_me <= '0';
+        next_ce_tctr  <= '1';
+      else
+        NEXT_STATE    <= WLOS; -- no alignment found yet
+        next_ce_tctr  <= '1';
+      end if;
+    when ALIGN  =>
+      if   ( sd_cv_in /= "00" ) then
+        NEXT_STATE     <= ALIGN;
+        next_ce_cctr   <= '1'; -- increment CV counter
+        next_ce_tctr   <= '1';
+        next_align_me  <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+        elsif( (sd_retry_in = '0') and ((sd_alignment_in = "10") or (sd_alignment_in = "01")) ) then
+        NEXT_STATE     <= WRXA; -- one komma character has been received
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+      elsif( (sd_retry_in = '1') and (sd_alignment_in = "10")) then
+        NEXT_STATE    <= SLEEP; -- MAREK STYLE - CORRECT?
+        next_rst_tctr <= '1';
+        next_lane_rst <= '1';
+      else
+        NEXT_STATE     <= ALIGN; -- wait for komma character
+        next_ce_tctr   <= '1';
+        next_align_me  <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+      end if;
+    when WRXA  =>
+      if   ( sd_cv_in /= "00" ) then
+        NEXT_STATE     <= WRXA;
+        next_ce_cctr   <= '1'; -- increment CV counter
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+        elsif( (timing_ctr(28) = '1') and (rst_tctr = '0') ) then
+        NEXT_STATE     <= WTXA; -- wait cycle done, allow reception of data
+        next_rst_tctr  <= '1';
+        next_rx_allow  <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+      else
+        NEXT_STATE     <= WRXA; -- wait one complete cycle (2^27 x 10ns = 1.3s)
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+      end if;
+    when WTXA  =>
+      if   ( sd_cv_in /= "00" ) then
+        NEXT_STATE     <= WTXA;
+        next_ce_cctr   <= '1'; -- increment CV counter
+        next_ce_tctr   <= '1';
+        next_rx_allow  <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+       elsif( (timing_ctr(28) = '1') and (rst_tctr = '0') ) then -- we could use [29:0] as counter and use [29] here
+        NEXT_STATE     <= LINK; -- wait cycle done, allow transmission of data
+        next_rst_tctr  <= '1';
+        next_rx_allow  <= '1';
+        next_tx_allow  <= '1';
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_OK;
+      else
+        NEXT_STATE     <= WTXA; -- wait one complete cycle (2^27 x 10ns = 1.3s)
+        next_ce_tctr   <= '1';
+        next_rx_allow  <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_WAIT;
+      end if;
+    when LINK  =>
+      if   ( (sfp_missing_in = '1') or (sfp_los_in = '1') ) then
+        NEXT_STATE     <= SLEEP;
+        next_lane_rst  <= '1';
+        next_rst_tctr  <= '1';
+      elsif( sd_cv_in /= "00" ) then
+        NEXT_STATE     <= CVFND;
+        next_ce_cctr   <= '1'; -- increment CV counter
+        next_rx_allow  <= '1';
+        next_tx_allow  <= '1';
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_OK;
+      else
+        NEXT_STATE     <= LINK;
+        next_rx_allow  <= '1';
+        next_tx_allow  <= '1';
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_OK;
+      end if;
+    when CVFND  =>
+        if( cv_ctr(15) = '0' ) then
+        NEXT_STATE     <= LINK; -- try again (?)
+        next_rx_allow  <= '1';
+        next_tx_allow  <= '1';
+        next_ce_tctr   <= '1';
+        next_reset_me  <= '0';
+        next_med_error <= ERROR_OK;
+      else
+        NEXT_STATE     <= CVBAD;
+        next_ce_tctr   <= '1';
+        next_med_error <= ERROR_FATAL;
+      end if;
+    when CVBAD  =>
+      if   ( (sfp_missing_in = '1') or (sfp_los_in = '1') ) then
+        NEXT_STATE     <= SLEEP;
+        next_lane_rst  <= '1';
+        next_rst_tctr  <= '1';
+      else
+        NEXT_STATE     <= CVBAD;
+        next_ce_tctr   <= '1';
+        next_med_error <= ERROR_FATAL;
+      end if;
+    when others  =>  NEXT_STATE <= QRST;
+  end case;
+end process;
+
+THE_DECODE_PROC: process( CURRENT_STATE, timing_ctr )
+begin
+  case CURRENT_STATE is
+    when QRST =>  state_bits    <= "0000";
+            link_status_led <= '0';
+    when SLEEP  =>  state_bits    <= "0001";
+            link_status_led  <= '0';
+    when WPAR  =>  state_bits    <= "0010";
+            link_status_led <= timing_ctr(23) and timing_ctr(24); -- nice frequency for human eye
+    when WLOS  =>  state_bits    <= "0011";
+            link_status_led  <= timing_ctr(22);
+    when ALIGN  =>  state_bits    <= "0100";
+            link_status_led  <= timing_ctr(23);
+    when WRXA  =>  state_bits    <= "0101";
+            link_status_led  <= timing_ctr(24);
+    when WTXA  =>  state_bits    <= "0110";
+            link_status_led  <= timing_ctr(25);
+    when CVFND  =>  state_bits    <= "0111";
+            link_status_led  <= '1';
+    when LINK  =>  state_bits    <= "1000";
+            link_status_led  <= '1';
+    when CVBAD  =>  state_bits    <= "1001";
+            link_status_led  <= timing_ctr(25) and timing_ctr(24) and timing_ctr(23);
+    when others  =>  state_bits    <= "1111";
+            link_status_led  <= '0';
+  end case;
+end process THE_DECODE_PROC;
+
+--------------------------------------------------------------------------
+-- Output signals
+--------------------------------------------------------------------------
+swap_bytes_out  <= buf_swap_bytes;
+full_reset_out  <= quad_rst;
+lane_reset_out  <= lane_rst;
+tx_allow_out    <= tx_allow;
+rx_allow_out    <= rx_allow;
+
+--------------------------------------------------------------------------
+-- Status output signaled (normed)
+--------------------------------------------------------------------------
+stat_op(2 downto 0)  <= med_error;
+stat_op(8 downto 3)  <= (others => '0'); -- unused
+stat_op(9)           <= link_status_led;
+stat_op(10)          <= '0'; -- Rx LED, made outside LSM
+stat_op(11)          <= '0'; -- Tx LED, made outside LSM
+stat_op(12)          <= '0'; -- unused
+stat_op(13)          <= '0';
+stat_op(14)          <= reset_me; -- reset out
+stat_op(15)          <= '0'; -- protocol error
+
+--------------------------------------------------------------------------
+-- Debug output
+--------------------------------------------------------------------------
+stat_debug(3 downto 0)   <= state_bits;
+stat_debug(4)            <= align_me;
+stat_debug(5)            <= buf_swap_bytes;
+stat_debug(6)            <= resync;
+stat_debug(7)            <= sfp_missing_in;
+stat_debug(8)            <= sfp_los_in;
+stat_debug(31 downto 9)  <= (others => '0');
+
+
+--------------------------------------------------------------------------
+--------------------------------------------------------------------------
+-- Code prions below
+--------------------------------------------------------------------------
+--------------------------------------------------------------------------
+
+--Generate LED signals
+----------------------
+--process(clock)
+--  begin
+--    if rising_edge(clock) then
+--      led_counter <= led_counter + 1;
+--
+--      if buf_med_dataready_out = '1' then
+--        rx_led <= '1';
+--      elsif led_counter = 0 then
+--        rx_led <= '0';
+--      end if;
+--
+--      if tx_k(0) = '0' then
+--        tx_led <= '1';
+--      elsif led_counter = 0 then
+--        tx_led <= '0';
+--      end if;
+--
+--    end if;
+--  end process;
+
+end architecture;
\ No newline at end of file
diff --git a/media_interfaces/trb_net16_med_ecp_fot_4.vhd b/media_interfaces/trb_net16_med_ecp_fot_4.vhd
new file mode 100644 (file)
index 0000000..0393b5a
--- /dev/null
@@ -0,0 +1,720 @@
+LIBRARY ieee;
+use ieee.std_logic_1164.all;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+
+entity trb_net16_med_ecp_fot_4 is
+  port(
+    CLK    : in std_logic;
+    CLK_25 : in std_logic;
+    CLK_EN : in std_logic;
+    RESET  : in std_logic;
+
+    --Internal Connection
+    MED_DATA_IN        : in  std_logic_vector(c_DATA_WIDTH*4-1 downto 0);
+    MED_PACKET_NUM_IN  : in  std_logic_vector(c_NUM_WIDTH*4-1 downto 0);
+    MED_DATAREADY_IN   : in  std_logic_vector(3 downto 0);
+    MED_READ_OUT       : out std_logic_vector(3 downto 0);
+    MED_DATA_OUT       : out std_logic_vector(c_DATA_WIDTH*4-1 downto 0);
+    MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH*4-1 downto 0);
+    MED_DATAREADY_OUT  : out std_logic_vector(3 downto 0);
+    MED_READ_IN        : in  std_logic_vector(3 downto 0);
+
+    --SFP Connection
+    TXP : out std_logic_vector(3 downto 0);
+    TXN : out std_logic_vector(3 downto 0);
+    RXP : in  std_logic_vector(3 downto 0);
+    RXN : in  std_logic_vector(3 downto 0);
+    SD  : in  std_logic_vector(3 downto 0);
+
+    -- Status and control port
+    STAT_OP            : out  std_logic_vector (63 downto 0);
+    CTRL_OP            : in  std_logic_vector (63 downto 0);
+    STAT_DEBUG         : out  std_logic_vector (255 downto 0);
+    CTRL_DEBUG         : in  std_logic_vector (63 downto 0)
+    );
+end entity;
+
+architecture trb_net16_med_ecp_fot_4_arch of trb_net16_med_ecp_fot_4 is
+
+-- Placer Directives
+attribute HGROUP : string;
+-- for whole architecture
+attribute HGROUP of trb_net16_med_ecp_fot_4_arch : architecture  is "GROUP_PCS";
+
+component serdes_full_quad is
+  generic(
+    USER_CONFIG_FILE    :  String := "serdes_full_quad.txt" );
+  port(
+    core_txrefclk : in std_logic;
+    core_rxrefclk : in std_logic;
+
+    hdinp0 : in std_logic;
+    hdinn0 : in std_logic;
+    hdoutp0 : out std_logic;
+    hdoutn0 : out std_logic;
+    ff_rxiclk_ch0 : in std_logic;
+    ff_txiclk_ch0 : in std_logic;
+    ff_ebrd_clk_0 : in std_logic;
+    ff_txdata_ch0 : in std_logic_vector (7 downto 0);
+    ff_rxdata_ch0 : out std_logic_vector (7 downto 0);
+    ff_tx_k_cntrl_ch0 : in std_logic;
+    ff_rx_k_cntrl_ch0 : out std_logic;
+    ff_rxfullclk_ch0 : out std_logic;
+    ff_force_disp_ch0 : in std_logic;
+    ff_disp_sel_ch0 : in std_logic;
+    ff_correct_disp_ch0 : in std_logic;
+    ff_disp_err_ch0 : out std_logic;
+    ff_cv_ch0 : out std_logic;
+    ffc_rrst_ch0 : in std_logic;
+    ffc_lane_tx_rst_ch0 : in std_logic;
+    ffc_lane_rx_rst_ch0 : in std_logic;
+    ffc_txpwdnb_ch0 : in std_logic;
+    ffc_rxpwdnb_ch0 : in std_logic;
+    ffs_rlos_lo_ch0 : out std_logic;
+    ffs_ls_sync_status_ch0 : out std_logic;
+    ffs_cc_underrun_ch0 : out std_logic;
+    ffs_cc_overrun_ch0 : out std_logic;
+    ffs_txfbfifo_error_ch0 : out std_logic;
+    ffs_rxfbfifo_error_ch0 : out std_logic;
+    ffs_rlol_ch0 : out std_logic;
+    oob_out_ch0 : out std_logic;
+
+    hdinp1 : in std_logic;
+    hdinn1 : in std_logic;
+    hdoutp1 : out std_logic;
+    hdoutn1 : out std_logic;
+    ff_rxiclk_ch1 : in std_logic;
+    ff_txiclk_ch1 : in std_logic;
+    ff_ebrd_clk_1 : in std_logic;
+    ff_txdata_ch1 : in std_logic_vector (7 downto 0);
+    ff_rxdata_ch1 : out std_logic_vector (7 downto 0);
+    ff_tx_k_cntrl_ch1 : in std_logic;
+    ff_rx_k_cntrl_ch1 : out std_logic;
+    ff_rxfullclk_ch1 : out std_logic;
+    ff_force_disp_ch1 : in std_logic;
+    ff_disp_sel_ch1 : in std_logic;
+    ff_correct_disp_ch1 : in std_logic;
+    ff_disp_err_ch1 : out std_logic;
+    ff_cv_ch1 : out std_logic;
+    ffc_rrst_ch1 : in std_logic;
+    ffc_lane_tx_rst_ch1 : in std_logic;
+    ffc_lane_rx_rst_ch1 : in std_logic;
+    ffc_txpwdnb_ch1 : in std_logic;
+    ffc_rxpwdnb_ch1 : in std_logic;
+    ffs_rlos_lo_ch1 : out std_logic;
+    ffs_ls_sync_status_ch1 : out std_logic;
+    ffs_cc_underrun_ch1 : out std_logic;
+    ffs_cc_overrun_ch1 : out std_logic;
+    ffs_txfbfifo_error_ch1 : out std_logic;
+    ffs_rxfbfifo_error_ch1 : out std_logic;
+    ffs_rlol_ch1 : out std_logic;
+    oob_out_ch1 : out std_logic;
+
+    hdinp2 : in std_logic;
+    hdinn2 : in std_logic;
+    hdoutp2 : out std_logic;
+    hdoutn2 : out std_logic;
+    ff_rxiclk_ch2 : in std_logic;
+    ff_txiclk_ch2 : in std_logic;
+    ff_ebrd_clk_2 : in std_logic;
+    ff_txdata_ch2 : in std_logic_vector (7 downto 0);
+    ff_rxdata_ch2 : out std_logic_vector (7 downto 0);
+    ff_tx_k_cntrl_ch2 : in std_logic;
+    ff_rx_k_cntrl_ch2 : out std_logic;
+    ff_rxfullclk_ch2 : out std_logic;
+    ff_force_disp_ch2 : in std_logic;
+    ff_disp_sel_ch2 : in std_logic;
+    ff_correct_disp_ch2 : in std_logic;
+    ff_disp_err_ch2 : out std_logic;
+    ff_cv_ch2 : out std_logic;
+    ffc_rrst_ch2 : in std_logic;
+    ffc_lane_tx_rst_ch2 : in std_logic;
+    ffc_lane_rx_rst_ch2 : in std_logic;
+    ffc_txpwdnb_ch2 : in std_logic;
+    ffc_rxpwdnb_ch2 : in std_logic;
+    ffs_rlos_lo_ch2 : out std_logic;
+    ffs_ls_sync_status_ch2 : out std_logic;
+    ffs_cc_underrun_ch2 : out std_logic;
+    ffs_cc_overrun_ch2 : out std_logic;
+    ffs_txfbfifo_error_ch2 : out std_logic;
+    ffs_rxfbfifo_error_ch2 : out std_logic;
+    ffs_rlol_ch2 : out std_logic;
+    oob_out_ch2 : out std_logic;
+
+    hdinp3 : in std_logic;
+    hdinn3 : in std_logic;
+    hdoutp3 : out std_logic;
+    hdoutn3 : out std_logic;
+    ff_rxiclk_ch3 : in std_logic;
+    ff_txiclk_ch3 : in std_logic;
+    ff_ebrd_clk_3 : in std_logic;
+    ff_txdata_ch3 : in std_logic_vector (7 downto 0);
+    ff_rxdata_ch3 : out std_logic_vector (7 downto 0);
+    ff_tx_k_cntrl_ch3 : in std_logic;
+    ff_rx_k_cntrl_ch3 : out std_logic;
+    ff_rxfullclk_ch3 : out std_logic;
+    ff_force_disp_ch3 : in std_logic;
+    ff_disp_sel_ch3 : in std_logic;
+    ff_correct_disp_ch3 : in std_logic;
+    ff_disp_err_ch3 : out std_logic;
+    ff_cv_ch3 : out std_logic;
+    ffc_rrst_ch3 : in std_logic;
+    ffc_lane_tx_rst_ch3 : in std_logic;
+    ffc_lane_rx_rst_ch3 : in std_logic;
+    ffc_txpwdnb_ch3 : in std_logic;
+    ffc_rxpwdnb_ch3 : in std_logic;
+    ffs_rlos_lo_ch3 : out std_logic;
+    ffs_ls_sync_status_ch3 : out std_logic;
+    ffs_cc_underrun_ch3 : out std_logic;
+    ffs_cc_overrun_ch3 : out std_logic;
+    ffs_txfbfifo_error_ch3 : out std_logic;
+    ffs_rxfbfifo_error_ch3 : out std_logic;
+    ffs_rlol_ch3 : out std_logic;
+    oob_out_ch3 : out std_logic;
+
+    ffc_macro_rst : in std_logic;
+    ffc_quad_rst : in std_logic;
+    ffc_trst : in std_logic;
+    ff_txfullclk : out std_logic;
+    ff_txhalfclk : out std_logic;
+    ffs_plol : out std_logic
+    );
+  end component;
+
+  component trb_net16_lsm_sfp is
+    port(
+      SYSCLK            : in  std_logic; -- fabric clock
+      RESET                : in  std_logic; -- synchronous reset
+      CLEAR                : in  std_logic; -- asynchronous reset, connect to '0' if not needed / available
+      -- status signals
+      SFP_MISSING_IN    : in  std_logic; -- SFP Present ('0' = no SFP mounted, '1' = SFP in place)
+      SFP_LOS_IN        : in  std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
+      SD_LINK_OK_IN        : in  std_logic; -- SerDes Link OK ('0' = not linked, '1' link established)
+      SD_LOS_IN            : in  std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost)
+      SD_TXCLK_BAD_IN    : in  std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked)
+      SD_RXCLK_BAD_IN    : in  std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked)
+      SD_RETRY_IN        : in  std_logic; -- '0' = handle byte swapping in logic, '1' = simply restart link and hope
+      SD_ALIGNMENT_IN    : in  std_logic_vector(1 downto 0); -- SerDes Byte alignment ("10" = swapped, "01" = correct)
+      SD_CV_IN            : in  std_logic_vector(1 downto 0); -- SerDes Code Violation ("00" = OK, everything else = BAD)
+      -- control signals
+      FULL_RESET_OUT    : out std_logic; -- full reset AKA quad_reset
+      LANE_RESET_OUT    : out std_logic; -- partial reset AKA lane_reset
+      TX_ALLOW_OUT        : out std_logic; -- allow normal transmit operation
+      RX_ALLOW_OUT        : out std_logic; -- allow normal receive operation
+      SWAP_BYTES_OUT    : out std_logic; -- bytes need swapping ('0' = correct order, '1' = swapped order)
+      -- debug signals
+      STAT_OP            : out std_logic_vector(15 downto 0);
+      CTRL_OP            : in  std_logic_vector(15 downto 0);
+      STAT_DEBUG        : out std_logic_vector(31 downto 0)
+      );
+  end component;
+
+  component signal_sync is
+    generic(
+      WIDTH : integer := 1;     --
+      DEPTH : integer := 3
+      );
+    port(
+      RESET    : in  std_logic; --Reset is neceessary to avoid optimization to shift register
+      CLK0     : in  std_logic;                          --clock for first FF
+      CLK1     : in  std_logic;                          --Clock for other FF
+      D_IN     : in  std_logic_vector(WIDTH-1 downto 0); --Data input
+      D_OUT    : out std_logic_vector(WIDTH-1 downto 0)  --Data output
+      );
+  end component;
+
+  component lattice_ecp2m_fifo_8x8_dualport
+    port (
+      Data: in  std_logic_vector(7 downto 0);
+      WrClock: in  std_logic;
+      RdClock: in  std_logic;
+      WrEn: in  std_logic;
+      RdEn: in  std_logic;
+      Reset: in  std_logic;
+      RPReset: in  std_logic;
+      Q: out  std_logic_vector(7 downto 0);
+      Empty: out  std_logic;
+      Full: out  std_logic
+      );
+  end component;
+
+  component lattice_ecp2m_fifo_16x8_dualport
+    port (
+      Data: in  std_logic_vector(15 downto 0);
+      WrClock: in  std_logic;
+      RdClock: in  std_logic;
+      WrEn: in  std_logic;
+      RdEn: in  std_logic;
+      Reset: in  std_logic;
+      RPReset: in  std_logic;
+      Q: out  std_logic_vector(15 downto 0);
+      Empty: out  std_logic;
+      Full: out  std_logic
+      );
+  end component;
+
+
+
+  type link_error_t is array(0 to 3) of std_logic_vector(7 downto 0);
+  signal link_error : link_error_t;
+  signal link_error_q: link_error_t;
+  signal reg_link_error : link_error_t;
+  signal ffs_plol        : std_logic;
+  signal link_ok         : std_logic_vector(3 downto 0);
+  signal tx_data         : std_logic_vector(8*4-1 downto 0);
+  signal rx_data         : std_logic_vector(8*4-1 downto 0);
+  signal ff_rxfullclk    : std_logic_vector(3 downto 0);
+  signal ff_txfullclk    : std_logic;
+  signal rx_k            : std_logic_vector(3 downto 0);
+  signal tx_k            : std_logic_vector(3 downto 0);
+  signal lane_rst        : std_logic_vector(3 downto 0);
+  signal quad_rst        : std_logic_vector(3 downto 0);
+
+  signal byte_waiting         : std_logic_vector(3 downto 0);
+  signal byte_buffer          : std_logic_vector(4*8-1 downto 0);
+  signal fifo_reset           : std_logic_vector(3 downto 0);
+  signal tx_fifo_dout         : std_logic_vector(4*16-1 downto 0);
+  signal tx_fifo_data_in      : std_logic_vector(4*16-1 downto 0);
+  signal tx_fifo_read_en      : std_logic_vector(3 downto 0);
+  signal tx_fifo_write_en     : std_logic_vector(3 downto 0);
+  signal tx_fifo_empty        : std_logic_vector(3 downto 0);
+  signal tx_fifo_full         : std_logic_vector(3 downto 0);
+  signal last_tx_fifo_read_en : std_logic_vector(3 downto 0);
+  signal last_tx_fifo_empty   : std_logic_vector(3 downto 0);
+  signal tx_fifo_valid_read   : std_logic_vector(3 downto 0);
+  signal tx_allow             : std_logic_vector(3 downto 0);
+
+  signal rx_data_reg      : std_logic_vector(4*8-1 downto 0);
+  signal buf_rx_data      : std_logic_vector(4*8-1 downto 0);
+  signal buf_rx_k         : std_logic_vector(3 downto 0);
+  signal rx_fifo_write_en : std_logic_vector(3 downto 0);
+  signal rx_fifo_read_en  : std_logic_vector(3 downto 0);
+  signal rx_fifo_empty    : std_logic_vector(3 downto 0);
+  signal rx_fifo_full     : std_logic_vector(3 downto 0);
+  signal rx_fifo_dout     : std_logic_vector(4*8-1 downto 0);
+  signal is_idle_word     : std_logic_vector(3 downto 0);
+  signal rx_starting      : std_logic_vector(3 downto 0);
+  signal rx_allow         : std_logic_vector(3 downto 0);
+  signal sd_q             : std_logic_vector(3 downto 0);
+  signal last_rx_fifo_read_en : std_logic_vector(3 downto 0);
+  signal last_rx_fifo_empty   : std_logic_vector(3 downto 0);
+
+  signal buf_med_dataready_out  : std_logic_vector(3 downto 0);
+  signal buf_med_read_out    : std_logic_vector(3 downto 0);
+  signal buf_med_data_out    : std_logic_vector(16*4-1 downto 0);
+  signal byte_select         : std_logic_vector(3 downto 0);
+  signal rx_counter          : std_logic_vector(4*c_NUM_WIDTH-1 downto 0);
+  signal sfp_los             : std_logic_vector(3 downto 0);
+
+  type led_counter_t is array(0 to 3) of std_logic_vector(15 downto 0);
+  signal led_counter    : led_counter_t;
+  signal rx_led        : std_logic_vector(3 downto 0);
+  signal tx_led        : std_logic_vector(3 downto 0);
+
+  signal FSM_STAT_OP    : std_logic_vector(4*16-1 downto 0);
+  signal FSM_STAT_DEBUG : std_logic_vector(4*64-1 downto 0);
+  signal FSM_CTRL_OP    : std_logic_vector(4*16-1 downto 0);
+
+begin
+
+  THE_SERDES: serdes_full_quad
+    port map(
+      core_txrefclk        => CLK_25,
+      core_rxrefclk        => CLK_25,
+      hdinp0               => RXP(0),
+      hdinn0               => RXN(0),
+      hdoutp0              => TXP(0),
+      hdoutn0              => TXN(0),
+      ff_rxiclk_ch0        => ff_rxfullclk(0),
+      ff_txiclk_ch0        => ff_txfullclk,
+      ff_ebrd_clk_0        => ff_rxfullclk(0),
+      ff_txdata_ch0        => tx_data(7 downto 0),
+      ff_rxdata_ch0        => rx_data(7 downto 0),
+      ff_tx_k_cntrl_ch0    => tx_k(0),
+      ff_rx_k_cntrl_ch0    => rx_k(0),
+      ff_rxfullclk_ch0     => ff_rxfullclk(0),
+      ff_force_disp_ch0    => '0',
+      ff_disp_sel_ch0      => '0',
+      ff_correct_disp_ch0  => '0',
+      ff_disp_err_ch0      => link_error(0)(0),
+      ff_cv_ch0            => link_error(0)(1),
+      ffc_rrst_ch0         => '0',
+      ffc_lane_tx_rst_ch0  => lane_rst(0), --lane_rst(0),
+      ffc_lane_rx_rst_ch0  => lane_rst(0),
+      ffc_txpwdnb_ch0      => '1',
+      ffc_rxpwdnb_ch0      => '1',
+      ffs_rlos_lo_ch0      => link_error(0)(2),
+      ffs_ls_sync_status_ch0 => link_ok(0),
+      ffs_cc_underrun_ch0  => link_error(0)(3),
+      ffs_cc_overrun_ch0   => link_error(0)(4),
+      ffs_txfbfifo_error_ch0 => link_error(0)(5),
+      ffs_rxfbfifo_error_ch0 => link_error(0)(6),
+      ffs_rlol_ch0         => link_error(0)(7),
+      oob_out_ch0          => open,
+
+      hdinp1               => rxp(1),
+      hdinn1               => rxn(1),
+      hdoutp1              => txp(1),
+      hdoutn1              => txn(1),
+      ff_rxiclk_ch1        => ff_rxfullclk(1),
+      ff_txiclk_ch1        => ff_txfullclk,
+      ff_ebrd_clk_1        => ff_rxfullclk(1),
+      ff_txdata_ch1        => tx_data(15 downto 8),
+      ff_rxdata_ch1        => rx_data(15 downto 8),
+      ff_tx_k_cntrl_ch1    => tx_k(1),
+      ff_rx_k_cntrl_ch1    => rx_k(1),
+      ff_rxfullclk_ch1     => ff_rxfullclk(1),
+      ff_force_disp_ch1    => '0',
+      ff_disp_sel_ch1      => '0',
+      ff_correct_disp_ch1  => '0',
+      ff_disp_err_ch1      => link_error(1)(0),
+      ff_cv_ch1            => link_error(1)(1),
+      ffc_rrst_ch1         => '0',
+      ffc_lane_tx_rst_ch1  => lane_rst(1), --lane_rst(1),
+      ffc_lane_rx_rst_ch1  => lane_rst(1),
+      ffc_txpwdnb_ch1      => '1',
+      ffc_rxpwdnb_ch1      => '1',
+      ffs_rlos_lo_ch1      => link_error(1)(2),
+      ffs_ls_sync_status_ch1 => link_ok(1),
+      ffs_cc_underrun_ch1  => link_error(1)(3),
+      ffs_cc_overrun_ch1   => link_error(1)(4),
+      ffs_txfbfifo_error_ch1 => link_error(1)(5),
+      ffs_rxfbfifo_error_ch1 => link_error(1)(6),
+      ffs_rlol_ch1         => link_error(1)(7),
+      oob_out_ch1          => open,
+
+      hdinp2               => rxp(2),
+      hdinn2               => rxn(2),
+      hdoutp2              => txp(2),
+      hdoutn2              => txn(2),
+      ff_rxiclk_ch2        => ff_rxfullclk(2),
+      ff_txiclk_ch2        => ff_txfullclk,
+      ff_ebrd_clk_2        => ff_rxfullclk(2),
+      ff_txdata_ch2        => tx_data(23 downto 16),
+      ff_rxdata_ch2        => rx_data(23 downto 16),
+      ff_tx_k_cntrl_ch2    => tx_k(2),
+      ff_rx_k_cntrl_ch2    => rx_k(2),
+      ff_rxfullclk_ch2     => ff_rxfullclk(2),
+      ff_force_disp_ch2    => '0',
+      ff_disp_sel_ch2      => '0',
+      ff_correct_disp_ch2  => '0',
+      ff_disp_err_ch2      => link_error(2)(0),
+      ff_cv_ch2            => link_error(2)(1),
+      ffc_rrst_ch2         => '0',
+      ffc_lane_tx_rst_ch2  => lane_rst(2), --lane_rst(2),
+      ffc_lane_rx_rst_ch2  => lane_rst(2),
+      ffc_txpwdnb_ch2      => '1',
+      ffc_rxpwdnb_ch2      => '1',
+      ffs_rlos_lo_ch2      => link_error(2)(2),
+      ffs_ls_sync_status_ch2 => link_ok(2),
+      ffs_cc_underrun_ch2  => link_error(2)(3),
+      ffs_cc_overrun_ch2   => link_error(2)(4),
+      ffs_txfbfifo_error_ch2 => link_error(2)(5),
+      ffs_rxfbfifo_error_ch2 => link_error(2)(6),
+      ffs_rlol_ch2         => link_error(2)(7),
+      oob_out_ch2          => open,
+
+      hdinp3               => rxp(3),
+      hdinn3               => rxn(3),
+      hdoutp3              => txp(3),
+      hdoutn3              => txn(3),
+      ff_rxiclk_ch3        => ff_rxfullclk(3),
+      ff_txiclk_ch3        => ff_txfullclk,
+      ff_ebrd_clk_3        => ff_rxfullclk(3),
+      ff_txdata_ch3        => tx_data(31 downto 24),
+      ff_rxdata_ch3        => rx_data(31 downto 24),
+      ff_tx_k_cntrl_ch3    => tx_k(3),
+      ff_rx_k_cntrl_ch3    => rx_k(3),
+      ff_rxfullclk_ch3     => ff_rxfullclk(3),
+      ff_force_disp_ch3    => '0',
+      ff_disp_sel_ch3      => '0',
+      ff_correct_disp_ch3  => '0',
+      ff_disp_err_ch3      => link_error(3)(0),
+      ff_cv_ch3            => link_error(3)(1),
+      ffc_rrst_ch3         => '0',
+      ffc_lane_tx_rst_ch3  => lane_rst(3), --lane_rst(3),
+      ffc_lane_rx_rst_ch3  => lane_rst(3),
+      ffc_txpwdnb_ch3      => '1',
+      ffc_rxpwdnb_ch3      => '1',
+      ffs_rlos_lo_ch3      => link_error(3)(2),
+      ffs_ls_sync_status_ch3 => link_ok(3),
+      ffs_cc_underrun_ch3  => link_error(3)(3),
+      ffs_cc_overrun_ch3   => link_error(3)(4),
+      ffs_txfbfifo_error_ch3 => link_error(3)(5),
+      ffs_rxfbfifo_error_ch3 => link_error(3)(6),
+      ffs_rlol_ch3         => link_error(3)(7),
+      oob_out_ch3          => open,
+
+      ffc_macro_rst        => '0',
+      ffc_quad_rst         => quad_rst(0),
+      ffc_trst             => '0',
+      ff_txfullclk         => ff_txfullclk,
+      ffs_plol             => ffs_plol
+      );
+
+--TX Control 25
+---------------
+
+  gen_tx_fifos : for i in 0 to 3 generate
+
+    THE_TX_FIFO: lattice_ecp2m_fifo_16x8_dualport
+      port map(
+        Data    => tx_fifo_data_in((i+1)*16-1 downto i*16),
+        WrClock => CLK,
+        RdClock => ff_txfullclk,
+        WrEn    => tx_fifo_write_en(i),
+        RdEn    => tx_fifo_read_en(i),
+        Reset   => fifo_reset(i),
+        RPReset => fifo_reset(i),
+        Q       => tx_fifo_dout((i+1)*16-1 downto i*16),
+        Empty   => tx_fifo_empty(i),
+        Full    => tx_fifo_full(i)
+        );
+
+    THE_READ_TX_FIFO_PROC: process( ff_txfullclk )
+      begin
+        if( rising_edge(ff_txfullclk) ) then
+          if( reset = '1' ) then
+            byte_waiting(i)               <= '0';
+            tx_fifo_read_en(i)            <= '0';
+            tx_k(i)                       <= '1';
+            tx_data((i+1)*8-1 downto i*8) <= x"EE";
+            tx_fifo_valid_read(i)         <= '0';
+          else
+            tx_fifo_read_en(i)      <= tx_allow(i);
+            last_tx_fifo_read_en(i) <= tx_fifo_read_en(i);
+            last_tx_fifo_empty(i)   <= tx_fifo_empty(i);
+            tx_fifo_valid_read(i)   <= tx_fifo_read_en(i) and not tx_fifo_empty(i);
+            if( byte_waiting(i) = '0' ) then
+              if( (tx_fifo_valid_read(i) = '1')) then
+                byte_buffer((i+1)*8-1 downto i*8) <= tx_fifo_dout((i)*16+15 downto i*16+8);
+                byte_waiting(i)                   <= '1';
+                tx_k(i)                           <= '0';
+                tx_data((i+1)*8-1 downto i*8)     <= tx_fifo_dout(7 downto 0);
+                tx_fifo_read_en(i)                <= tx_allow(i);
+              else
+                byte_buffer((i+1)*8-1 downto i*8) <= x"50";
+                byte_waiting(i)                   <= '1';
+                tx_k(i)                           <= '1';
+                tx_data((i+1)*8-1 downto i*8)     <= x"BC";
+                tx_fifo_read_en(i)                <= tx_allow(i);
+              end if;
+            else --if byte_waiting = '1' then
+              tx_data((i+1)*8-1 downto i*8)       <= byte_buffer((i+1)*8-1 downto i*8);
+              tx_k(i)                             <= '0';  --second byte is always data
+              byte_waiting(i)                     <= '0';
+              tx_fifo_read_en(i)                  <= '0';
+            end if;
+          end if;
+        end if;
+      end process;
+
+    fifo_reset(i) <= reset or quad_rst(0);
+
+  --RX Control (25)
+  ---------------------
+
+    THE_RX_FIFO: lattice_ecp2m_fifo_8x8_dualport
+      port map(
+        Data    => rx_data_reg((i+1)*8-1 downto i*8),
+        WrClock => ff_rxfullclk(i),
+        RdClock => clk,
+        WrEn    => rx_fifo_write_en(i),
+        RdEn    => rx_fifo_read_en(i),
+        Reset   => fifo_reset(i),
+        RPReset => fifo_reset(i),
+        Q       => rx_fifo_dout((i+1)*8-1 downto i*8),
+        Empty   => rx_fifo_empty(i),
+        Full    => rx_fifo_full(i)
+      );
+
+    THE_WRITE_RX_FIFO_PROC: process( ff_rxfullclk )
+      begin
+        if( rising_edge(ff_rxfullclk(i)) ) then
+          buf_rx_data((i+1)*8-1 downto i*8) <= rx_data((i+1)*8-1 downto i*8);
+          buf_rx_k(i) <= rx_k(i);
+          if( (reset = '1') or (rx_allow(i) = '0') ) then
+            rx_fifo_write_en(i) <= '0';
+            is_idle_word(i) <= '1';
+            rx_starting(i) <= '1';
+          else
+            rx_data_reg((i+1)*8-1 downto i*8) <= buf_rx_data((i+1)*8-1 downto i*8);
+            if( rx_allow(i) = '1' ) then
+              if( (rx_k(i) = '0') and (is_idle_word(i) = '0') and (rx_starting(i) = '0') ) then
+                rx_fifo_write_en(i) <= '1';
+              else
+                rx_fifo_write_en(i) <= '0';
+              end if;
+              if   ( buf_rx_k(i) = '1' ) then
+                is_idle_word(i) <= '1';
+                rx_starting(i) <= '0';
+              elsif( (buf_rx_k(i) = '0') and (is_idle_word(i) = '1') ) then
+                is_idle_word(i) <= '0';
+              end if;
+            end if;
+          end if;
+        end if;
+      end process THE_WRITE_RX_FIFO_PROC;
+
+--TX Control (100)
+---------------------
+    buf_med_read_out(i)                  <= not tx_fifo_full(i) and tx_allow(i);
+    tx_fifo_write_en(i)                  <= buf_med_read_out(i) and med_dataready_in(i);
+    tx_fifo_data_in(i*16+15 downto i*16) <= med_data_in(i*16+15 downto i*16);
+    med_read_out(i)                      <= buf_med_read_out(i);
+
+--RX Control (100)
+---------------------
+    process( clk )
+      begin
+        if( rising_edge(clk) ) then
+          if( reset = '1' ) then
+            buf_med_dataready_out(i) <= '0';
+            byte_select(i)           <= '0';
+            last_rx_fifo_read_en(i)  <= '0';
+          else
+            last_rx_fifo_read_en(i)  <= rx_fifo_read_en(i);
+            buf_med_dataready_out(i) <= '0';
+            if( (last_rx_fifo_empty(i) = '0') and (last_rx_fifo_read_en(i) = '1') ) then
+              if( byte_select(i) = '1' ) then
+                buf_MED_DATA_OUT((i+1)*16-1 downto i*16) <= rx_fifo_dout((i+1)*8-1 downto i*8)
+                                                            & buf_MED_DATA_OUT(i*16+7 downto i*16);
+                buf_MED_DATAREADY_OUT(i) <= '1';
+              else
+                buf_MED_DATA_OUT((i+1)*16-1 downto i*16)      <= x"00" & rx_fifo_dout((i+1)*8-1 downto i*8);
+              end if;
+              byte_select(i) <= not byte_select(i);
+            end if;
+          end if;
+        end if;
+      end process;
+
+    rx_fifo_read_en(i)                                           <= tx_allow(i);
+    MED_DATA_OUT((i+1)*16-1 downto i*16)                         <= buf_MED_DATA_OUT((i+1)*16-1 downto i*16);
+    MED_DATAREADY_OUT(i)                                         <= buf_MED_DATAREADY_OUT(i);
+    MED_PACKET_NUM_OUT((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) <= rx_counter((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH);
+
+--rx packet counter
+---------------------
+    THE_RX_PACKETS_PROC: process( clk )
+      begin
+        if( rising_edge(clk) ) then
+          last_rx_fifo_empty(i) <= rx_fifo_empty(i);
+          if( (reset = '1') or (rx_allow(i) = '0') ) then
+            rx_counter(i*3+2 downto i*3) <= c_H0;
+          else
+            if( buf_med_dataready_out(i) = '1' ) then
+              if( rx_counter(i*3+2 downto i*3) = c_max_word_number ) then
+                rx_counter(i*3+2 downto i*3) <= (others => '0');
+              else
+                rx_counter(i*3+2 downto i*3) <= rx_counter(i*3+2 downto i*3) + 1;
+              end if;
+            end if;
+          end if;
+        end if;
+      end process;
+
+
+
+--Link State machine
+---------------------
+
+
+    LINK_ERROR_SYNC: signal_sync
+      generic map(
+        DEPTH => 2,
+        WIDTH => 8
+        )
+      port map(
+        RESET    => reset,
+        D_IN(7 downto 0)  => link_error(i),
+        CLK0     => ff_rxfullclk(i),
+        CLK1     => CLK,
+        D_OUT(7 downto 0) => link_error_q(i)
+        );
+
+    SD_SYNC_2: signal_sync
+      generic map(
+        DEPTH => 2,
+        WIDTH => 1
+        )
+      port map(
+        RESET    => reset,
+        D_IN(0)  => sd(i),
+        CLK0     => ff_rxfullclk(i),
+        CLK1     => CLK,
+        D_OUT(0) => sd_q(i)
+        );
+
+--LED Signals
+---------------------
+    THE_TX_RX_LED_PROC: process( clk )
+      begin
+        if( rising_edge(CLK) ) then
+          led_counter(i) <= led_counter(i) + 1;
+          if   ( buf_med_dataready_out(i) = '1' ) then
+            rx_led(i) <= '1';
+          elsif( led_counter(i) = 0 ) then
+            rx_led(i) <= '0';
+          end if;
+          if( tx_fifo_valid_read(i) = '1') then
+            tx_led(i) <= '1';
+          elsif led_counter(i) = 0 then
+            tx_led(i) <= '0';
+          end if;
+        end if;
+      end process;
+
+
+    STAT_OP(i*16+9 downto i*16+0)   <= FSM_STAT_OP(i*16+9 downto i*16+0);
+    STAT_OP(i*16+10) <= rx_led(i);
+    STAT_OP(i*16+11) <= tx_led(i);
+    STAT_OP(i*16+15 downto i*16+12) <= FSM_STAT_OP(i*16+15 downto i*16+12);
+
+    STAT_DEBUG(i*64+31 downto i*64+0) <= FSM_STAT_DEBUG(i*32+31 downto i*32);
+    STAT_DEBUG(i*64+39 downto i*64+32) <= rx_data_reg(i*8+7 downto i*8);
+    STAT_DEBUG(i*64+63 downto i*64+40) <= (others => '0');
+
+  end generate;
+
+
+  gen_lsm : for i in 0 to 3 generate
+    THE_SFP_LSM: trb_net16_lsm_sfp
+      port map(
+        SYSCLK            => CLK,
+        RESET             => reset,
+        CLEAR             => reset,
+        SFP_MISSING_IN    => '0',
+        SFP_LOS_IN        => sfp_los(i),
+        SD_LINK_OK_IN     => link_ok(i),
+        SD_LOS_IN         => link_error(i)(2),
+        SD_TXCLK_BAD_IN   => ffs_plol,
+        SD_RXCLK_BAD_IN   => link_error(i)(7),
+        SD_RETRY_IN       => '0', -- '0' = handle byte swapping in logic, '1' = simply restart link and hope
+        SD_ALIGNMENT_IN   => "10",
+        SD_CV_IN(0)       => link_error(i)(1),
+        SD_CV_IN(1)       => '0',
+        FULL_RESET_OUT    => quad_rst(i),
+        LANE_RESET_OUT    => lane_rst(i),
+        TX_ALLOW_OUT      => tx_allow(i),
+        RX_ALLOW_OUT      => rx_allow(i),
+        SWAP_BYTES_OUT    => open,
+        STAT_OP           => FSM_STAT_OP(i*16+15 downto i*16),
+        CTRL_OP           => FSM_CTRL_OP(i*16+15 downto i*16),
+        STAT_DEBUG        => FSM_STAT_DEBUG(i*32+31 downto i*32)
+        );
+
+  end generate;
+
+  sfp_los <= not sd_q;
+  FSM_CTRL_OP <= CTRL_OP;
+
+
+
+
+
+end architecture;
\ No newline at end of file
diff --git a/media_interfaces/trb_net16_med_ecp_sfp.vhd b/media_interfaces/trb_net16_med_ecp_sfp.vhd
new file mode 100644 (file)
index 0000000..00e4ea6
--- /dev/null
@@ -0,0 +1,805 @@
+--Media interface for Lattice ECP2M using PCS at 2GHz
+
+--Still missing: link reset features, fifo full error handling, signals on stat_op
+
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.std_logic_ARITH.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+
+entity trb_net16_med_ecp_sfp is
+  generic(
+    SERDES_NUM : integer range 0 to 3 := 2
+    );
+  port(
+    CLK        : in  std_logic; -- SerDes clock
+    SYSCLK     : in  std_logic; -- fabric clock
+    RESET        : in  std_logic; -- synchronous reset
+    CLEAR        : in  std_logic; -- asynchronous reset
+    CLK_EN       : in  std_logic;
+    --Internal Connection
+    MED_DATA_IN        : in  std_logic_vector(c_DATA_WIDTH-1 downto 0);
+    MED_PACKET_NUM_IN  : in  std_logic_vector(c_NUM_WIDTH-1 downto 0);
+    MED_DATAREADY_IN   : in  std_logic;
+    MED_READ_OUT       : out std_logic;
+    MED_DATA_OUT       : out std_logic_vector(c_DATA_WIDTH-1 downto 0);
+    MED_PACKET_NUM_OUT : out std_logic_vector(c_NUM_WIDTH-1 downto 0);
+    MED_DATAREADY_OUT  : out std_logic;
+    MED_READ_IN        : in  std_logic;
+    REFCLK2CORE_OUT    : out std_logic;
+    --SFP Connection
+    SD_RXD_P_IN        : in  std_logic;
+    SD_RXD_N_IN        : in  std_logic;
+    SD_TXD_P_OUT       : out std_logic;
+    SD_TXD_N_OUT       : out std_logic;
+    SD_REFCLK_P_IN     : in  std_logic;
+    SD_REFCLK_N_IN     : in  std_logic;
+    SD_PRSNT_N_IN      : in  std_logic; -- SFP Present ('0' = SFP in place, '1' = no SFP mounted)
+    SD_LOS_IN          : in  std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
+    -- Status and control port
+    STAT_OP            : out  std_logic_vector (15 downto 0);
+    CTRL_OP            : in  std_logic_vector (15 downto 0);
+    STAT_DEBUG         : out  std_logic_vector (63 downto 0);
+    CTRL_DEBUG         : in  std_logic_vector (63 downto 0)
+   );
+end entity;
+
+architecture med_ecp_sfp of trb_net16_med_ecp_sfp is
+
+  component serdes_0
+    port(
+     core_txrefclk : in std_logic;
+     core_rxrefclk : in std_logic;
+      hdinp0 : in std_logic;
+      hdinn0 : in std_logic;
+      ff_rxiclk_ch0 : in std_logic;
+      ff_txiclk_ch0 : in std_logic;
+      ff_ebrd_clk_0 : in std_logic;
+      ff_txdata_ch0 : in std_logic_vector(15 downto 0);
+      ff_tx_k_cntrl_ch0 : in std_logic_vector(1 downto 0);
+      ff_force_disp_ch0 : in std_logic_vector(1 downto 0);
+      ff_disp_sel_ch0 : in std_logic_vector(1 downto 0);
+      ff_correct_disp_ch0 : in std_logic_vector(1 downto 0);
+      ffc_rrst_ch0 : in std_logic;
+      ffc_lane_tx_rst_ch0 : in std_logic;
+      ffc_lane_rx_rst_ch0 : in std_logic;
+      ffc_txpwdnb_ch0 : in std_logic;
+      ffc_rxpwdnb_ch0 : in std_logic;
+      ffc_macro_rst : in std_logic;
+      ffc_quad_rst : in std_logic;
+      ffc_trst : in std_logic;
+      hdoutp0 : out std_logic;
+      hdoutn0 : out std_logic;
+      ff_rxdata_ch0 : out std_logic_vector(15 downto 0);
+      ff_rx_k_cntrl_ch0 : out std_logic_vector(1 downto 0);
+      ff_rxfullclk_ch0 : out std_logic;
+      ff_rxhalfclk_ch0 : out std_logic;
+      ff_disp_err_ch0 : out std_logic_vector(1 downto 0);
+      ff_cv_ch0 : out std_logic_vector(1 downto 0);
+      ffs_rlos_lo_ch0 : out std_logic;
+      ffs_ls_sync_status_ch0 : out std_logic;
+      ffs_cc_underrun_ch0 : out std_logic;
+      ffs_cc_overrun_ch0 : out std_logic;
+      ffs_txfbfifo_error_ch0 : out std_logic;
+      ffs_rxfbfifo_error_ch0 : out std_logic;
+      ffs_rlol_ch0 : out std_logic;
+      oob_out_ch0 : out std_logic;
+      ff_txfullclk : out std_logic;
+      ff_txhalfclk : out std_logic;
+      refck2core : out std_logic;
+      ffs_plol : out std_logic
+      );
+  end component;
+
+  component serdes_1
+    port(
+      core_txrefclk : in std_logic;
+      core_rxrefclk : in std_logic;
+      refclkp : IN std_logic;
+      refclkn : IN std_logic;
+      hdinp1 : in std_logic;
+      hdinn1 : in std_logic;
+      ff_rxiclk_ch1 : in std_logic;
+      ff_txiclk_ch1 : in std_logic;
+      ff_ebrd_clk_1 : in std_logic;
+      ff_txdata_ch1 : in std_logic_vector(15 downto 0);
+      ff_tx_k_cntrl_ch1 : in std_logic_vector(1 downto 0);
+      ff_force_disp_ch1 : in std_logic_vector(1 downto 0);
+      ff_disp_sel_ch1 : in std_logic_vector(1 downto 0);
+      ff_correct_disp_ch1 : in std_logic_vector(1 downto 0);
+      ffc_rrst_ch1 : in std_logic;
+      ffc_lane_tx_rst_ch1 : in std_logic;
+      ffc_lane_rx_rst_ch1 : in std_logic;
+      ffc_txpwdnb_ch1 : in std_logic;
+      ffc_rxpwdnb_ch1 : in std_logic;
+      ffc_macro_rst : in std_logic;
+      ffc_quad_rst : in std_logic;
+      ffc_trst : in std_logic;
+      hdoutp1 : out std_logic;
+      hdoutn1 : out std_logic;
+      ff_rxdata_ch1 : out std_logic_vector(15 downto 0);
+      ff_rx_k_cntrl_ch1 : out std_logic_vector(1 downto 0);
+      ff_rxfullclk_ch1 : out std_logic;
+      ff_rxhalfclk_ch1 : out std_logic;
+      ff_disp_err_ch1 : out std_logic_vector(1 downto 0);
+      ff_cv_ch1 : out std_logic_vector(1 downto 0);
+      ffs_rlos_lo_ch1 : out std_logic;
+      ffs_ls_sync_status_ch1 : out std_logic;
+      ffs_cc_underrun_ch1 : out std_logic;
+      ffs_cc_overrun_ch1 : out std_logic;
+      ffs_txfbfifo_error_ch1 : out std_logic;
+      ffs_rxfbfifo_error_ch1 : out std_logic;
+      ffs_rlol_ch1 : out std_logic;
+      oob_out_ch1 : out std_logic;
+      ff_txfullclk : out std_logic;
+      ff_txhalfclk : out std_logic;
+      refck2core : out std_logic;
+      ffs_plol : out std_logic
+      );
+  end component;
+
+
+  component serdes_2
+    port(
+      core_txrefclk : in std_logic;
+      core_rxrefclk : in std_logic;
+      hdinp2 : in std_logic;
+      hdinn2 : in std_logic;
+      ff_rxiclk_ch2 : in std_logic;
+      ff_txiclk_ch2 : in std_logic;
+      ff_ebrd_clk_2 : in std_logic;
+      ff_txdata_ch2 : in std_logic_vector(15 downto 0);
+      ff_tx_k_cntrl_ch2 : in std_logic_vector(1 downto 0);
+      ff_force_disp_ch2 : in std_logic_vector(1 downto 0);
+      ff_disp_sel_ch2 : in std_logic_vector(1 downto 0);
+      ff_correct_disp_ch2 : in std_logic_vector(1 downto 0);
+      ffc_rrst_ch2 : in std_logic;
+      ffc_lane_tx_rst_ch2 : in std_logic;
+      ffc_lane_rx_rst_ch2 : in std_logic;
+      ffc_txpwdnb_ch2 : in std_logic;
+      ffc_rxpwdnb_ch2 : in std_logic;
+      ffc_macro_rst : in std_logic;
+      ffc_quad_rst : in std_logic;
+      ffc_trst : in std_logic;
+      hdoutp2 : out std_logic;
+      hdoutn2 : out std_logic;
+      ff_rxdata_ch2 : out std_logic_vector(15 downto 0);
+      ff_rx_k_cntrl_ch2 : out std_logic_vector(1 downto 0);
+      ff_rxfullclk_ch2 : out std_logic;
+      ff_rxhalfclk_ch2 : out std_logic;
+      ff_disp_err_ch2 : out std_logic_vector(1 downto 0);
+      ff_cv_ch2 : out std_logic_vector(1 downto 0);
+      ffs_rlos_lo_ch2 : out std_logic;
+      ffs_ls_sync_status_ch2 : out std_logic;
+      ffs_cc_underrun_ch2 : out std_logic;
+      ffs_cc_overrun_ch2 : out std_logic;
+      ffs_txfbfifo_error_ch2 : out std_logic;
+      ffs_rxfbfifo_error_ch2 : out std_logic;
+      ffs_rlol_ch2 : out std_logic;
+      oob_out_ch2 : out std_logic;
+      ff_txfullclk : out std_logic;
+      ff_txhalfclk : out std_logic;
+      refck2core : out std_logic;
+      ffs_plol : out std_logic
+      );
+  end component;
+
+  component serdes_3
+    port(
+      core_txrefclk : in std_logic;
+      core_rxrefclk : in std_logic;
+      hdinp3 : in std_logic;
+      hdinn3 : in std_logic;
+      ff_rxiclk_ch3 : in std_logic;
+      ff_txiclk_ch3 : in std_logic;
+      ff_ebrd_clk_3 : in std_logic;
+      ff_txdata_ch3 : in std_logic_vector(15 downto 0);
+      ff_tx_k_cntrl_ch3 : in std_logic_vector(1 downto 0);
+      ff_force_disp_ch3 : in std_logic_vector(1 downto 0);
+      ff_disp_sel_ch3 : in std_logic_vector(1 downto 0);
+      ff_correct_disp_ch3 : in std_logic_vector(1 downto 0);
+      ffc_rrst_ch3 : in std_logic;
+      ffc_lane_tx_rst_ch3 : in std_logic;
+      ffc_lane_rx_rst_ch3 : in std_logic;
+      ffc_txpwdnb_ch3 : in std_logic;
+      ffc_rxpwdnb_ch3 : in std_logic;
+      ffc_macro_rst : in std_logic;
+      ffc_quad_rst : in std_logic;
+      ffc_trst : in std_logic;
+      hdoutp3 : out std_logic;
+      hdoutn3 : out std_logic;
+      ff_rxdata_ch3 : out std_logic_vector(15 downto 0);
+      ff_rx_k_cntrl_ch3 : out std_logic_vector(1 downto 0);
+      ff_rxfullclk_ch3 : out std_logic;
+      ff_rxhalfclk_ch3 : out std_logic;
+      ff_disp_err_ch3 : out std_logic_vector(1 downto 0);
+      ff_cv_ch3 : out std_logic_vector(1 downto 0);
+      ffs_rlos_lo_ch3 : out std_logic;
+      ffs_ls_sync_status_ch3 : out std_logic;
+      ffs_cc_underrun_ch3 : out std_logic;
+      ffs_cc_overrun_ch3 : out std_logic;
+      ffs_txfbfifo_error_ch3 : out std_logic;
+      ffs_rxfbfifo_error_ch3 : out std_logic;
+      ffs_rlol_ch3 : out std_logic;
+      oob_out_ch3 : out std_logic;
+      ff_txfullclk : out std_logic;
+      ff_txhalfclk : out std_logic;
+      refck2core : out std_logic;
+      ffs_plol : out std_logic
+      );
+  end component;
+
+  component trb_net16_lsm_sfp is
+    port(
+      SYSCLK            : in  std_logic; -- fabric clock
+      RESET                : in  std_logic; -- synchronous reset
+      CLEAR                : in  std_logic; -- asynchronous reset, connect to '0' if not needed / available
+      -- status signals
+      SFP_MISSING_IN    : in  std_logic; -- SFP Present ('0' = no SFP mounted, '1' = SFP in place)
+      SFP_LOS_IN        : in  std_logic; -- SFP Loss Of Signal ('0' = OK, '1' = no signal)
+      SD_LINK_OK_IN        : in  std_logic; -- SerDes Link OK ('0' = not linked, '1' link established)
+      SD_LOS_IN            : in  std_logic; -- SerDes Loss Of Signal ('0' = OK, '1' = signal lost)
+      SD_TXCLK_BAD_IN    : in  std_logic; -- SerDes Tx Clock locked ('0' = locked, '1' = not locked)
+      SD_RXCLK_BAD_IN    : in  std_logic; -- SerDes Rx Clock locked ('0' = locked, '1' = not locked)
+      SD_RETRY_IN        : in  std_logic; -- '0' = handle byte swapping in logic, '1' = simply restart link and hope
+      SD_ALIGNMENT_IN    : in  std_logic_vector(1 downto 0); -- SerDes Byte alignment ("10" = swapped, "01" = correct)
+      SD_CV_IN            : in  std_logic_vector(1 downto 0); -- SerDes Code Violation ("00" = OK, everything else = BAD)
+      -- control signals
+      FULL_RESET_OUT    : out std_logic; -- full reset AKA quad_reset
+      LANE_RESET_OUT    : out std_logic; -- partial reset AKA lane_reset
+      TX_ALLOW_OUT        : out std_logic; -- allow normal transmit operation
+      RX_ALLOW_OUT        : out std_logic; -- allow normal receive operation
+      SWAP_BYTES_OUT    : out std_logic; -- bytes need swapping ('0' = correct order, '1' = swapped order)
+      -- debug signals
+      STAT_OP            : out std_logic_vector(15 downto 0);
+      CTRL_OP            : in  std_logic_vector(15 downto 0);
+      STAT_DEBUG        : out std_logic_vector(31 downto 0)
+      );
+  end component;
+
+  component trb_net_fifo_16bit_bram_dualport is
+    generic(
+      USE_STATUS_FLAGS : integer  := c_YES
+        );
+    port( read_clock_in    : in  std_logic;
+        write_clock_in  : in  std_logic;
+        read_enable_in  : in  std_logic;
+        write_enable_in  : in  std_logic;
+        fifo_gsr_in    : in  std_logic;
+        write_data_in    : in  std_logic_vector(17 downto 0);
+        read_data_out    : out  std_logic_vector(17 downto 0);
+        full_out      : out  std_logic;
+        empty_out      : out  std_logic;
+        fifostatus_out  : out  std_logic_vector(3 downto 0);
+        valid_read_out  : out  std_logic;
+        almost_empty_out  : out  std_logic;
+        almost_full_out  : out  std_logic
+      );
+  end component;
+
+  component signal_sync is
+    generic(
+      WIDTH : integer := 1;     --
+      DEPTH : integer := 3
+      );
+    port(
+      RESET    : in  std_logic; --Reset is neceessary to avoid optimization to shift register
+      CLK0     : in  std_logic;                          --clock for first FF
+      CLK1     : in  std_logic;                          --Clock for other FF
+      D_IN     : in  std_logic_vector(WIDTH-1 downto 0); --Data input
+      D_OUT    : out std_logic_vector(WIDTH-1 downto 0)  --Data output
+      );
+  end component;
+
+  signal refck2core      : std_logic;
+  signal clock           : std_logic;
+  --reset signals
+  signal ffc_quad_rst      : std_logic;
+  signal ffc_lane_tx_rst   : std_logic;
+  signal ffc_lane_rx_rst   : std_logic;
+  --serdes connections
+  signal tx_data        : std_logic_vector(15 downto 0);
+  signal tx_k          : std_logic_vector(1 downto 0);
+  signal rx_data        : std_logic_vector(15 downto 0);
+  signal rx_k          : std_logic_vector(1 downto 0);
+  signal link_ok        : std_logic_vector(0 downto 0);
+  signal link_error      : std_logic_vector(8 downto 0);
+  signal ff_rxhalfclk      : std_logic;
+  signal ff_txhalfclk      : std_logic;
+  --rx fifo signals
+  signal fifo_rx_rd_en    : std_logic;
+  signal fifo_rx_wr_en    : std_logic;
+  signal fifo_rx_reset    : std_logic;
+  signal fifo_rx_din      : std_logic_vector(17 downto 0);
+  signal fifo_rx_dout      : std_logic_vector(17 downto 0);
+  signal fifo_rx_full      : std_logic;
+  signal fifo_rx_empty    : std_logic;
+  --tx fifo signals
+  signal fifo_tx_rd_en    : std_logic;
+  signal fifo_tx_wr_en    : std_logic;
+  signal fifo_tx_reset    : std_logic;
+  signal fifo_tx_din      : std_logic_vector(17 downto 0);
+  signal fifo_tx_dout      : std_logic_vector(17 downto 0);
+  signal fifo_tx_full      : std_logic;
+  signal fifo_tx_empty    : std_logic;
+  --rx path
+  signal rx_counter        : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal buf_med_dataready_out  : std_logic;
+  signal buf_med_data_out      : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal buf_med_packet_num_out  : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal last_rx          : std_logic_vector(8 downto 0);
+  signal last_fifo_rx_empty    : std_logic;
+  --tx path
+  signal last_fifo_tx_empty    : std_logic;
+  --link status
+  signal link_led : std_logic;
+  signal rx_k_q            : std_logic_vector(1 downto 0);
+
+  signal info_led          : std_logic;
+
+  signal quad_rst      : std_logic;
+  signal lane_rst      : std_logic;
+  signal tx_allow      : std_logic;
+  signal rx_allow      : std_logic;
+
+  signal rx_allow_q        : std_logic; -- clock domain changed signal
+  signal tx_allow_q        : std_logic;
+  signal swap_bytes        : std_logic;
+  signal buf_stat_debug    : std_logic_vector(31 downto 0);
+
+  -- status inputs from SFP
+  signal sfp_prsnt_n       : std_logic; -- synchronized input signals
+  signal sfp_los           : std_logic; -- synchronized input signals
+
+  signal buf_STAT_OP          : std_logic_vector(15 downto 0);
+
+  signal led_counter          : std_logic_vector(17 downto 0);
+  signal rx_led, tx_led       : std_logic;
+
+
+begin
+
+--------------------------------------------------------------------------
+-- Main control state machine, startup control for SFP
+--------------------------------------------------------------------------
+clock <= SYSCLK;
+
+-- Input synchronizer
+
+THE_SFP_STATUS_SYNC: signal_sync
+  generic map(
+    DEPTH => 3,
+    WIDTH => 2
+    )
+  port map(
+    RESET    => RESET,
+    D_IN(0)  => SD_PRSNT_N_IN,
+    D_IN(1)  => SD_LOS_IN,
+    CLK0     => clock,
+    CLK1     => clock,
+    D_OUT(0) => sfp_prsnt_n,
+    D_OUT(1) => sfp_los
+    );
+
+-- Transfering the komma delimiter in the *training* phase
+THE_RX_K_SYNC: signal_sync
+  generic map(
+    DEPTH => 3,
+    WIDTH => 2
+    )
+  port map(
+    RESET    => RESET,
+    D_IN     => rx_k,
+    CLK0     => ff_rxhalfclk,
+    CLK1     => clock,
+    D_OUT    => rx_k_q
+    );
+
+----------------------------------------------------------------------------------------------------------
+-- NEW STATEMACHINE START
+----------------------------------------------------------------------------------------------------------
+THE_SFP_LSM: trb_net16_lsm_sfp
+    port map(
+      SYSCLK            => clock,
+      RESET             => reset,
+      CLEAR             => clear,
+      SFP_MISSING_IN    => sfp_prsnt_n,
+      SFP_LOS_IN        => sfp_los,
+      SD_LINK_OK_IN        => link_ok(0),
+      SD_LOS_IN         => link_error(8),
+      SD_TXCLK_BAD_IN   => link_error(5),
+      SD_RXCLK_BAD_IN   => link_error(4),
+      SD_RETRY_IN       => '0', -- '0' = handle byte swapping in logic, '1' = simply restart link and hope
+      SD_ALIGNMENT_IN    => rx_k_q,
+      SD_CV_IN          => link_error(7 downto 6),
+      FULL_RESET_OUT    => quad_rst,
+      LANE_RESET_OUT    => lane_rst,
+      TX_ALLOW_OUT      => tx_allow,
+      RX_ALLOW_OUT      => rx_allow,
+      SWAP_BYTES_OUT    => swap_bytes,
+      STAT_OP           => buf_stat_op,
+      CTRL_OP           => ctrl_op,
+      STAT_DEBUG        => buf_stat_debug
+      );
+----------------------------------------------------------------------------------------------------------
+-- NEW STATEMACHINE STOP
+----------------------------------------------------------------------------------------------------------
+
+THE_RX_ALLOW_SYNC: signal_sync -- really needed?!?
+  generic map(
+    DEPTH => 2,
+    WIDTH => 2
+    )
+  port map(
+    RESET    => RESET,
+    D_IN(0)  => rx_allow,
+    D_IN(1)  => tx_allow,
+    CLK0     => clock, --ff_rxhalfclk,
+    CLK1     => clock, --ff_rxhalfclk,
+    D_OUT(0) => rx_allow_q,
+    D_OUT(1) => tx_allow_q
+    );
+
+--------------------------------------------------------------------------
+--------------------------------------------------------------------------
+
+ffc_quad_rst         <= quad_rst;
+ffc_lane_tx_rst      <= lane_rst;
+ffc_lane_rx_rst      <= lane_rst;
+
+-- SerDes clock output to FPGA fabric
+REFCLK2CORE_OUT <= refck2core;
+
+-- Instantiation of serdes module
+  gen_serdes_0 : if SERDES_NUM = 0 generate
+    THE_SERDES: serdes_0
+      port map(
+             core_txrefclk          => clk,
+             core_rxrefclk          => clk,
+              hdinp0                 => sd_rxd_p_in,
+              hdinn0                 => sd_rxd_n_in,
+              ff_rxiclk_ch0          => ff_rxhalfclk,
+              ff_txiclk_ch0          => ff_txhalfclk,
+              ff_ebrd_clk_0          => ff_rxhalfclk, -- not used, just for completeness
+              ff_txdata_ch0          => tx_data,
+              ff_tx_k_cntrl_ch0      => tx_k,
+              ff_force_disp_ch0      => "00",
+              ff_disp_sel_ch0        => "00",
+              ff_correct_disp_ch0    => "00",
+              ffc_rrst_ch0           => '0',
+              ffc_lane_tx_rst_ch0    => ffc_lane_tx_rst,
+              ffc_lane_rx_rst_ch0    => ffc_lane_rx_rst,
+              ffc_txpwdnb_ch0        => '1',
+              ffc_rxpwdnb_ch0        => '1',
+              ffc_macro_rst          => '0',
+              ffc_quad_rst           => ffc_quad_rst,
+              ffc_trst               => '0',
+              hdoutp0                => sd_txd_p_out,
+              hdoutn0                => sd_txd_n_out,
+              ff_rxdata_ch0          => rx_data, --comb_rx_data,
+              ff_rx_k_cntrl_ch0      => rx_k, --comb_rx_k,
+              ff_rxfullclk_ch0       => open,
+              ff_rxhalfclk_ch0       => ff_rxhalfclk,
+              ff_disp_err_ch0        => open,
+              ff_cv_ch0              => link_error(7 downto 6),
+              ffs_rlos_lo_ch0        => link_error(8),
+              ffs_ls_sync_status_ch0 => link_ok(0),
+              ffs_cc_underrun_ch0    => link_error(0),
+              ffs_cc_overrun_ch0     => link_error(1),
+              ffs_txfbfifo_error_ch0 => link_error(2),
+              ffs_rxfbfifo_error_ch0 => link_error(3),
+              ffs_rlol_ch0           => link_error(4),
+              oob_out_ch0            => open,
+              ff_txfullclk           => open,
+              ff_txhalfclk           => ff_txhalfclk,
+              refck2core             => refck2core,
+              ffs_plol               => link_error(5)
+            );
+  end generate;
+  gen_serdes_1 : if SERDES_NUM = 1 generate
+    THE_SERDES: serdes_1
+      port map(
+              core_txrefclk          => clk,
+              core_rxrefclk          => clk,
+              refclkp                => SD_REFCLK_P_IN,
+              refclkn                => SD_REFCLK_N_IN,
+              hdinp1                 => sd_rxd_p_in,
+              hdinn1                 => sd_rxd_n_in,
+              ff_rxiclk_ch1          => ff_rxhalfclk,
+              ff_txiclk_ch1          => ff_txhalfclk,
+              ff_ebrd_clk_1          => ff_rxhalfclk, -- not used, just for completeness
+              ff_txdata_ch1          => tx_data,
+              ff_tx_k_cntrl_ch1      => tx_k,
+              ff_force_disp_ch1      => "00",
+              ff_disp_sel_ch1        => "00",
+              ff_correct_disp_ch1    => "00",
+              ffc_rrst_ch1           => '0',
+              ffc_lane_tx_rst_ch1    => ffc_lane_tx_rst,
+              ffc_lane_rx_rst_ch1    => ffc_lane_rx_rst,
+              ffc_txpwdnb_ch1        => '1',
+              ffc_rxpwdnb_ch1        => '1',
+              ffc_macro_rst          => '0',
+              ffc_quad_rst           => ffc_quad_rst,
+              ffc_trst               => '0',
+              hdoutp1                => sd_txd_p_out,
+              hdoutn1                => sd_txd_n_out,
+              ff_rxdata_ch1          => rx_data, --comb_rx_data,
+              ff_rx_k_cntrl_ch1      => rx_k, --comb_rx_k,
+              ff_rxfullclk_ch1       => open,
+              ff_rxhalfclk_ch1       => ff_rxhalfclk,
+              ff_disp_err_ch1        => open,
+              ff_cv_ch1              => link_error(7 downto 6),
+              ffs_rlos_lo_ch1        => link_error(8),
+              ffs_ls_sync_status_ch1 => link_ok(0),
+              ffs_cc_underrun_ch1    => link_error(0),
+              ffs_cc_overrun_ch1     => link_error(1),
+              ffs_txfbfifo_error_ch1 => link_error(2),
+              ffs_rxfbfifo_error_ch1 => link_error(3),
+              ffs_rlol_ch1           => link_error(4),
+              oob_out_ch1            => open,
+              ff_txfullclk           => open,
+              ff_txhalfclk           => ff_txhalfclk,
+              refck2core             => refck2core,
+              ffs_plol               => link_error(5)
+            );
+  end generate;
+  gen_serdes_2 : if SERDES_NUM = 2 generate
+    THE_SERDES: serdes_2
+      port map(
+              core_txrefclk          => clk,
+              core_rxrefclk          => clk,
+              hdinp2                 => sd_rxd_p_in,
+              hdinn2                 => sd_rxd_n_in,
+              ff_rxiclk_ch2          => ff_rxhalfclk,
+              ff_txiclk_ch2          => ff_txhalfclk,
+              ff_ebrd_clk_2          => ff_rxhalfclk, -- not used, just for completeness
+              ff_txdata_ch2          => tx_data,
+              ff_tx_k_cntrl_ch2      => tx_k,
+              ff_force_disp_ch2      => "00",
+              ff_disp_sel_ch2        => "00",
+              ff_correct_disp_ch2    => "00",
+              ffc_rrst_ch2           => '0',
+              ffc_lane_tx_rst_ch2    => ffc_lane_tx_rst,
+              ffc_lane_rx_rst_ch2    => ffc_lane_rx_rst,
+              ffc_txpwdnb_ch2        => '1',
+              ffc_rxpwdnb_ch2        => '1',
+              ffc_macro_rst          => '0',
+              ffc_quad_rst           => ffc_quad_rst,
+              ffc_trst               => '0',
+              hdoutp2                => sd_txd_p_out,
+              hdoutn2                => sd_txd_n_out,
+              ff_rxdata_ch2          => rx_data, --comb_rx_data,
+              ff_rx_k_cntrl_ch2      => rx_k, --comb_rx_k,
+              ff_rxfullclk_ch2       => open,
+              ff_rxhalfclk_ch2       => ff_rxhalfclk,
+              ff_disp_err_ch2        => open,
+              ff_cv_ch2              => link_error(7 downto 6),
+              ffs_rlos_lo_ch2        => link_error(8),
+              ffs_ls_sync_status_ch2 => link_ok(0),
+              ffs_cc_underrun_ch2    => link_error(0),
+              ffs_cc_overrun_ch2     => link_error(1),
+              ffs_txfbfifo_error_ch2 => link_error(2),
+              ffs_rxfbfifo_error_ch2 => link_error(3),
+              ffs_rlol_ch2           => link_error(4),
+              oob_out_ch2            => open,
+              ff_txfullclk           => open,
+              ff_txhalfclk           => ff_txhalfclk,
+              refck2core             => refck2core,
+              ffs_plol               => link_error(5)
+            );
+  end generate;
+  gen_serdes_3 : if SERDES_NUM = 3 generate
+    THE_SERDES: serdes_3
+      port map(
+              core_txrefclk          => clk,
+              core_rxrefclk          => clk,
+              hdinp3                 => sd_rxd_p_in,
+              hdinn3                 => sd_rxd_n_in,
+              ff_rxiclk_ch3          => ff_rxhalfclk,
+              ff_txiclk_ch3          => ff_txhalfclk,
+              ff_ebrd_clk_3          => ff_rxhalfclk, -- not used, just for completeness
+              ff_txdata_ch3          => tx_data,
+              ff_tx_k_cntrl_ch3      => tx_k,
+              ff_force_disp_ch3      => "00",
+              ff_disp_sel_ch3        => "00",
+              ff_correct_disp_ch3    => "00",
+              ffc_rrst_ch3           => '0',
+              ffc_lane_tx_rst_ch3    => ffc_lane_tx_rst,
+              ffc_lane_rx_rst_ch3    => ffc_lane_rx_rst,
+              ffc_txpwdnb_ch3        => '1',
+              ffc_rxpwdnb_ch3        => '1',
+              ffc_macro_rst          => '0',
+              ffc_quad_rst           => ffc_quad_rst,
+              ffc_trst               => '0',
+              hdoutp3                => sd_txd_p_out,
+              hdoutn3                => sd_txd_n_out,
+              ff_rxdata_ch3          => rx_data, --comb_rx_data,
+              ff_rx_k_cntrl_ch3      => rx_k, --comb_rx_k,
+              ff_rxfullclk_ch3       => open,
+              ff_rxhalfclk_ch3       => ff_rxhalfclk,
+              ff_disp_err_ch3        => open,
+              ff_cv_ch3              => link_error(7 downto 6),
+              ffs_rlos_lo_ch3        => link_error(8),
+              ffs_ls_sync_status_ch3 => link_ok(0),
+              ffs_cc_underrun_ch3    => link_error(0),
+              ffs_cc_overrun_ch3     => link_error(1),
+              ffs_txfbfifo_error_ch3 => link_error(2),
+              ffs_rxfbfifo_error_ch3 => link_error(3),
+              ffs_rlol_ch3           => link_error(4),
+              oob_out_ch3            => open,
+              ff_txfullclk           => open,
+              ff_txhalfclk           => ff_txhalfclk,
+              refck2core             => refck2core,
+              ffs_plol               => link_error(5)
+            );
+  end generate;
+
+
+-------------------------------------------------------------------------
+-- RX Fifo & Data output
+-------------------------------------------------------------------------
+THE_FIFO_SFP_TO_FPGA: trb_net_fifo_16bit_bram_dualport
+generic map(
+  USE_STATUS_FLAGS => c_NO
+       )
+port map( read_clock_in    => clock,
+      write_clock_in  => ff_rxhalfclk,
+      read_enable_in  => fifo_rx_rd_en,
+      write_enable_in  => fifo_rx_wr_en,
+      fifo_gsr_in    => fifo_rx_reset,
+      write_data_in    => fifo_rx_din,
+      read_data_out    => fifo_rx_dout,
+      full_out      => fifo_rx_full,
+      empty_out      => fifo_rx_empty
+    );
+
+fifo_rx_reset <= RESET;
+fifo_rx_rd_en <= '1';
+
+-- Received bytes need to be swapped if the SerDes is "off by one" in its internal 8bit path
+THE_BYTE_SWAP_PROC: process( ff_rxhalfclk )
+begin
+  if( rising_edge(ff_rxhalfclk) ) then
+    last_rx <= rx_k(1) & rx_data(15 downto 8);
+    if( swap_bytes = '0' ) then
+      fifo_rx_din   <= rx_k(1) & rx_k(0) & rx_data(15 downto 8) & rx_data(7 downto 0);
+      fifo_rx_wr_en <= not rx_k(0) and rx_allow and link_ok(0);
+    else
+      fifo_rx_din   <= rx_k(0) & last_rx(8) & rx_data(7 downto 0) & last_rx(7 downto 0);
+      fifo_rx_wr_en <= not last_rx(8) and rx_allow and link_ok(0);
+    end if;
+  end if;
+end process THE_BYTE_SWAP_PROC;
+
+buf_med_data_out          <= fifo_rx_dout(15 downto 0);
+buf_med_dataready_out     <= not fifo_rx_dout(17) and not fifo_rx_dout(16) and not last_fifo_rx_empty and rx_allow_q;
+buf_med_packet_num_out    <= rx_counter;
+med_read_out              <= tx_allow_q;
+
+THE_SYNC_PROC: process( clock )
+begin
+  if( rising_edge(clock) ) then
+    if RESET = '1' then
+      med_dataready_out <= '0';
+    else
+      med_dataready_out     <= buf_med_dataready_out;
+      med_data_out          <= buf_med_data_out;
+      med_packet_num_out    <= buf_med_packet_num_out;
+    end if;
+  end if;
+end process THE_SYNC_PROC;
+
+--rx packet counter
+---------------------
+THE_RX_PACKETS_PROC: process( clock )
+begin
+  if( rising_edge(clock) ) then
+    last_fifo_rx_empty <= fifo_rx_empty;
+    if RESET = '1' or rx_allow_q = '0' then
+      rx_counter <= c_H0;
+    else
+      if( buf_med_dataready_out = '1' ) then
+        if( rx_counter = c_max_word_number ) then
+          rx_counter <= (others => '0');
+        else
+          rx_counter <= rx_counter + 1;
+        end if;
+      end if;
+    end if;
+  end if;
+end process;
+
+--TX Fifo & Data output to Serdes
+---------------------
+THE_FIFO_FPGA_TO_SFP: trb_net_fifo_16bit_bram_dualport
+generic map(
+  USE_STATUS_FLAGS => c_NO
+       )
+port map( read_clock_in    => ff_txhalfclk,
+      write_clock_in  => clock,
+      read_enable_in  => fifo_tx_rd_en,
+      write_enable_in  => fifo_tx_wr_en,
+      fifo_gsr_in    => fifo_tx_reset,
+      write_data_in    => fifo_tx_din,
+      read_data_out    => fifo_tx_dout,
+      full_out      => fifo_tx_full,
+      empty_out      => fifo_tx_empty
+    );
+
+fifo_tx_reset <= reset;
+fifo_tx_din   <= med_packet_num_in(2) & med_packet_num_in(0)& med_data_in;
+fifo_tx_wr_en <= med_dataready_in and tx_allow_q;
+fifo_tx_rd_en <= tx_allow;
+
+
+THE_SERDES_INPUT_PROC: process( ff_txhalfclk )
+begin
+  if( rising_edge(ff_txhalfclk) ) then
+  last_fifo_tx_empty <= fifo_tx_empty;
+    if( (last_fifo_tx_empty = '1') or (tx_allow = '0') ) then
+      tx_data <= x"c5bc";
+      tx_k <= "01";
+--    elsif send_resync = '1' then
+--      tx_data <= x"7F7F";
+--      tx_k <= "00";
+    else
+      tx_data <= fifo_tx_dout(15 downto 0);
+      tx_k <= "00";
+    end if;
+  end if;
+end process THE_SERDES_INPUT_PROC;
+
+--
+
+
+--Generate LED signals
+----------------------
+process(clock)
+  begin
+    if rising_edge(clock) then
+      led_counter <= led_counter + 1;
+
+      if buf_med_dataready_out = '1' then
+        rx_led <= '1';
+      elsif led_counter = 0 then
+        rx_led <= '0';
+      end if;
+
+      if tx_k(0) = '0' then -- tx_k clock domain crossing!
+        tx_led <= '1';
+      elsif led_counter = 0 then
+        tx_led <= '0';
+      end if;
+
+    end if;
+  end process;
+
+stat_op(15 downto 12) <= buf_stat_op(15 downto 12);
+stat_op(11)           <= tx_led; --tx led
+stat_op(10)           <= rx_led; --rx led
+stat_op(9 downto 0)   <= buf_stat_op(9 downto 0);
+
+-- Debug output
+stat_debug(3 downto 0)   <= buf_stat_debug(3 downto 0); -- state_bits
+stat_debug(4)            <= buf_stat_debug(4); -- alignme
+stat_debug(5)            <= sfp_prsnt_n;
+stat_debug(6)            <= tx_k(0);
+stat_debug(7)            <= tx_k(1);
+stat_debug(8)            <= rx_k_q(0);
+stat_debug(9)            <= rx_k_q(1);
+--stat_debug(9 downto 7)   <= (others => '0');
+stat_debug(18 downto 10) <= link_error;
+stat_debug(19)           <= '0';
+stat_debug(20)           <= link_ok(0);
+stat_debug(38 downto 21) <= fifo_rx_din;
+stat_debug(39)           <= swap_bytes;
+stat_debug(40)           <= buf_stat_debug(7); -- sfp_missing_in
+stat_debug(41)           <= buf_stat_debug(8); -- sfp_los_in
+stat_debug(42)           <= buf_stat_debug(6); -- resync
+stat_debug(59 downto 43) <= (others => '0');
+stat_debug(63 downto 60) <= link_error(3 downto 0);
+
+end architecture;
\ No newline at end of file