diff --git a/libraries/io/tr_xaui/src/vhdl/mms_tr_xaui.vhd b/libraries/io/tr_xaui/src/vhdl/mms_tr_xaui.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..297719de10de77b8849197fa9dc79eb7c1ea690e
--- /dev/null
+++ b/libraries/io/tr_xaui/src/vhdl/mms_tr_xaui.vhd
@@ -0,0 +1,296 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib, mdio_lib, diagnostics_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE mdio_lib.mdio_pkg.ALL;
+USE mdio_lib.mdio_vitesse_vsc8486_pkg.ALL;
+
+ENTITY mms_tr_xaui IS
+  GENERIC(
+    g_sim             : BOOLEAN := FALSE;
+    g_nof_xaui        : NATURAL := 1; -- Up to 3 (hard XAUI only) supported
+    g_mdio            : BOOLEAN := FALSE
+--    g_mdio_mm_ctrl    : BOOLEAN := FALSE -- FALSE uses mdio_ctlr to auto execute the initialization 
+--                                         -- sequence for the Vitesse chips. TRUE enables MM control.
+    );                      
+  PORT (   
+    -- Transceiver PLL reference clock   
+    tr_clk                  : IN  STD_LOGIC;
+
+    -- Calibration & reconfig clock
+    cal_rec_clk             : IN  STD_LOGIC;
+ 
+    -- MM clock for register of optional MDIO master
+    mm_clk                  : IN  STD_LOGIC := '0';
+    mm_rst                  : IN  STD_LOGIC := '0';
+
+    -- Streaming RX interfaces
+    rx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    rx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    rx_sosi_arr             : OUT t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+    rx_siso_arr             : IN  t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+
+    -- Streaming TX interfaces
+    tx_clk                  : IN  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    tx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    tx_sosi_arr             : IN  t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+    tx_siso_arr             : OUT t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+   
+    --Serial I/O
+    xaui_rx                 : IN  t_xaui_arr(g_nof_xaui-1 DOWNTO 0);
+    xaui_tx                 : OUT t_xaui_arr(g_nof_xaui-1 DOWNTO 0);   
+      
+    -- MDIO master = mm slave
+    mdio_mosi_arr           : IN  t_mem_mosi_arr(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>c_mem_mosi_rst);
+    mdio_miso_arr           : OUT t_mem_miso_arr(g_nof_xaui-1 DOWNTO 0);
+
+    -- MDIO External clock and serial data.
+    mdio_rst                : OUT STD_LOGIC;
+    mdio_mdc                : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);       
+    mdio_mdat_in            : IN  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>'0');
+    mdio_mdat_oen           : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+    diagnostics_mosi        : IN  t_mem_mosi := c_mem_mosi_rst;
+    diagnostics_miso        : OUT t_mem_miso := c_mem_miso_rst;
+
+    xaui_mosi               : IN  t_mem_mosi := c_mem_mosi_rst;
+    xaui_miso               : OUT t_mem_miso := c_mem_miso_rst
+    );
+END mms_tr_xaui;
+
+
+ARCHITECTURE wrap OF mms_tr_xaui IS  
+
+  CONSTANT c_nof_select    : NATURAL := 2;
+  CONSTANT c_nof_select_w  : NATURAL := ceil_log2(c_nof_select);
+  CONSTANT c_sel_user      : NATURAL := 0;
+  CONSTANT c_sel_diag      : NATURAL := 1;
+ 
+  TYPE t_select_sosi_2arr IS ARRAY (INTEGER RANGE <>) OF t_dp_sosi_arr(c_nof_select-1 DOWNTO 0);
+  TYPE t_select_siso_2arr IS ARRAY (INTEGER RANGE <>) OF t_dp_siso_arr(c_nof_select-1 DOWNTO 0);
+
+  TYPE t_select_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(c_nof_select_w-1 DOWNTO 0);
+
+  SIGNAL i_tx_rst             :  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL i_rx_clk             :  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL i_rx_rst             :  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL diagnostics_rx_sosi_arr  : t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0); 
+  SIGNAL diagnostics_rx_siso_arr  : t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL diagnostics_tx_sosi_arr  : t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL diagnostics_tx_siso_arr  : t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL diagnostics_tx_en_arr    : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL diagnostics_rx_en_arr    : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL mux_in_siso_2arr         : t_select_siso_2arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mux_in_sosi_2arr         : t_select_sosi_2arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL mux_out_sosi_arr         : t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mux_out_siso_arr         : t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL demux_in_siso_arr        : t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL demux_in_sosi_arr        : t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL demux_out_sosi_2arr      : t_select_sosi_2arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL demux_out_siso_2arr      : t_select_siso_2arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL mux_select_arr           : t_select_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL nxt_mux_select_arr       : t_select_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL demux_select_arr         : t_select_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL nxt_demux_select_arr     : t_select_arr(g_nof_xaui-1 DOWNTO 0);
+
+BEGIN
+
+  rx_rst <= i_rx_rst;
+  rx_clk <= i_rx_clk;
+  tx_rst <= i_tx_rst;
+
+  u_tr_xaui: ENTITY work.tr_xaui 
+  GENERIC MAP (
+    g_sim              => g_sim,
+    g_mdio             => g_mdio,
+    g_nof_xaui         => g_nof_xaui
+  )
+  PORT MAP (     
+    tr_clk             => tr_clk,
+
+    mm_rst             => mm_rst,  
+    mm_clk             => mm_clk,
+                        
+    --Serial data
+    xaui_tx            => xaui_tx, 
+    xaui_rx            => xaui_rx,  
+
+    mdio_mosi_arr      => mdio_mosi_arr,
+    mdio_miso_arr      => mdio_miso_arr,
+
+    mdio_rst           => mdio_rst,
+    mdio_mdc           => mdio_mdc,
+    mdio_mdat_in       => mdio_mdat_in,
+    mdio_mdat_oen      => mdio_mdat_oen, 
+ 
+    --Parallel data
+    rx_rst             => i_rx_rst,   
+    rx_clk             => i_rx_clk,  
+    rx_sosi_arr        => demux_in_sosi_arr,   
+    rx_siso_arr        => demux_in_siso_arr,
+    
+    tx_rst             => i_tx_rst,    
+    tx_clk             => tx_clk,   
+    tx_sosi_arr        => mux_out_sosi_arr,   
+    tx_siso_arr        => mux_out_siso_arr,
+
+    cal_rec_clk        => cal_rec_clk,
+
+    xaui_mosi          => xaui_mosi,
+    xaui_miso          => xaui_miso
+    );
+
+  u_mms_diagnostics: ENTITY diagnostics_lib.mms_diagnostics
+  GENERIC MAP(
+    g_data_w       => c_xgmii_data_w,
+    g_nof_streams  => g_nof_xaui,
+    g_separate_clk => TRUE
+  )                      
+  PORT MAP (       
+    mm_rst          => mm_rst,  
+    mm_clk          => mm_clk,
+
+    src_rst         => i_tx_rst,
+    src_clk         => tx_clk,
+
+    snk_rst         => i_rx_rst,
+    snk_clk         => i_rx_clk,
+    
+    mm_mosi         => diagnostics_mosi, 
+    mm_miso         => diagnostics_miso,
+
+    src_out_arr     => diagnostics_tx_sosi_arr,
+    src_in_arr      => diagnostics_tx_siso_arr,
+
+    snk_out_arr     => diagnostics_rx_siso_arr,
+    snk_in_arr      => diagnostics_rx_sosi_arr,
+
+    src_en_out      => diagnostics_tx_en_arr,
+    snk_en_out      => diagnostics_rx_en_arr
+  );
+
+   gen_select : FOR i IN 0 TO g_nof_xaui-1 GENERATE
+
+    -- 0 = user data, 
+    tx_siso_arr(i)                     <= mux_in_siso_2arr(i)(c_sel_user);
+    mux_in_sosi_2arr(i)(c_sel_user)    <= tx_sosi_arr(i);
+  
+    demux_out_siso_2arr(i)(c_sel_user) <= rx_siso_arr(i);
+    rx_sosi_arr(i)                     <= demux_out_sosi_2arr(i)(c_sel_user);
+  
+    -- 1 = internal diagnostics data
+    diagnostics_tx_siso_arr(i)         <= mux_in_siso_2arr(i)(c_sel_diag);
+    mux_in_sosi_2arr(i)(c_sel_diag)    <= diagnostics_tx_sosi_arr(i);
+  
+    demux_out_siso_2arr(i)(c_sel_diag) <= diagnostics_rx_siso_arr(i);
+    diagnostics_rx_sosi_arr(i)         <= demux_out_sosi_2arr(i)(c_sel_diag);
+
+    -- If user enables internal diagnostics source, the dp_mux automatically forwards that data to the corresponding transmitter
+    nxt_mux_select_arr(i) <= slv(diagnostics_tx_en_arr(i));
+
+    -- If user enables internal diagnostics sink, the dp_demux is automatically set to forward the corresponding receiver data
+    nxt_demux_select_arr(i) <= slv(diagnostics_rx_en_arr(i));
+
+    u_dp_mux : ENTITY dp_lib.dp_mux
+    GENERIC MAP (
+      -- Mux
+      g_sel_ctrl_invert   => TRUE, -- We're using DOWNTO ranges in out streaming arrays, so we must invert the selection input
+      g_mode              => 2,  
+      g_nof_input         => c_nof_select, 
+      g_append_channel_lo => FALSE, 
+      -- Input FIFO
+      g_use_fifo          => FALSE,
+      g_fifo_size         => array_init(1024, c_nof_select),
+      g_fifo_fill         => array_init(   0, c_nof_select)
+    )
+    PORT MAP (
+      rst         => i_tx_rst(i),
+      clk         => tx_clk(i),
+  
+      sel_ctrl    => TO_UINT(mux_select_arr(i)),
+
+      -- ST sinks
+      snk_out_arr => mux_in_siso_2arr(i), 
+      snk_in_arr  => mux_in_sosi_2arr(i),
+      -- ST source
+      src_in      => mux_out_siso_arr(i),  
+      src_out     => mux_out_sosi_arr(i)
+    );  
+
+    p_tx_clk : PROCESS(i_tx_rst, tx_clk)
+    BEGIN
+      IF i_tx_rst(i)='1' THEN
+        mux_select_arr(i) <= (OTHERS=>'0');
+      ELSIF rising_edge(tx_clk(i)) THEN
+        mux_select_arr(i) <= nxt_mux_select_arr(i);
+      END IF;
+    END PROCESS;
+
+    u_dp_demux : ENTITY dp_lib.dp_demux
+    GENERIC MAP (
+      g_sel_ctrl_invert   => TRUE, -- We're using DOWNTO ranges in out streaming arrays, so we must invert the selection input
+      g_mode              => 2,  
+      g_nof_output        => c_nof_select,
+      g_remove_channel_lo => FALSE, 
+      g_combined          => FALSE 
+    )
+    PORT MAP (
+      rst         => i_rx_rst(i),
+      clk         => i_rx_clk(i),
+  
+      sel_ctrl    => TO_UINT(demux_select_arr(i)), 
+  
+      -- ST sinks
+      snk_out     => demux_in_siso_arr(i),    
+      snk_in      => demux_in_sosi_arr(i),
+      -- ST source
+      src_in_arr  => demux_out_siso_2arr(i), 
+      src_out_arr => demux_out_sosi_2arr(i)
+    );
+  
+    p_rx_clk : PROCESS(i_rx_rst, i_rx_clk)
+    BEGIN
+      IF i_rx_rst(i)='1' THEN
+        demux_select_arr(i) <= (OTHERS=>'0');
+      ELSIF rising_edge(i_rx_clk(i)) THEN
+        demux_select_arr(i) <= nxt_demux_select_arr(i);
+      END IF;
+    END PROCESS;
+
+  END GENERATE;
+      
+END wrap;
+
diff --git a/libraries/io/tr_xaui/src/vhdl/tr_xaui.vhd b/libraries/io/tr_xaui/src/vhdl/tr_xaui.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..fb72fdb53f276ae4dbe172a168d8394e15572f6c
--- /dev/null
+++ b/libraries/io/tr_xaui/src/vhdl/tr_xaui.vhd
@@ -0,0 +1,455 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib, mdio_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE mdio_lib.mdio_pkg.ALL;
+USE mdio_lib.mdio_vitesse_vsc8486_pkg.ALL;
+
+ENTITY tr_xaui IS
+  GENERIC (
+    g_sim                   : BOOLEAN := FALSE;
+    g_sim_level             : NATURAL := 0;     -- 0 = use IP; 1 = use fast serdes model
+    g_use_xgmii             : BOOLEAN := FALSE; -- Don't use streaming I/O but XGMII (e.g. conenct to 10GbE MAC)
+    g_nof_xaui              : NATURAL := 1;     -- Up to 3 (hard XAUI only) supported
+    g_mdio                  : BOOLEAN := FALSE;
+    g_mdio_epcs_dis         : BOOLEAN := FALSE -- TRUE disables EPCS on init; e.g. to target a 10GbE card in PC that does not support it 
+    --g_mdio_mm_ctrl          : BOOLEAN := FALSE  -- FALSE uses mdio_ctlr to auto execute the initialization sequence for the Vitesse chips. TRUE enables MM control.
+  );
+  PORT (   
+    -- Transceiver PLL reference clock   
+    tr_clk                  : IN  STD_LOGIC;
+
+    -- Calibration & reconfig clock
+    cal_rec_clk             : IN  STD_LOGIC;
+ 
+    -- MM clock for register of optional MDIO master
+    mm_clk                  : IN  STD_LOGIC := '0';
+    mm_rst                  : IN  STD_LOGIC := '0';
+
+    -- Streaming RX interfaces
+    rx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    rx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    rx_sosi_arr             : OUT t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+    rx_siso_arr             : IN  t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>c_dp_siso_rst);
+
+    -- Streaming TX interfaces
+    tx_clk                  : IN  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    tx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    tx_sosi_arr             : IN  t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>c_dp_sosi_rst);
+    tx_siso_arr             : OUT t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+
+    -- Direct XGMII interface
+    xgmii_tx_dc_arr         : IN  t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0'));
+    xgmii_rx_dc_arr         : OUT t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0);
+     
+    --Serial I/O
+    xaui_rx                 : IN  t_xaui_arr(g_nof_xaui-1 DOWNTO 0);
+    xaui_tx                 : OUT t_xaui_arr(g_nof_xaui-1 DOWNTO 0);   
+
+    -- XAUI PHY IP MM control/status
+    xaui_mosi               : IN  t_mem_mosi := c_mem_mosi_rst;
+    xaui_miso               : OUT t_mem_miso; 
+      
+    -- MDIO master = mm slave
+    mdio_mosi_arr           : IN  t_mem_mosi_arr(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>c_mem_mosi_rst);
+    mdio_miso_arr           : OUT t_mem_miso_arr(g_nof_xaui-1 DOWNTO 0);
+
+    -- MDIO External clock and serial data.
+    mdio_rst                : OUT STD_LOGIC;
+    mdio_mdc                : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);       
+    mdio_mdat_in            : IN  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0) := (OTHERS=>'0');
+    mdio_mdat_oen           : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0)
+  );
+END tr_xaui;
+
+
+ARCHITECTURE str OF tr_xaui IS  
+
+  SIGNAL crc_rx_ready              : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0); --crc = synchronous to Cal_Rec_Clk
+  SIGNAL crc_tx_ready              : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL rxc_rx_ready              : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL txc_tx_ready              : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL i_rx_rst                  : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL i_tx_rst                  : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL trc_rst                   : STD_LOGIC;
+  SIGNAL i_rx_clk                  : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  --XGMII data and control combined:
+  SIGNAL xgmii_tx_dc               : t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL xgmii_rx_dc               : t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0);
+
+  --XGMII control bits (one for each XGMII lane):
+  SIGNAL xgmii_tx_c                : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL xgmii_rx_c                : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0);
+  
+  --XGMII data
+  SIGNAL xgmii_tx_d                : t_xgmii_d_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL xgmii_rx_d                : t_xgmii_d_arr(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL a_rx_channelaligned       : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+--  SIGNAL rxc_rx_channelaligned     : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL txc_rx_channelaligned_dly : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0); 
+
+  -- MDIO (optional) signals
+  SIGNAL mdio_hdr                  : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mdio_tx_dat               : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mdio_rx_dat               : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mdio_en_evt               : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mdio_done                 : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL mdio_done_ack_evt         : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL reg_mdio_hdr              : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL reg_mdio_tx_dat           : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL reg_mdio_rx_dat           : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL reg_mdio_en_evt           : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL reg_mdio_done             : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL reg_mdio_done_ack_evt     : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL ctlr_mdio_rst             : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_hdr             : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_tx_dat          : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_rx_dat          : t_slv_16_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_en_evt          : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_done            : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL ctlr_mdio_done_ack_evt    : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL ctlr_exec_complete        : STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+  SIGNAL tx_framer_siso_arr        : t_dp_siso_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL tx_framer_sosi_arr        : t_dp_sosi_arr(g_nof_xaui-1 DOWNTO 0);
+
+BEGIN
+
+  -----------------------------------------------------------------------------
+  -- XAUI PHY
+  -----------------------------------------------------------------------------
+  gen_phy: IF g_sim = FALSE OR g_sim_level = 0 GENERATE
+    -- Altera's IP
+    u_phy_xaui : ENTITY work.phy_xaui
+    GENERIC MAP (
+      g_nof_xaui => g_nof_xaui 
+    )
+    PORT MAP (
+      tr_clk               => tr_clk,
+      trc_rst              => trc_rst,
+ 
+      mm_rst               => mm_rst,  
+      mm_clk               => mm_clk,
+ 
+      cal_rec_clk          => cal_rec_clk,
+    
+      tx_clk               => tx_clk,
+      rx_clk               => i_rx_clk,
+     
+      crc_rx_ready         => crc_rx_ready,
+      crc_tx_ready         => crc_tx_ready,
+  
+      a_rx_channelaligned  => a_rx_channelaligned,
+  
+      xgmii_tx_dc          => xgmii_tx_dc,
+      xgmii_rx_dc          => xgmii_rx_dc,
+  
+      xaui_rx              => xaui_rx,
+      xaui_tx              => xaui_tx,
+
+      xaui_mosi            => xaui_mosi,
+      xaui_miso            => xaui_miso
+    );
+  END GENERATE;  
+
+  gen_sim: IF g_sim = TRUE AND g_sim_level = 1 GENERATE
+    -- Behavioural serdes model (fast)
+    u_sim_xaui : ENTITY work.sim_xaui
+    GENERIC MAP (
+      g_nof_xaui => g_nof_xaui 
+    )
+    PORT MAP (
+      tr_clk               => tr_clk,
+      trc_rst              => trc_rst,
+  
+      cal_rec_clk          => cal_rec_clk,
+    
+      tx_clk               => tx_clk,
+      rx_clk               => i_rx_clk,
+     
+      crc_rx_ready         => crc_rx_ready,
+      crc_tx_ready         => crc_tx_ready,
+  
+      a_rx_channelaligned  => a_rx_channelaligned,
+  
+      xgmii_tx_dc          => xgmii_tx_dc,
+      xgmii_rx_dc          => xgmii_rx_dc,
+  
+      xaui_rx              => xaui_rx,
+      xaui_tx              => xaui_tx
+    );
+  END GENERATE;  
+
+  -----------------------------------------------------------------------------
+  -- Clock and reset generation
+  -----------------------------------------------------------------------------
+  u_areset_trc_rst : ENTITY common_lib.common_areset
+  GENERIC MAP(
+    g_rst_level => '1',
+    g_delay_len => 4
+  )
+  PORT MAP(
+    clk     => tr_clk,
+    in_rst  => '0',
+    out_rst => trc_rst
+  );    
+ 
+  gen_nof_xaui : FOR i IN g_nof_xaui-1 DOWNTO 0 GENERATE
+
+    tx_rst(i) <= i_tx_rst(i);
+
+    rx_clk(i) <= i_rx_clk(i);
+    rx_rst(i) <= i_rx_rst(i);
+
+    i_rx_rst(i) <= NOT rxc_rx_ready(i);
+    i_tx_rst(i) <= NOT txc_tx_ready(i); 
+
+    u_async_rxc_rx_ready: ENTITY common_lib.common_async
+    GENERIC MAP(
+      g_rst_level => '0'
+    )
+    PORT MAP(
+      clk  => i_rx_clk(i),
+      din  => crc_rx_ready(i),
+      dout => rxc_rx_ready(i)
+    );
+
+    u_async_txc_tx_ready: ENTITY common_lib.common_async
+    GENERIC MAP(
+      g_rst_level => '0'
+    )
+    PORT MAP(
+      clk  => tx_clk(i),
+      din  => crc_tx_ready(i),
+      dout => txc_tx_ready(i)
+    );
+
+    -----------------------------------------------------------------------------
+    -- SOSI <-> XGMII
+    -----------------------------------------------------------------------------
+    gen_sosi_io: IF g_use_xgmii=FALSE GENERATE
+ 
+      xgmii_tx_dc(i) <= xgmii_dc(xgmii_tx_d(i), xgmii_tx_c(i));
+  
+      xgmii_rx_d(i) <= xgmii_d(xgmii_rx_dc(i));
+      xgmii_rx_c(i) <= xgmii_c(xgmii_rx_dc(i));
+  
+      tx_siso_arr(i).ready <= '0' WHEN txc_rx_channelaligned_dly(i) = '0' ELSE tx_framer_siso_arr(i).ready;
+      tx_siso_arr(i).xon   <= txc_rx_channelaligned_dly(i);
+  
+      tx_framer_sosi_arr(i) <= tx_sosi_arr(i);
+  
+      u_tx_framer : ENTITY work.tr_xaui_framer
+      GENERIC MAP (
+        g_dat_len => sel_a_b(g_sim, 100, 100000),
+        g_gap_len => 10
+       )
+      PORT MAP (
+        tx_rst     => i_tx_rst(i),
+        tx_clk     => tx_clk(i),
+  
+        snk_out    => tx_framer_siso_arr(i),
+        snk_in     => tx_framer_sosi_arr(i),
+  
+        xgmii_tx_d => xgmii_tx_d(i),
+        xgmii_tx_c => xgmii_tx_c(i)    
+      );
+  
+      u_rx_deframer : ENTITY work.tr_xaui_deframer
+      PORT MAP (
+        rx_rst     => i_rx_rst(i),
+        rx_clk     => i_rx_clk(i),
+  
+        xgmii_rx_d => xgmii_rx_d(i),
+        xgmii_rx_c => xgmii_rx_c(i),
+  
+        src_out    => rx_sosi_arr(i)
+      );
+
+      u_tr_xaui_align_dly: ENTITY work.tr_xaui_align_dly
+      GENERIC MAP(
+        g_sim => g_sim
+      )
+      PORT MAP(
+        tx_rst                    => i_tx_rst(i),
+        tx_clk                    => tx_clk(i),
+  
+        a_rx_channelaligned       => a_rx_channelaligned(i),
+        txc_rx_channelaligned_dly => txc_rx_channelaligned_dly(i)
+      );
+
+    END GENERATE;
+
+    -----------------------------------------------------------------------------
+    -- Direct XGMII
+    -----------------------------------------------------------------------------
+    gen_xgmii_io: IF g_use_xgmii=TRUE GENERATE
+      xgmii_tx_dc(i)     <= xgmii_tx_dc_arr(i);
+      xgmii_rx_dc_arr(i) <= xgmii_rx_dc(i);
+    END GENERATE;
+
+    gen_mdio: IF g_mdio = TRUE GENERATE
+
+      -- UniBoard FN resets 4 Vitesse chips using one output.
+      mdio_rst <= ctlr_mdio_rst(0);
+
+      -----------------------------------------------------------------------------
+      -- MDIO: the PHY core itself
+      -----------------------------------------------------------------------------
+      u_mdio_phy : ENTITY mdio_lib.mdio_phy
+      GENERIC MAP(
+        g_add_mdc_cycle => TRUE
+      )
+      PORT MAP (
+        gs_sim            => g_sim,
+        
+        rst               => trc_rst,
+        clk               => tr_clk,
+      
+        mdio_en_evt       => mdio_en_evt(i),
+        mdio_done         => mdio_done(i),
+        mdio_done_ack_evt => mdio_done_ack_evt(i),
+      
+        hdr               => mdio_hdr(i),
+        tx_dat            => mdio_tx_dat(i),
+        rx_dat            => mdio_rx_dat(i),
+      
+        -- External clock and serial data
+        mdc               => mdio_mdc(i),
+        mdat_in           => mdio_mdat_in(i),
+        mdat_oen          => mdio_mdat_oen(i)
+      );
+
+      -----------------------------------------------------------------------------
+      -- MDIO: MM port
+      -----------------------------------------------------------------------------
+      u_mdio_phy_reg : ENTITY mdio_lib.mdio_phy_reg
+      PORT MAP ( 
+        mm_rst            => mm_rst,
+        mm_clk            => mm_clk,
+    
+        mdio_rst          => trc_rst,
+        mdio_clk          => tr_clk,
+    
+        sla_in            => mdio_mosi_arr(i),
+        sla_out           => mdio_miso_arr(i),
+    
+        mdio_en_evt       => reg_mdio_en_evt(i),
+        mdio_done_ack_evt => reg_mdio_done_ack_evt(i),
+        mdio_done         => reg_mdio_done(i),
+    
+        mdio_hdr          => reg_mdio_hdr(i),
+        mdio_tx_dat       => reg_mdio_tx_dat(i),
+        mdio_rx_dat       => reg_mdio_rx_dat(i)
+      );
+
+      -----------------------------------------------------------------------------
+      -- MDIO controller auto-executes MDIO sequence on startup
+      -----------------------------------------------------------------------------
+      gen_mdio_epcs : IF g_mdio_epcs_dis = FALSE GENERATE
+        u_mdio_ctlr_epcs : ENTITY mdio_lib.mdio_ctlr
+        GENERIC MAP (
+           g_mdio_prtad           => c_mdio_vsc8486_prtad,
+           g_mdio_cmd_arr         => c_mdio_vsc8486_init_cmd_arr,
+           g_mdio_rst_level       => '0', 
+           g_mdio_rst_cycles      => 250000,           
+           g_mdio_post_rst_cycles => 250000
+          ) 
+        PORT MAP (
+          rst               => trc_rst,
+          clk               => tr_clk,
+
+          mdio_rst          => ctlr_mdio_rst(i),
+          mdio_en_evt       => ctlr_mdio_en_evt(i),
+          mdio_done         => ctlr_mdio_done(i),
+      
+          mdio_done_ack_evt => ctlr_mdio_done_ack_evt(i),
+      
+          hdr               => ctlr_mdio_hdr(i),
+          tx_dat            => ctlr_mdio_tx_dat(i),
+
+          exec_complete     => ctlr_exec_complete(i)
+        );
+      END GENERATE;
+
+      -----------------------------------------------------------------------------
+      -- MDIO controller auto-executes MDIO sequence on startup
+      -----------------------------------------------------------------------------
+      gen_mdio_no_epcs : IF g_mdio_epcs_dis = TRUE GENERATE
+        u_mdio_ctlr_no_epcs : ENTITY mdio_lib.mdio_ctlr
+        GENERIC MAP (
+           g_mdio_prtad           => c_mdio_vsc8486_prtad,
+           g_mdio_cmd_arr         => c_mdio_vsc8486_init_epcs_dis_cmd_arr,
+           g_mdio_rst_level       => '0', 
+           g_mdio_rst_cycles      => 250000,
+           g_mdio_post_rst_cycles => 250000
+          ) 
+        PORT MAP (
+          rst               => trc_rst,
+          clk               => tr_clk,
+
+          mdio_rst          => ctlr_mdio_rst(i),      
+          mdio_en_evt       => ctlr_mdio_en_evt(i),
+          mdio_done         => ctlr_mdio_done(i),
+      
+          mdio_done_ack_evt => ctlr_mdio_done_ack_evt(i),
+      
+          hdr               => ctlr_mdio_hdr(i),
+          tx_dat            => ctlr_mdio_tx_dat(i),
+
+          exec_complete     => ctlr_exec_complete(i)
+        );
+      END GENERATE;
+
+      -----------------------------------------------------------------------------
+      -- MDIO: Connect the mdio_ctlr to the mdio_phy initially, when it's done
+      --       connect the MM controller to allow user control/monitoring.
+      -----------------------------------------------------------------------------
+      mdio_en_evt(i)       <= ctlr_mdio_en_evt(i)       WHEN ctlr_exec_complete(i)='0' ELSE reg_mdio_en_evt(i); 
+      mdio_done_ack_evt(i) <= ctlr_mdio_done_ack_evt(i) WHEN ctlr_exec_complete(i)='0' ELSE reg_mdio_done_ack_evt(i);
+      mdio_hdr(i)          <= ctlr_mdio_hdr(i)          WHEN ctlr_exec_complete(i)='0' ELSE reg_mdio_hdr(i);
+      mdio_tx_dat(i)       <= ctlr_mdio_tx_dat(i)       WHEN ctlr_exec_complete(i)='0' ELSE reg_mdio_tx_dat(i);       
+    
+      ctlr_mdio_done(i)    <= mdio_done(i)   WHEN ctlr_exec_complete(i)='0' ELSE '0';
+      reg_mdio_done(i)     <= mdio_done(i)   WHEN ctlr_exec_complete(i)='1' ELSE '0';
+      reg_mdio_rx_dat(i)   <= mdio_rx_dat(i) WHEN ctlr_exec_complete(i)='1' ELSE (OTHERS=>'0');
+
+
+    END GENERATE; -- if g_mdio = True
+
+  END GENERATE; -- for i in 0..g_nof_xaui
+      
+END str;
+
diff --git a/libraries/io/tr_xaui/src/vhdl/tr_xaui_align_dly.vhd b/libraries/io/tr_xaui/src/vhdl/tr_xaui_align_dly.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..0a4a1578f66c3841c7369094e9c31cd4f6a89b53
--- /dev/null
+++ b/libraries/io/tr_xaui/src/vhdl/tr_xaui_align_dly.vhd
@@ -0,0 +1,122 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+
+ENTITY tr_xaui_align_dly IS    
+  GENERIC(
+    g_sim : BOOLEAN
+  );              
+  PORT (   
+    tx_clk                    : IN STD_LOGIC;
+    tx_rst                    : IN STD_LOGIC;
+
+    a_rx_channelaligned       : IN STD_LOGIC;
+    txc_rx_channelaligned_dly : OUT STD_LOGIC
+  
+  );
+END tr_xaui_align_dly;
+
+
+ARCHITECTURE rtl OF tr_xaui_align_dly IS  
+  
+  -- FSM to delay txc_rx_channelaligned (txc_rx_channelaligned_dly is connected to tx_siso.ready)
+  CONSTANT c_align_dly_cnt             : NATURAL := sel_a_b(g_sim, 50, 150000000); -- about 1 second on hw
+  CONSTANT c_align_dly_cnt_w           : NATURAL := ceil_log2(c_align_dly_cnt);
+
+  TYPE t_state_enum IS (s_init, s_aligned, s_aligned_dly);
+
+  SIGNAL state                         : t_state_enum;
+  SIGNAL nxt_state                     : t_state_enum; 
+
+  SIGNAL txc_rx_channelaligned         : STD_LOGIC;
+
+  SIGNAL txc_align_dly_cycle_cnt       : STD_LOGIC_VECTOR(c_align_dly_cnt_w-1 DOWNTO 0);
+  SIGNAL nxt_txc_align_dly_cycle_cnt   : STD_LOGIC_VECTOR(c_align_dly_cnt_w-1 DOWNTO 0);
+ 
+  SIGNAL i_txc_rx_channelaligned_dly   : STD_LOGIC;
+  SIGNAL nxt_txc_rx_channelaligned_dly : STD_LOGIC;
+
+BEGIN 
+
+  txc_rx_channelaligned_dly <= i_txc_rx_channelaligned_dly;
+
+  u_async_txc_rx_channelaligned: ENTITY common_lib.common_async
+  GENERIC MAP(
+    g_rst_level => '0'
+  )
+  PORT MAP(
+    rst  => tx_rst,
+    clk  => tx_clk,
+    din  => a_rx_channelaligned,
+    dout => txc_rx_channelaligned
+  );
+
+  -- Assert txc_rx_channelaligned: basically indicates whether or not the RX of the receiving
+  -- XAUI core (NOT this one) is assumed to be channelaligned.
+  -- We assume the RX connected to our TX will be channel aligned within txc_align_dly_cycle_cnt cycles
+  -- after 'our own' RX has asserted channelaligned. This is important because txc_tx_channelaligned_dly
+  -- connects directly to tx_siso.ready.
+  p_tx_clk : PROCESS(tx_rst, tx_clk)
+  BEGIN
+    IF tx_rst='1' THEN
+      state                     <= s_init;  
+      txc_align_dly_cycle_cnt   <= (OTHERS=>'0');
+      i_txc_rx_channelaligned_dly <= '0';
+    ELSIF rising_edge(tx_clk) THEN
+      state                     <= nxt_state;
+      txc_align_dly_cycle_cnt   <= nxt_txc_align_dly_cycle_cnt;
+      i_txc_rx_channelaligned_dly <= nxt_txc_rx_channelaligned_dly;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, txc_align_dly_cycle_cnt, txc_rx_channelaligned, i_txc_rx_channelaligned_dly)
+  BEGIN  
+    nxt_state                     <= state;  
+    nxt_txc_align_dly_cycle_cnt   <= txc_align_dly_cycle_cnt;
+    nxt_txc_rx_channelaligned_dly <= i_txc_rx_channelaligned_dly;
+  CASE state IS
+     
+    WHEN s_init => --Wait until our own RX is channel aligned      
+      IF txc_rx_channelaligned= '1' THEN
+        nxt_state <= s_aligned;
+      END IF;   
+    
+    WHEN s_aligned => -- We assume the connecting RX is aligned after this delay...
+      nxt_txc_align_dly_cycle_cnt <= INCR_UVEC(txc_align_dly_cycle_cnt, 1); 
+      IF txc_align_dly_cycle_cnt = TO_UVEC(c_align_dly_cnt, c_align_dly_cnt_w) THEN
+        nxt_txc_rx_channelaligned_dly <= '1';
+        nxt_state                     <= s_aligned_dly;
+      END IF;
+
+    WHEN s_aligned_dly => -- ... So now we can assume connected RX has aligned.
+      -- Do nothing.
+        
+    END CASE;
+  END PROCESS;
+
+
+END rtl;
+
diff --git a/libraries/io/tr_xaui/src/vhdl/tr_xaui_deframer.vhd b/libraries/io/tr_xaui/src/vhdl/tr_xaui_deframer.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9a2981a420d5ae990a246e27eebacbe119e0771c
--- /dev/null
+++ b/libraries/io/tr_xaui/src/vhdl/tr_xaui_deframer.vhd
@@ -0,0 +1,212 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+
+ENTITY tr_xaui_deframer IS
+  PORT (
+    rx_clk     : IN STD_LOGIC;
+    rx_rst     : IN STD_LOGIC;
+
+    xgmii_rx_d : IN STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+    xgmii_rx_c : IN STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+
+    src_out    : OUT t_dp_sosi
+  );
+END tr_xaui_deframer;
+
+ARCHITECTURE rtl OF tr_xaui_deframer IS
+
+  CONSTANT c_xgmii_c_start_lo : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0) := c_xgmii_c_start(c_xgmii_nof_lanes/2-1 DOWNTO 0); -- 0x1
+  CONSTANT c_xgmii_c_term_lo  : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0) := c_xgmii_c_term (c_xgmii_nof_lanes/2-1 DOWNTO 0); -- 0x8
+
+  -- We need to look at the data when we receive the c_xgmii_c_start_lo as control, as the control bits happen to be the same during lane alignment.
+  -- In that case, the incoming data word is 0x01000009C on both the LS and MS word, and we don't want to mistake that for data.
+  CONSTANT c_xgmii_d_start_lo  : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0) :=  c_xgmii_d_start(c_xgmii_data_w/2-1 DOWNTO 0); -- 0x000000FB
+
+  TYPE t_state_enum IS (s_init, s_gap, s_data, s_data_misaligned);
+
+  SIGNAL prev_state         : t_state_enum;
+  SIGNAL state              : t_state_enum;
+  SIGNAL nxt_state          : t_state_enum; 
+
+  -- XGMII RX data & control IN:
+  SIGNAL xgmii_rx_d_hi      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL xgmii_rx_d_lo      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  SIGNAL prev_xgmii_rx_d_hi : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  SIGNAL xgmii_rx_c_hi      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+  SIGNAL xgmii_rx_c_lo      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  -- RX data & valid OUT:
+  SIGNAL rx_data_hi         : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL rx_data_lo         : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL rx_data_val        : STD_LOGIC;
+
+  SIGNAL nxt_rx_data_hi     : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL nxt_rx_data_lo     : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL nxt_rx_data_val    : STD_LOGIC;
+
+BEGIN
+
+  src_out.data(c_xgmii_data_w-1 DOWNTO 0) <= rx_data_hi & rx_data_lo; 
+  src_out.valid                           <= rx_data_val;
+
+  xgmii_rx_d_hi <= xgmii_rx_d(c_xgmii_data_w  -1 DOWNTO c_xgmii_data_w/2);
+  xgmii_rx_d_lo <= xgmii_rx_d(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  xgmii_rx_c_hi <= xgmii_rx_c(c_xgmii_nof_lanes  -1 DOWNTO c_xgmii_nof_lanes/2);
+  xgmii_rx_c_lo <= xgmii_rx_c(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  -- FSM function if word boundary was 64b (it's not):
+  -- =================================================
+  -- xgmii_rx_d   I  I  S  D0 D1 D2 D3 T I I I S  D4  D5
+
+  -- nxt_rx_sosi: G  G  G  D0 D1 D2 D3 G G G G G  D4  D5 
+  -- State  :     G  G  G  D  D  D  D  G G G G G  D   D
+
+
+  -- FSM function, word boundary is 32b, tx_data_lo aligned to rx_data_lo:
+  -- =====================================================================
+  -- nxt_rx_sosi_hi = xgmii_rx_d_hi (during s_data)
+  -- nxt_rx_sosi_lo = xgmii_rx_d_lo (during s_data)
+  -- -----------------------
+  -- xgmii_rx_d_hi:  I_hi  I_hi  S_hi  D0_hi D1_hi D2_hi D3_hi T_hi I_hi I_hi I_hi S_hi  D4_hi  D5_hi
+  -- xgmii_rx_d_lo:  I_lo  I_lo  S_lo  D0_lo D1_lo D2_lo D3_lo T_lo I_lo I_lo I_lo S_lo  D4_lo  D5_lo
+
+  -- nxt_rx_data_hi: G     G     G     D0_hi D1_hi D2_hi D3_hi G_hi G_hi G_hi G_hi G_hi  D4_hi  D5_hi
+  -- nxt_rx_data_lo: G     G     G     D0_lo D1_lo D2_lo D3_lo G_lo G_lo G_lo G_lo G_lo  D4_lo  D5_lo
+  -- State  :        G     G     G     D     D     D     D     D    G    G    G    G     D      D
+  --                             ^     ^                       ^
+  --                             |     |                       TERM(LS portion) detected: nxt_rx_data = GAP during last s_data   
+  --                             |     nxt_rx_data<=DATA during all s_data cycles but the last
+  --                             START(LS portion) detected on xgmii_rx_d_lo: nxt_state <= s_data
+
+
+  -- FSM function, word boundary is 32b, tx_data_lo aligned to rx_data_hi:
+  -- =====================================================================
+  -- We need to use the previous rx_data_hi:
+  -- nxt_rx_sosi_hi = xgmii_rx_d_lo      (during s_data_misaligned)
+  -- nxt_rx_sosi_lo = prev_xgmii_rx_d_hi (during s_data_misaligned)
+  -- ---------------------------
+  -- xgmii_rx_d_hi:       I_lo  S_lo  D0_lo D1_lo D2_lo D3_lo T_lo  I_lo I_lo I_lo S_lo D4_lo D5_lo
+  -- xgmii_rx_d_lo:       I_hi  I_hi  S_hi  D0_hi D1_hi D2_hi D3_hi T_hi I_hi I_hi I_hi S_hi  D4_hi D5_hi
+  -- prev_xgmii_rx_d_hi:        I_lo  S_lo  D0_lo D1_lo D2_lo D3_lo T_lo I_lo I_lo I_lo S_lo  D4_lo D5_lo
+
+  -- nxt_rx_data_hi       G     G     G     D0_hi D1_hi D2_hi D3_hi G_hi G_hi G_hi G_hi G_hi  D4_hi D5_hi
+  -- nxt_rx_data_lo       G     G     G     D0_lo D1_lo D2_lo D3_lo G_lo G_lo G_lo G_lo G_lo  D4_lo D5_lo
+  -- State  :             G     G     D     D     D     D     D     G    G    G    G    G     D     D
+  --                            ^     ^                       ^
+  --                            |     |                       TERM(LS portion) detected: nxt_rx_data = DATA during last s_data_misaligned   
+  --                            |     nxt_rx_data<=GAP during first s_data_misaligned cycle (prev_state=s_gap)
+  --                            START(LS portion) detected on xgmii_rx_d_hi: nxt_state <= s_data_misaligned
+
+
+  p_clk : PROCESS(rx_clk, rx_rst)
+  BEGIN
+    IF rx_rst='1' THEN
+      state               <= s_init;  
+      prev_state          <= s_init;
+      prev_xgmii_rx_d_hi  <= (OTHERS=>'0');
+      rx_data_hi          <= (OTHERS=>'0');     
+      rx_data_lo          <= (OTHERS=>'0');
+      rx_data_val         <= '0';
+    ELSIF rising_edge(rx_clk) THEN
+      state               <= nxt_state;
+      prev_state          <= state;
+      prev_xgmii_rx_d_hi  <= xgmii_rx_d_hi;
+      rx_data_hi          <= nxt_rx_data_hi; 
+      rx_data_lo          <= nxt_rx_data_lo; 
+      rx_data_val         <= nxt_rx_data_val;
+    END IF;
+  END PROCESS;
+
+  -- Note: we only need the XGMII control as input to determine gaps and (mis)alignment
+  p_state : PROCESS(state, prev_state, prev_xgmii_rx_d_hi, xgmii_rx_c, xgmii_rx_c_lo, xgmii_rx_c_hi, xgmii_rx_d_hi, xgmii_rx_d_lo)
+  BEGIN  
+    nxt_state  <= state;  
+
+  CASE state IS
+     
+    WHEN s_gap =>
+      nxt_rx_data_hi  <= (OTHERS=>'0');
+      nxt_rx_data_lo  <= (OTHERS=>'0');
+      nxt_rx_data_val <= '0';
+      IF xgmii_rx_c_lo = c_xgmii_c_start_lo AND xgmii_rx_d_lo = c_xgmii_d_start_lo THEN 
+        -- Data happens to be aligned correctly
+        nxt_state <= s_data;
+      ELSIF xgmii_rx_c_hi = c_xgmii_c_start_lo AND xgmii_rx_d_hi = c_xgmii_d_start_lo THEN 
+        -- Data misaligned
+        nxt_state <= s_data_misaligned;
+      END IF;
+     
+    WHEN s_data => 
+      nxt_rx_data_hi  <= xgmii_rx_d_hi;
+      nxt_rx_data_lo  <= xgmii_rx_d_lo;
+      nxt_rx_data_val <= '1';
+      IF xgmii_rx_c_lo = c_xgmii_c_term_lo THEN 
+        -- As we're aligned properly, we can expect a TERM char in the LS word.
+        -- The MS word will contain the MS portion of the c_xgmii_c_term,
+        -- and after that we expect idle patterns, so nxt_rx_data is a GAP.
+        nxt_state       <= s_gap;
+        nxt_rx_data_hi  <= (OTHERS=>'0');
+        nxt_rx_data_lo  <= (OTHERS=>'0');
+        nxt_rx_data_val <= '0';
+      ELSIF xgmii_rx_c = c_xgmii_c_init THEN
+        -- Data interrupted due to re-initialization
+        nxt_state <= s_gap;
+      END IF;
+
+    WHEN s_data_misaligned => 
+      nxt_rx_data_hi  <= xgmii_rx_d_lo;
+      nxt_rx_data_lo  <= prev_xgmii_rx_d_hi;
+      nxt_rx_data_val <= '1';
+      IF prev_state = s_gap THEN
+        nxt_rx_data_hi  <= (OTHERS=>'0');
+        nxt_rx_data_lo  <= (OTHERS=>'0');
+        nxt_rx_data_val <= '0';
+      END IF;
+      IF xgmii_rx_c_hi = c_xgmii_c_term_lo THEN 
+        -- As we're misaligned, we can expect the LS portion of c_xgmii_c_term on the MS position.
+        nxt_state <= s_gap;
+      ELSIF xgmii_rx_c = c_xgmii_c_init THEN
+        -- Data interrupted due to re-initialization
+        nxt_state <= s_gap;
+      END IF;
+   
+    WHEN OTHERS =>
+      nxt_state       <= s_gap;
+      nxt_rx_data_hi  <= (OTHERS=>'0');
+      nxt_rx_data_lo  <= (OTHERS=>'0');
+      nxt_rx_data_val <= '0';
+
+    END CASE;
+  END PROCESS;
+
+END rtl;
+
+
diff --git a/libraries/io/tr_xaui/src/vhdl/tr_xaui_framer.vhd b/libraries/io/tr_xaui/src/vhdl/tr_xaui_framer.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..414f3cee9c5dbe0b5ed09e108122c55e116dbb4b
--- /dev/null
+++ b/libraries/io/tr_xaui/src/vhdl/tr_xaui_framer.vhd
@@ -0,0 +1,161 @@
+
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.std_logic_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+
+ENTITY tr_xaui_framer IS
+  GENERIC (
+    g_dat_len : NATURAL := 1000000; -- Max number of cycles carrying user data
+    g_gap_len : NATURAL := 5 -- Gap length, including 2 cycles for the START and TERMINATE words
+    );
+  PORT (
+    tx_clk     : IN STD_LOGIC;
+    tx_rst     : IN STD_LOGIC;
+    -- ST sink
+    snk_out    : OUT t_dp_siso;
+    snk_in     : IN  t_dp_sosi;
+
+    xgmii_tx_d : OUT STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+    xgmii_tx_c : OUT STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0)
+
+  );
+END tr_xaui_framer;
+
+ARCHITECTURE rtl OF tr_xaui_framer IS
+
+  TYPE t_state_enum IS (s_init, s_gap, s_data);
+
+  SIGNAL prev_state     : t_state_enum; 
+  SIGNAL state          : t_state_enum;
+  SIGNAL nxt_state      : t_state_enum; 
+
+  SIGNAL i_xgmii_tx_d   : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+  SIGNAL nxt_xgmii_tx_d : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+
+  SIGNAL i_xgmii_tx_c   : STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+  SIGNAL nxt_xgmii_tx_c : STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+
+  SIGNAL gap_siso       : t_dp_siso;
+  SIGNAL gap_sosi       : t_dp_sosi;
+
+  SIGNAL prev_gap_sosi  : t_dp_sosi;
+
+BEGIN
+
+  xgmii_tx_d <= i_xgmii_tx_d;
+  xgmii_tx_c <= i_xgmii_tx_c;
+
+  -- We're using a dp_gap instance to make sure gaps occur on a regular basis. This is
+  -- required as idle patterns (that are converted to lane alignment and other control
+  -- chars by the xaui phy IP) are inserted during these gaps. Dp_gap also extends any
+  -- gap on its snk_in to the minimum gap_len by deasserting snk_out.ready.
+  u_dp_gap : ENTITY dp_lib.dp_gap
+  GENERIC MAP (
+    g_dat_len    => g_dat_len,
+    g_gap_len    => g_gap_len,
+    g_gap_extend => TRUE
+  )
+  PORT MAP (
+    rst       => tx_rst,
+    clk       => tx_clk,
+
+    snk_out   => snk_out,
+    snk_in    => snk_in,
+    
+    src_in    => gap_siso,
+    src_out   => gap_sosi
+  );
+
+  gap_siso.ready <= '1';
+
+  -- As the dp_gap takes care of the frame length and the gap length, all our FSM needs
+  -- to do is to take care of xgmii data and control words:
+  --   * idle->data should be separated by a START (0xFB=Frame Begin) control char (inserted during 1 invalid cycle)
+  --   * data: encoded as data
+  --   * data->idle should be separated by a TERMINATE (0xFD=Frame Delimiter) control char (inserted during 1 invalid cycle)
+  --   * idle: encoded as control
+  -- ..so we need only 2 states (gap & data) and a data buffer:
+  -- 
+  --      gap_sosi: G  G  D0 D1 D2 D3 G  G G G G D4 D5  
+  -- prev_gap_sosi: G  G  G  D0 D1 D2 D3 G G G G G  D4  D5
+  -- nxt tx data  : I  I  S  D0 D1 D2 D3 T I I I S  D4  D5
+  -- State        : G  G  G  D  D  D  D  G G G G G  D   D
+  p_clk : PROCESS(tx_clk, tx_rst)
+  BEGIN
+    IF tx_rst='1' THEN
+      state               <= s_init;  
+      i_xgmii_tx_d        <= c_xgmii_d_idle;
+      i_xgmii_tx_c        <= c_xgmii_c_idle;
+    ELSIF rising_edge(tx_clk) THEN
+      state               <= nxt_state;
+      prev_state          <= state;
+      prev_gap_sosi       <= gap_sosi;
+      i_xgmii_tx_d        <= nxt_xgmii_tx_d;
+      i_xgmii_tx_c        <= nxt_xgmii_tx_c;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, prev_state, gap_sosi)
+  BEGIN  
+    nxt_state  <= state;  
+
+  CASE state IS
+     
+    WHEN s_gap =>
+      -- Insert idle words during gaps
+      nxt_xgmii_tx_d <= c_xgmii_d_idle; 
+      nxt_xgmii_tx_c <= c_xgmii_c_idle;
+      IF prev_state = s_data THEN 
+        -- Insert the TERM word during transition from data to idle
+        nxt_xgmii_tx_d <= c_xgmii_d_term;
+        nxt_xgmii_tx_c <= c_xgmii_c_term;
+      END IF;
+      IF gap_sosi.valid = '1' THEN  
+        -- Insert the START word during transition from idle to data
+        nxt_state      <= s_data;
+        nxt_xgmii_tx_d <= c_xgmii_d_start;
+        nxt_xgmii_tx_c <= c_xgmii_c_start;
+      END IF;
+    
+    WHEN s_data => -- Forward the data stored in prev_gap_sosi
+      nxt_xgmii_tx_d <= prev_gap_sosi.data(c_xgmii_data_w-1 DOWNTO 0);
+      nxt_xgmii_tx_c <= c_xgmii_c_data;
+      IF gap_sosi.valid = '0' THEN
+        nxt_state      <= s_gap;
+      END IF;
+ 
+    WHEN OTHERS => -- s_init
+      nxt_state      <= s_gap;
+      nxt_xgmii_tx_d <= c_xgmii_d_idle;
+      nxt_xgmii_tx_c <= c_xgmii_c_idle;
+
+    END CASE;
+  END PROCESS;
+
+END rtl;
+
+
diff --git a/libraries/io/tr_xaui/tb/vhdl/sim_xaui.vhd b/libraries/io/tr_xaui/tb/vhdl/sim_xaui.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..12ef7dee8f55a244ad2ced8aa7418cd782e2aa1a
--- /dev/null
+++ b/libraries/io/tr_xaui/tb/vhdl/sim_xaui.vhd
@@ -0,0 +1,154 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2013
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+--------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, tr_nonbonded_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+
+ENTITY sim_xaui IS
+  GENERIC(
+    g_nof_xaui        : NATURAL := 1
+  );                      
+  PORT (   
+    -- Transceiver PLL reference clock   
+    tr_clk                  : IN  STD_LOGIC;
+    trc_rst                 : IN  STD_LOGIC;
+
+    -- Calibration & reconfig clock
+    cal_rec_clk             : IN  STD_LOGIC;
+ 
+    tx_clk                  : IN  STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+    rx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+   
+    crc_rx_ready            : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0); --crc = synchronous to Cal_Rec_Clk
+    crc_tx_ready            : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+    a_rx_channelaligned     : OUT STD_LOGIC_VECTOR(g_nof_xaui-1 DOWNTO 0);
+
+    xgmii_tx_dc             : IN  t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0);
+    xgmii_rx_dc             : OUT t_xgmii_dc_arr(g_nof_xaui-1 DOWNTO 0);
+
+    xaui_rx                 : IN  t_xaui_arr(g_nof_xaui-1 DOWNTO 0);
+    xaui_tx                 : OUT t_xaui_arr(g_nof_xaui-1 DOWNTO 0)
+  );
+END sim_xaui;
+
+
+ARCHITECTURE wrap OF sim_xaui IS  
+
+  CONSTANT c_xaui_serdes_data_w    : NATURAL := 16;
+  CONSTANT c_xaui_serdes_ctrl_w    : NATURAL := c_xaui_serdes_data_w/c_byte_w;
+  CONSTANT c_xaui_serdes_line_rate : NATURAL := 3125;
+
+  --XGMII control bits (one for each XGMII lane):
+  SIGNAL xgmii_tx_c                : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL xgmii_rx_c                : t_xgmii_c_arr(g_nof_xaui-1 DOWNTO 0);
+  
+  --XGMII data
+  SIGNAL xgmii_tx_d                : t_xgmii_d_arr(g_nof_xaui-1 DOWNTO 0);
+  SIGNAL xgmii_rx_d                : t_xgmii_d_arr(g_nof_xaui-1 DOWNTO 0);
+ 
+BEGIN
+
+  rx_clk <= tx_clk;
+ 
+  gen_nof_xaui : FOR i IN g_nof_xaui-1 DOWNTO 0 GENERATE
+
+    xgmii_tx_d(i) <= xgmii_d(xgmii_tx_dc(i));
+    xgmii_tx_c(i) <= xgmii_c(xgmii_tx_dc(i));
+
+    xgmii_rx_dc(i) <= xgmii_dc(xgmii_rx_d(i), xgmii_rx_c(i));
+    
+    u_areset_tx_rdy : ENTITY common_lib.common_areset
+    GENERIC MAP(
+      g_rst_level => '0',
+      g_delay_len => 10
+    )
+    PORT MAP(
+      clk     => cal_rec_clk,
+      in_rst  => '0',
+      out_rst => crc_tx_ready(i)
+    );    
+
+    u_areset_rx_rdy : ENTITY common_lib.common_areset
+    GENERIC MAP(
+      g_rst_level => '0',
+      g_delay_len => 20
+    )
+    PORT MAP(
+      clk     => cal_rec_clk,
+      in_rst  => '0',
+      out_rst => crc_rx_ready(i)
+    );   
+
+    u_areset_rx_channelaligned : ENTITY common_lib.common_areset
+    GENERIC MAP(
+      g_rst_level => '0',
+      g_delay_len => 30
+    )
+    PORT MAP(
+      clk     => cal_rec_clk,
+      in_rst  => '0',
+      out_rst => a_rx_channelaligned(i)
+    );    
+
+    gen_serdes: FOR j IN c_nof_xaui_lanes-1 DOWNTO 0 GENERATE
+
+      u_ser: ENTITY tr_nonbonded_lib.serializer
+      GENERIC MAP (
+        g_data_w    => c_xaui_serdes_data_w,
+        g_line_rate => c_xaui_serdes_line_rate
+      )
+      PORT MAP (
+          
+        tr_clk             => tr_clk,  
+        tr_rst             => trc_rst,
+         
+        tx_in_data         => xgmii_tx_d(i)(j*c_xaui_serdes_data_w+c_xaui_serdes_data_w-1 DOWNTO j*c_xaui_serdes_data_w),
+        tx_in_ctrl         => xgmii_tx_c(i)(j*c_xaui_serdes_ctrl_w+c_xaui_serdes_ctrl_w-1 DOWNTO j*c_xaui_serdes_ctrl_w),
+    
+        tx_out             => xaui_tx(i)(j)
+      );
+
+      u_des: ENTITY tr_nonbonded_lib.deserializer 
+      GENERIC MAP (
+        g_data_w    => c_xaui_serdes_data_w,
+        g_line_rate => c_xaui_serdes_line_rate
+      )
+      PORT MAP (
+          
+        tr_clk             => tr_clk,  
+        tr_rst             => trc_rst,
+         
+        rx_out_data        => xgmii_rx_d(i)(j*c_xaui_serdes_data_w+c_xaui_serdes_data_w-1 DOWNTO j*c_xaui_serdes_data_w),
+        rx_out_ctrl        => xgmii_rx_c(i)(j*c_xaui_serdes_ctrl_w+c_xaui_serdes_ctrl_w-1 DOWNTO j*c_xaui_serdes_ctrl_w),
+    
+        rx_in              => xaui_rx(i)(j)
+      );
+
+    END GENERATE;
+
+  END GENERATE;
+      
+END wrap;
+
diff --git a/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_deframer.vhd b/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_deframer.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..bc2b2d58d66fea4d3264297d906eaeb47247a4d0
--- /dev/null
+++ b/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_deframer.vhd
@@ -0,0 +1,197 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE dp_lib.tb_dp_pkg.ALL;
+
+ENTITY tb_tr_xaui_deframer IS
+END tb_tr_xaui_deframer;
+
+ARCHITECTURE tb OF tb_tr_xaui_deframer IS
+
+  CONSTANT c_clk_period   : TIME    := 10 ns;   
+  CONSTANT c_rl           : NATURAL := 1;
+  CONSTANT c_tx_init      : NATURAL := 0;
+
+  SIGNAL rst              : STD_LOGIC;
+  SIGNAL clk              : STD_LOGIC := '1';
+  
+  SIGNAL tx_enable        : STD_LOGIC;
+
+  SIGNAL tx_siso          : t_dp_siso;
+  SIGNAL tx_sosi          : t_dp_sosi;
+
+  SIGNAL gap_siso         : t_dp_siso;
+  SIGNAL gap_sosi         : t_dp_sosi;
+
+  SIGNAL xgmii_tx_d       : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+  SIGNAL xgmii_tx_c       : STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+
+  SIGNAL xgmii_rx_d       : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+  SIGNAL xgmii_rx_c       : STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+
+  SIGNAL deframer_sosi    : t_dp_sosi;
+  SIGNAL deframer_siso    : t_dp_siso;
+
+  SIGNAL verify_en        : STD_LOGIC;
+  SIGNAL prev_data1       : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+  SIGNAL prev_data2       : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+
+  SIGNAL xgmii_rx_d_hi      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL xgmii_rx_d_lo      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  SIGNAL xgmii_tx_d_hi      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL xgmii_tx_d_lo      : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  SIGNAL prev_xgmii_tx_d_hi : STD_LOGIC_VECTOR(c_xgmii_data_w/2-1 DOWNTO 0);
+  SIGNAL prev_xgmii_tx_c_hi : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  SIGNAL xgmii_tx_c_hi      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+  SIGNAL xgmii_tx_c_lo      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  SIGNAL xgmii_rx_c_hi      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+  SIGNAL xgmii_rx_c_lo      : STD_LOGIC_VECTOR(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  SIGNAL misalign           : STD_LOGIC;
+
+BEGIN
+
+  rst <= '1', '0' AFTER c_clk_period*7;
+  clk <= NOT clk AFTER c_clk_period/2;
+
+  xgmii_tx_d_hi <= xgmii_tx_d(c_xgmii_data_w  -1 DOWNTO c_xgmii_data_w/2);
+  xgmii_tx_d_lo <= xgmii_tx_d(c_xgmii_data_w/2-1 DOWNTO 0);
+
+  xgmii_tx_c_hi <= xgmii_tx_c(c_xgmii_nof_lanes  -1 DOWNTO c_xgmii_nof_lanes/2);
+  xgmii_tx_c_lo <= xgmii_tx_c(c_xgmii_nof_lanes/2-1 DOWNTO 0);
+
+  xgmii_rx_d <= xgmii_rx_d_hi & xgmii_rx_d_lo;
+  xgmii_rx_c <= xgmii_rx_c_hi & xgmii_rx_c_lo;
+
+  p_stim : PROCESS
+  BEGIN
+    tx_enable <= '0';
+    verify_en <= '0';   
+    misalign  <= '0';
+
+    WAIT FOR c_clk_period*100; 
+    tx_enable <= '1';
+    gap_siso.ready <= '1';
+  
+    WAIT FOR c_clk_period*20; 
+    verify_en <= '1';
+
+    -- Let run for a while with aligned data
+    WAIT FOR 3 us;
+
+    WAIT UNTIL deframer_sosi.valid = '0';
+    WAIT UNTIL rising_edge(clk);
+    misalign  <= '1'; -- Now change the 32b word boundary
+
+    WAIT;
+  END PROCESS;  
+  
+   -- Generate tx_sosi for DUT using counter data generator
+  proc_dp_gen_data(c_rl, c_xgmii_data_w, c_tx_init, rst, clk, tx_enable, tx_siso, tx_sosi);
+  
+  -- Introduce some gaps in the streaming data to make sure framer handles them correctly.
+  u_dp_gap : ENTITY dp_lib.dp_gap
+  GENERIC MAP (
+    g_dat_len    => 40,
+    g_gap_len    => 20
+  )
+  PORT MAP (
+    rst       => rst,
+    clk       => clk,
+
+    snk_out   => tx_siso,
+    snk_in    => tx_sosi,
+    
+    src_in    => gap_siso,
+    src_out   => gap_sosi
+  );
+
+  u_framer : ENTITY work.tr_xaui_framer
+  GENERIC MAP (
+    g_dat_len => 100,
+    g_gap_len => 5
+   )
+  PORT MAP (
+    tx_rst     => rst,
+    tx_clk     => clk,
+
+    snk_out    => gap_siso,
+    snk_in     => gap_sosi,
+
+    xgmii_tx_d => xgmii_tx_d,
+    xgmii_tx_c => xgmii_tx_c    
+  );
+
+  -- ============== We'll emulate misalignment here ===========================
+ 
+  -- Aligned data:
+  -- RX Hi:  0 1 2 3 4 5
+  -- RX Lo:  0 1 2 3 4 5
+  xgmii_rx_d_hi <= xgmii_tx_d_lo WHEN misalign = '1' ELSE xgmii_tx_d_hi;
+  xgmii_rx_c_hi <= xgmii_tx_c_lo WHEN misalign = '1' ELSE xgmii_tx_c_hi;
+
+  -- Misligned data:
+  -- RX Hi:  1 2 3 4 5 6
+  -- RX Lo:  0 1 2 3 4 5
+  xgmii_rx_d_lo <= prev_xgmii_tx_d_hi WHEN misalign = '1' ELSE xgmii_tx_d_lo;
+  xgmii_rx_c_lo <= prev_xgmii_tx_c_hi WHEN misalign = '1' ELSE xgmii_tx_c_lo;
+
+  p_clk : PROCESS(clk, rst)
+  BEGIN
+    IF rst='1' THEN
+      prev_xgmii_tx_d_hi <= x"07070707";
+      prev_xgmii_tx_c_hi <= x"F";
+    ELSIF rising_edge(clk) THEN
+      prev_xgmii_tx_d_hi <= xgmii_tx_d_hi;
+      prev_xgmii_tx_c_hi <= xgmii_tx_c_hi;
+    END IF;
+  END PROCESS;
+
+  -- ===========================================================================
+
+  dut : ENTITY work.tr_xaui_deframer
+  PORT MAP (
+    rx_rst     => rst,
+    rx_clk     => clk,
+
+    xgmii_rx_d => xgmii_rx_d,
+    xgmii_rx_c => xgmii_rx_c,
+
+    src_out    => deframer_sosi
+
+  );
+
+  -- Verify DUT output incrementing data, prev_data is an auxiliary signal needed by the proc
+  proc_common_verify_data(c_rl, clk, verify_en, deframer_siso.ready, deframer_sosi.valid, deframer_sosi.data(c_xgmii_data_w-1 DOWNTO 0), prev_data1);
+  proc_dp_verify_data("data", c_rl, clk, verify_en, deframer_siso.ready, deframer_sosi.valid, deframer_sosi.data(c_xgmii_data_w-1 DOWNTO 0), prev_data2);  
+ 
+END tb;
diff --git a/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_framer.vhd b/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_framer.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..dee798e02ab6598f90a9e525f11ef83cb5b6a3c3
--- /dev/null
+++ b/libraries/io/tr_xaui/tb/vhdl/tb_tr_xaui_framer.vhd
@@ -0,0 +1,106 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2012
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE common_lib.common_interface_layers_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE dp_lib.tb_dp_pkg.ALL;
+
+ENTITY tb_tr_xaui_framer IS
+END tb_tr_xaui_framer;
+
+ARCHITECTURE tb OF tb_tr_xaui_framer IS
+
+  CONSTANT c_clk_period   : TIME    := 10 ns;   
+  CONSTANT c_rl           : NATURAL := 1;
+  CONSTANT c_tx_init      : NATURAL := 0;
+
+  SIGNAL rst              : STD_LOGIC;
+  SIGNAL clk              : STD_LOGIC := '1';
+  
+  SIGNAL tx_enable        : STD_LOGIC;
+
+  SIGNAL tx_siso          : t_dp_siso;
+  SIGNAL tx_sosi          : t_dp_sosi;
+
+  SIGNAL gap_siso         : t_dp_siso;
+  SIGNAL gap_sosi         : t_dp_sosi;
+
+  SIGNAL xgmii_tx_d       : STD_LOGIC_VECTOR(c_xgmii_data_w-1 DOWNTO 0);
+  SIGNAL xgmii_tx_c       : STD_LOGIC_VECTOR(c_xgmii_nof_lanes-1 DOWNTO 0);
+
+BEGIN
+
+  rst <= '1', '0' AFTER c_clk_period*7;
+  clk <= NOT clk AFTER c_clk_period/2;
+
+  p_stim : PROCESS
+  BEGIN
+    tx_enable <= '0';
+    
+    WAIT FOR c_clk_period*100; 
+    tx_enable <= '1';
+ 
+    WAIT;
+  END PROCESS;  
+  
+   -- Generate tx_sosi for DUT using counter data generator
+  proc_dp_gen_data(c_rl, c_xgmii_data_w, c_tx_init, rst, clk, tx_enable, tx_siso, tx_sosi);
+  
+  -- Introduce some gaps in the streaming data to make sure framer handles them correctly.
+  u_dp_gap : ENTITY dp_lib.dp_gap
+  GENERIC MAP (
+    g_dat_len    => 40,
+    g_gap_len    => 20
+  )
+  PORT MAP (
+    rst       => rst,
+    clk       => clk,
+
+    snk_out   => tx_siso,
+    snk_in    => tx_sosi,
+    
+    src_in    => gap_siso,
+    src_out   => gap_sosi
+  );
+
+  dut : ENTITY work.tr_xaui_framer
+  GENERIC MAP (
+    g_dat_len => 100,
+    g_gap_len => 5
+   )
+  PORT MAP (
+    tx_rst     => rst,
+    tx_clk     => clk,
+
+    snk_out    => gap_siso,
+    snk_in     => gap_sosi,
+
+    xgmii_tx_d => xgmii_tx_d,
+    xgmii_tx_c => xgmii_tx_c
+    
+  );
+    
+END tb;