From 359aff8281e145c82857878b8500cb1bffb50d44 Mon Sep 17 00:00:00 2001
From: Erik Kooistra <kooistra@astron.nl>
Date: Tue, 3 Jun 2014 09:45:59 +0000
Subject: [PATCH] Ported the gigabit transceiver from tr_nonbonded phy_gx.vhd
 to tech_transceiver_gx_stratixiv.vhd. The tech_transceiver_gx_stratixiv.vhd
 is instantiated in tech_transceiver_gx.vhd when
 g_technology=c_tech_stratixiv. The tech_transceiver_gx.vhd is the technology
 independent component for the user.

---
 libraries/technology/transceiver/hdllib.cfg   |  18 +
 .../tech_transceiver_component_pkg.vhd        | 154 +++++
 .../transceiver/tech_transceiver_gx.vhd       |  81 +++
 .../tech_transceiver_gx_stratixiv.vhd         | 531 ++++++++++++++++++
 .../transceiver/tech_transceiver_rx_align.vhd | 163 ++++++
 .../transceiver/tech_transceiver_rx_order.vhd | 106 ++++
 .../transceiver/tech_transceiver_rx_rst.vhd   | 156 +++++
 .../transceiver/tech_transceiver_tx_align.vhd | 129 +++++
 .../transceiver/tech_transceiver_tx_rst.vhd   | 139 +++++
 9 files changed, 1477 insertions(+)
 create mode 100644 libraries/technology/transceiver/hdllib.cfg
 create mode 100644 libraries/technology/transceiver/tech_transceiver_component_pkg.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_gx.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_gx_stratixiv.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_rx_align.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_rx_order.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_rx_rst.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_tx_align.vhd
 create mode 100644 libraries/technology/transceiver/tech_transceiver_tx_rst.vhd

diff --git a/libraries/technology/transceiver/hdllib.cfg b/libraries/technology/transceiver/hdllib.cfg
new file mode 100644
index 0000000000..9ab90cf369
--- /dev/null
+++ b/libraries/technology/transceiver/hdllib.cfg
@@ -0,0 +1,18 @@
+hdl_lib_name = tech_transceiver
+hdl_library_clause_name = tech_transceiver_lib
+hdl_lib_uses = technology ip_altera_mf ip_stratixiv_hssi
+
+build_sim_dir = $HDL_BUILD_DIR
+build_synth_dir = 
+
+synth_files =
+    tech_transceiver_component_pkg.vhd
+    tech_transceiver_rx_order.vhd
+    tech_transceiver_rx_align.vhd
+    tech_transceiver_rx_rst.vhd
+    tech_transceiver_tx_align.vhd
+    tech_transceiver_tx_rst.vhd
+    tech_transceiver_gx_stratixiv.vhd
+    tech_transceiver_gx.vhd
+
+test_bench_files =
diff --git a/libraries/technology/transceiver/tech_transceiver_component_pkg.vhd b/libraries/technology/transceiver/tech_transceiver_component_pkg.vhd
new file mode 100644
index 0000000000..46e268c3d3
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_component_pkg.vhd
@@ -0,0 +1,154 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2014
+-- 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/>.
+--
+-------------------------------------------------------------------------------
+
+-- Purpose: IP components declarations for various devices that get wrapped by the tech components
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+
+PACKAGE tech_transceiver_component_pkg IS
+
+  ------------------------------------------------------------------------------
+  -- stratixiv_hssi
+  ------------------------------------------------------------------------------
+  
+  COMPONENT ip_stratixiv_hssi_gx_generic IS
+  GENERIC (
+    g_mbps                    : NATURAL;
+    starting_channel_number   : NATURAL := 0
+  );
+  PORT (
+    cal_blk_clk              : IN STD_LOGIC ;
+    gxb_powerdown            : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    pll_inclk                : IN STD_LOGIC ;
+    pll_powerdown            : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    reconfig_clk             : IN STD_LOGIC ;
+    reconfig_togxb           : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_analogreset           : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_datain                : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_digitalreset          : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_enapatternalign       : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_seriallpbken          : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    tx_ctrlenable            : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
+    tx_datain                : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+    tx_digitalreset          : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    pll_locked               : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    reconfig_fromgxb         : OUT STD_LOGIC_VECTOR (16 DOWNTO 0);
+    rx_byteorderalignstatus  : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_clkout                : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_ctrldetect            : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_dataout               : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+    rx_disperr               : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_errdetect             : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_freqlocked            : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_patterndetect         : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    tx_clkout                : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    tx_dataout               : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
+  );
+  END COMPONENT;
+
+  COMPONENT ip_stratixiv_hssi_tx_generic IS
+  GENERIC(
+    g_mbps : NATURAL
+  );
+  PORT (
+    cal_blk_clk     : IN STD_LOGIC ;
+    gxb_powerdown   : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    pll_inclk       : IN STD_LOGIC ;
+    pll_powerdown   : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    tx_ctrlenable   : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
+    tx_datain       : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+    tx_digitalreset : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    pll_locked      : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    tx_clkout       : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    tx_dataout      : OUT STD_LOGIC_VECTOR (0 DOWNTO 0)
+  );
+  END COMPONENT;
+  
+  COMPONENT ip_stratixiv_hssi_rx_generic IS
+  GENERIC (
+    g_mbps                  : NATURAL;
+    starting_channel_number : NATURAL := 0
+  );
+  PORT (
+    cal_blk_clk              : IN STD_LOGIC ;
+    gxb_powerdown            : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    reconfig_clk             : IN STD_LOGIC ;
+    reconfig_togxb           : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_analogreset           : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_cruclk                : IN STD_LOGIC_VECTOR (0 DOWNTO 0) :=  (OTHERS => '0');
+    rx_datain                : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_digitalreset          : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_enapatternalign       : IN STD_LOGIC_VECTOR (0 DOWNTO 0);
+    reconfig_fromgxb         : OUT STD_LOGIC_VECTOR (16 DOWNTO 0);
+    rx_byteorderalignstatus  : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_clkout                : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_ctrldetect            : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_dataout               : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
+    rx_disperr               : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_errdetect             : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
+    rx_freqlocked            : OUT STD_LOGIC_VECTOR (0 DOWNTO 0);
+    rx_patterndetect         : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
+  );
+  END COMPONENT;
+  
+  
+  ------------------------------------------------------------------------------
+  -- altera_mf
+  ------------------------------------------------------------------------------
+  
+  COMPONENT ip_altera_mf_gxb_reconfig_12_stratixiv IS
+  PORT (
+    reconfig_clk     : IN STD_LOGIC ;
+    reconfig_fromgxb : IN STD_LOGIC_VECTOR (203 DOWNTO 0);
+    busy             : OUT STD_LOGIC ;
+    reconfig_togxb   : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
+  );
+  END COMPONENT;
+  
+  COMPONENT ip_altera_mf_gxb_reconfig_8_stratixiv IS
+  PORT (
+    reconfig_clk     : IN STD_LOGIC ;
+    reconfig_fromgxb : IN STD_LOGIC_VECTOR (135 DOWNTO 0);
+    busy             : OUT STD_LOGIC ;
+    reconfig_togxb   : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
+  );
+  END COMPONENT;
+
+  COMPONENT ip_altera_mf_gxb_reconfig_4_stratixiv IS
+  PORT (
+    reconfig_clk     : IN STD_LOGIC ;
+    reconfig_fromgxb : IN STD_LOGIC_VECTOR (67 DOWNTO 0);
+    busy             : OUT STD_LOGIC ;
+    reconfig_togxb   : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
+  );
+  END COMPONENT;
+  
+  COMPONENT ip_altera_mf_gxb_reconfig_2_stratixiv IS
+  PORT (
+    reconfig_clk     : IN STD_LOGIC ;
+    reconfig_fromgxb : IN STD_LOGIC_VECTOR (33 DOWNTO 0);
+    busy             : OUT STD_LOGIC ;
+    reconfig_togxb   : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
+  );
+  END COMPONENT;
+
+END tech_transceiver_component_pkg;
diff --git a/libraries/technology/transceiver/tech_transceiver_gx.vhd b/libraries/technology/transceiver/tech_transceiver_gx.vhd
new file mode 100644
index 0000000000..357476ca0c
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_gx.vhd
@@ -0,0 +1,81 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2014
+-- 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, technology_lib, common_lib, dp_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+USE work.tech_transceiver_component_pkg.ALL;
+USE technology_lib.technology_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.tr_nonbonded_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+
+ENTITY tech_transceiver_gx IS 
+  GENERIC(
+    g_technology            : NATURAL := c_tech_select_default;
+    g_data_w                : NATURAL := 32; -- Supported: 32, 16.
+    g_nof_gx                : NATURAL;
+    g_mbps                  : NATURAL;  -- Supported: 6250, 5000, 3125, 2500 when g_data_w=32, else 2500 when g_data_w=16
+    g_sim                   : BOOLEAN;
+    g_tx                    : BOOLEAN;
+    g_rx                    : BOOLEAN
+  );      
+  PORT(
+    cal_rec_clk             : IN  STD_LOGIC;
+    tr_clk                  : IN  STD_LOGIC;
+
+    rx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    rx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    rx_sosi_arr             : OUT t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0);
+    rx_siso_arr             : IN  t_dp_siso_arr(g_nof_gx-1 DOWNTO 0);
+
+    tx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_sosi_arr             : IN  t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0);
+    tx_siso_arr             : OUT t_dp_siso_arr(g_nof_gx-1 DOWNTO 0);
+   
+    --Serial I/O
+    rx_datain               : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_dataout              : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);   
+
+    -- Ctrl&stat
+    tx_state                : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0);
+    tx_align_en             : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+
+    rx_state                : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0);
+    rx_align_en             : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0)
+  );
+
+END tech_transceiver_gx;
+
+ARCHITECTURE str OF tech_transceiver_gx IS
+BEGIN
+ 
+  gen_stratixiv_hssi : IF g_technology=c_tech_stratixiv GENERATE
+    u0 : ENTITY work.tech_transceiver_gx_stratix_iv
+    GENERIC MAP (g_data_w, g_nof_gx, g_mbps, g_sim, g_tx, g_rx)
+    PORT MAP (cal_rec_clk, tr_clk, rx_clk, rx_rst, rx_sosi_arr, rx_siso_arr, tx_clk, tx_rst, tx_sosi_arr, tx_siso_arr, rx_datain, tx_dataout, tx_state, tx_align_en, rx_state, rx_align_en);
+  END GENERATE;
+  
+END str;
+
diff --git a/libraries/technology/transceiver/tech_transceiver_gx_stratixiv.vhd b/libraries/technology/transceiver/tech_transceiver_gx_stratixiv.vhd
new file mode 100644
index 0000000000..598b0e1b6a
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_gx_stratixiv.vhd
@@ -0,0 +1,531 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2014
+-- 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 IEEE.STD_LOGIC_UNSIGNED.ALL;
+USE work.tech_transceiver_component_pkg.ALL;
+USE common_lib.common_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+
+-- Declare IP libraries to ensure default binding in simulation. The IP library clause is ignored by synthesis.
+LIBRARY ip_altera_mf_lib;
+LIBRARY ip_stratixiv_hssi_lib;
+
+ENTITY tech_transceiver_gx_stratix_iv IS 
+  GENERIC(
+    g_data_w                : NATURAL := 32; -- Supported: 32, 16.
+    g_nof_gx                : NATURAL;
+    g_mbps                  : NATURAL;  -- Supported: 6250, 5000, 3125, 2500 when g_data_w=32, else 2500 when g_data_w=16
+    g_sim                   : BOOLEAN;
+    g_tx                    : BOOLEAN;
+    g_rx                    : BOOLEAN
+  );      
+  PORT(
+    cal_rec_clk             : IN  STD_LOGIC;
+    tr_clk                  : IN  STD_LOGIC;
+
+    rx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    rx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    rx_sosi_arr             : OUT t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0);
+    rx_siso_arr             : IN  t_dp_siso_arr(g_nof_gx-1 DOWNTO 0);
+
+    tx_clk                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_rst                  : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_sosi_arr             : IN  t_dp_sosi_arr(g_nof_gx-1 DOWNTO 0);
+    tx_siso_arr             : OUT t_dp_siso_arr(g_nof_gx-1 DOWNTO 0);
+   
+    --Serial I/O
+    rx_datain               : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    tx_dataout              : OUT STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);   
+
+    -- Ctrl&stat
+    tx_state                : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0);
+    tx_align_en             : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+
+    rx_state                : OUT STD_LOGIC_VECTOR(2*g_nof_gx-1 DOWNTO 0);
+    rx_align_en             : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0)
+  );
+
+END tech_transceiver_gx_stratix_iv;
+
+ARCHITECTURE str OF tech_transceiver_gx_stratix_iv IS
+
+  CONSTANT c_align_pattern_32      : STD_LOGIC_VECTOR := x"0000BC1C";  --Change in megafunction first. BC is std. comma symbol (K.28.5).
+  CONSTANT c_inval_pattern_32      : STD_LOGIC_VECTOR := x"3C3C3C3C";  --comma symbol K.28.1 (decoded as 3C) is used as invalid data indicator.
+
+  CONSTANT c_align_pattern_16      : STD_LOGIC_VECTOR := x"BCBC";      --Change in megafunction first. BC is std. comma symbol (K.28.5).
+  CONSTANT c_inval_pattern_16      : STD_LOGIC_VECTOR := x"BCBC";
+
+  CONSTANT c_align_pattern         : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := sel_a_b(g_data_w=16, c_align_pattern_16, c_align_pattern_32);
+  CONSTANT c_inval_pattern         : STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0) := sel_a_b(g_data_w=16, c_inval_pattern_16, c_inval_pattern_32);
+
+  CONSTANT c_reconf_togxb_bus_w    : NATURAL := 4;
+  CONSTANT c_reconf_fromgxb_bus_w  : NATURAL := 17;
+
+  CONSTANT c_nof_ctrl_bytes        : NATURAL := g_data_w / c_byte_w;
+
+  TYPE t_data_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+  TYPE t_ctrl_arr IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(c_nof_ctrl_bytes-1 DOWNTO 0);
+
+  SIGNAL reconfig_togxb            : STD_LOGIC_VECTOR(c_reconf_togxb_bus_w-1 DOWNTO 0);
+  SIGNAL reconfig_fromgxb          : STD_LOGIC_VECTOR(c_reconf_fromgxb_bus_w*g_nof_gx-1 DOWNTO 0);
+
+  SIGNAL rx_freq_locked            : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL tx_pll_locked             : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'0');
+  SIGNAL rec_busy                  : STD_LOGIC;
+  
+  SIGNAL trc_tx_pll_powerdown      : STD_LOGIC;
+  SIGNAL trc_tx_digital_rst        : STD_LOGIC;
+
+  SIGNAL trc_rx_analog_rst         : STD_LOGIC;
+  SIGNAL trc_rx_digital_rst        : STD_LOGIC;
+
+  SIGNAL i_tx_clk                  : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+  SIGNAL i_rx_clk                  : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+
+  SIGNAL i_tx_rst                  : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+  SIGNAL i_rx_rst                  : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+ 
+  SIGNAL tr_rst                    : STD_LOGIC;
+
+  SIGNAL trc_tx_rdy                : STD_LOGIC;
+  SIGNAL trc_rx_rdy                : STD_LOGIC;
+
+  SIGNAL not_trc_tx_rdy            : STD_LOGIC;
+  SIGNAL not_trc_rx_rdy            : STD_LOGIC;
+
+  SIGNAL tx_align_en_out           : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'0');
+
+  SIGNAL tx_datain                 : t_data_arr(g_nof_gx-1 DOWNTO 0);
+  SIGNAL rx_dataout                : t_data_arr(g_nof_gx-1 DOWNTO 0);
+
+  SIGNAL txc_tx_ctrlenable         : t_ctrl_arr(g_nof_gx-1 DOWNTO 0);
+  SIGNAL rxc_rx_ctrldetect         : t_ctrl_arr(g_nof_gx-1 DOWNTO 0); 
+
+  SIGNAL rxc_rx_align_en           : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0); --edge sensitive
+  SIGNAL rxc_rx_aligned            : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0) := (OTHERS=>'1');
+  
+BEGIN
+ 
+  ------------------------------------------------------------------------------
+  -- ALTGX Megafunction
+  ------------------------------------------------------------------------------
+
+  gen_altgx: FOR i IN 0 to g_nof_gx-1 GENERATE  --Generate g_nof_gx one-channel ALTGX instances 
+  
+    gen_tr : IF g_tx = TRUE AND g_rx = TRUE GENERATE  --Generate duplex transceivers
+    
+      gen_32b : IF g_data_w = 32 GENERATE
+        u_gx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_gx_generic
+        GENERIC MAP (
+          g_mbps                   => g_mbps,
+          starting_channel_number  => i*4  --Starting channel numbers must be 0,4,8,12 etc for individual ALTGX instances
+        )                                  --Reconfig megawizard: regenerate with 'number of channels' = 4*nof_gx 
+        PORT MAP (   
+          -- Clocks, in
+          pll_inclk           => tr_clk,  
+          cal_blk_clk         => cal_rec_clk,      
+          reconfig_clk        => cal_rec_clk,
+        
+          -- Clocks, generated (out)
+          sl(tx_clkout)       => i_tx_clk(i),   
+          sl(rx_clkout)       => i_rx_clk(i), 
+        
+          -- Parallel data I/O
+          rx_dataout          => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0), 
+          tx_datain           => tx_datain(i), 
+        
+          -- Serial data I/O 
+          rx_datain           => slv(rx_datain(i)),  
+          sl(tx_dataout)      => tx_dataout(i),
+        
+          -- Initialization I/O
+          sl(rx_freqlocked)   => rx_freq_locked(i),
+          sl(pll_locked)      => tx_pll_locked(i),
+          pll_powerdown       => slv(trc_tx_pll_powerdown),  
+          rx_digitalreset     => slv(trc_rx_digital_rst),                  
+          rx_analogreset      => slv(trc_rx_analog_rst),
+          tx_digitalreset     => slv(trc_tx_digital_rst),
+        
+          -- 8b/10b related
+          tx_ctrlenable       => txc_tx_ctrlenable(i), --8b10b
+          rx_ctrldetect       => rxc_rx_ctrldetect(i), --8b10b
+          rx_enapatternalign  => slv(rxc_rx_align_en(i)),
+        
+          -- Reconfig block connections
+          reconfig_togxb      => reconfig_togxb,
+          reconfig_fromgxb    => reconfig_fromgxb(c_reconf_fromgxb_bus_w*(i+1)-1 DOWNTO c_reconf_fromgxb_bus_w*(i+1)-c_reconf_fromgxb_bus_w),
+        
+          rx_seriallpbken     => slv('0'),
+          gxb_powerdown       => (OTHERS=>'0')
+        );  
+      END GENERATE;
+
+      gen_16b : IF g_data_w = 16 GENERATE 
+        u_gx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_gx_16b
+        GENERIC MAP (
+          starting_channel_number  => i*4  --Starting channel numbers must be 0,4,8,12 etc for individual ALTGX instances
+        )                                  --Reconfig megawizard: regenerate with 'number of channels' = 4*nof_gx 
+        PORT MAP (   
+          -- Clocks, in
+          pll_inclk           => tr_clk,  
+          cal_blk_clk         => cal_rec_clk,      
+          reconfig_clk        => cal_rec_clk,
+     
+          -- Clocks, generated (out)
+          sl(tx_clkout)       => i_tx_clk(i),   
+          sl(rx_clkout)       => i_rx_clk(i), 
+  
+          -- Parallel data I/O
+          rx_dataout          => rx_dataout(i), 
+          tx_datain           => tx_datain(i), 
+  
+          -- Serial data I/O 
+          rx_datain           => slv(rx_datain(i)),  
+          sl(tx_dataout)      => tx_dataout(i),
+  
+          -- Initialization I/O
+          sl(rx_freqlocked)   => rx_freq_locked(i),
+          sl(pll_locked)      => tx_pll_locked(i),
+          pll_powerdown       => slv(trc_tx_pll_powerdown),  
+          rx_digitalreset     => slv(trc_rx_digital_rst),                  
+          rx_analogreset      => slv(trc_rx_analog_rst),
+          tx_digitalreset     => slv(trc_tx_digital_rst),
+  
+          -- 8b/10b related
+          tx_ctrlenable       => txc_tx_ctrlenable(i), --8b10b
+          rx_ctrldetect       => rxc_rx_ctrldetect(i), --8b10b
+   
+          -- Reconfig block connections
+          reconfig_togxb      => reconfig_togxb,
+          reconfig_fromgxb    => reconfig_fromgxb(c_reconf_fromgxb_bus_w*(i+1)-1 DOWNTO c_reconf_fromgxb_bus_w*(i+1)-c_reconf_fromgxb_bus_w)
+        );  
+      END GENERATE;
+    END GENERATE;    
+    
+    gen_rx : IF g_tx = FALSE AND g_rx = TRUE GENERATE  --Generate receivers only
+
+      gen_32b : IF g_data_w = 32 GENERATE
+        u_rx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_rx_generic
+        GENERIC MAP (
+          g_mbps                   => g_mbps,
+          starting_channel_number  => i*4  --Starting channel numbers must be 0,4,8,12 etc for individual ALTGX instances     
+        )                                  --Reconfig megawizard: regenerate with 'number of channels' = 4*nof_gx
+        PORT MAP (   
+          cal_blk_clk         => cal_rec_clk,
+          gxb_powerdown       => (OTHERS=>'0'),
+          reconfig_clk        => cal_rec_clk,
+          reconfig_togxb      => reconfig_togxb,
+          rx_analogreset      => slv(trc_rx_analog_rst),
+          rx_datain           => slv(rx_datain(i)),
+          rx_digitalreset     => slv(trc_rx_digital_rst),
+          reconfig_fromgxb    => reconfig_fromgxb(c_reconf_fromgxb_bus_w*(i+1)-1 DOWNTO c_reconf_fromgxb_bus_w*(i+1)-c_reconf_fromgxb_bus_w),
+          sl(rx_clkout)       => i_rx_clk(i),
+          rx_ctrldetect       => rxc_rx_ctrldetect(i),
+          rx_dataout          => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0),
+          sl(rx_freqlocked)   => rx_freq_locked(i),
+          rx_enapatternalign  => slv(rxc_rx_align_en(i)),
+          
+          --ADDITTIONAL SIGNAL:
+          rx_cruclk           => slv(tr_clk)
+        );  
+      END GENERATE;
+
+      gen_16b : IF g_data_w = 16 GENERATE 
+        u_rx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_rx_16b
+        GENERIC MAP (
+          starting_channel_number  => i*4  --Starting channel numbers must be 0,4,8,12 etc for individual ALTGX instances
+        )                                  --Reconfig megawizard: regenerate with 'number of channels' = 4*nof_gx 
+        PORT MAP (   
+          -- Clocks, in
+          cal_blk_clk         => cal_rec_clk,      
+          reconfig_clk        => cal_rec_clk,
+     
+          -- Clocks, generated (out)
+          sl(rx_clkout)       => i_rx_clk(i), 
+  
+          -- Parallel data I/O
+          rx_dataout          => rx_dataout(i), 
+  
+          -- Serial data I/O 
+          rx_datain           => slv(rx_datain(i)),  
+  
+          -- Initialization I/O
+          sl(rx_freqlocked)   => rx_freq_locked(i),
+          rx_digitalreset     => slv(trc_rx_digital_rst),                  
+          rx_analogreset      => slv(trc_rx_analog_rst),
+ 
+          -- 8b/10b related
+          rx_ctrldetect       => rxc_rx_ctrldetect(i), --8b10b
+   
+          -- Reconfig block connections
+          reconfig_togxb      => reconfig_togxb,
+          reconfig_fromgxb    => reconfig_fromgxb(c_reconf_fromgxb_bus_w*(i+1)-1 DOWNTO c_reconf_fromgxb_bus_w*(i+1)-c_reconf_fromgxb_bus_w),
+
+          --ADDITTIONAL SIGNAL:
+          rx_cruclk           => slv(tr_clk)
+        );  
+      END GENERATE;
+    END GENERATE;
+    
+    gen_tx : IF g_tx = TRUE AND g_rx = FALSE GENERATE
+      gen_32b : IF g_data_w = 32 GENERATE
+        u_tx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_tx_generic
+        GENERIC MAP (
+           g_mbps             => g_mbps
+        )  
+        PORT MAP (   
+          cal_blk_clk         => cal_rec_clk,
+          gxb_powerdown       => (OTHERS=>'0'),
+          pll_inclk           => tr_clk,
+          pll_powerdown       => slv(trc_tx_pll_powerdown),
+          tx_ctrlenable       => txc_tx_ctrlenable(i),
+          tx_datain           => tx_datain(i),
+          tx_digitalreset     => slv(trc_tx_digital_rst),
+          sl(pll_locked)      => tx_pll_locked(i),
+          sl(tx_clkout)       => i_tx_clk(i),     
+          sl(tx_dataout)      => tx_dataout(i)
+        );  
+      END GENERATE; 
+
+      gen_16b : IF g_data_w = 16 GENERATE 
+        u_tx: ENTITY ip_stratixiv_hssi_lib.ip_stratixiv_hssi_tx_16b
+        PORT MAP (   
+          -- Clocks, in
+          pll_inclk           => tr_clk,  
+          cal_blk_clk         => cal_rec_clk,      
+     
+          -- Clocks, generated (out)
+          sl(tx_clkout)       => i_tx_clk(i),   
+  
+          -- Parallel data I/O
+          tx_datain           => tx_datain(i), 
+  
+          -- Serial data I/O 
+          sl(tx_dataout)      => tx_dataout(i),
+  
+          -- Initialization I/O
+          sl(pll_locked)      => tx_pll_locked(i),
+          pll_powerdown       => slv(trc_tx_pll_powerdown),                
+          tx_digitalreset     => slv(trc_tx_digital_rst),
+  
+          -- 8b/10b related
+          tx_ctrlenable       => txc_tx_ctrlenable(i) --8b10b   
+        );  
+      END GENERATE;
+    END GENERATE;
+  END GENERATE;
+
+  
+  ------------------------------------------------------------------------------
+  -- Reset and alignment
+  ------------------------------------------------------------------------------
+  
+  u_areset_tr_rst : ENTITY common_lib.common_areset
+  GENERIC MAP(
+    g_rst_level => '1'
+  )
+  PORT MAP(
+    clk    => tr_clk,
+    in_rst => '0',
+    out_rst => tr_rst
+  );  
+
+  gen_tx : IF g_tx = TRUE GENERATE
+ 
+    tx_clk <= i_tx_clk;
+    tx_rst <= i_tx_rst;
+
+    not_trc_tx_rdy <= NOT(trc_tx_rdy);
+
+    u_tech_transceiver_tx_rst : ENTITY work.tech_transceiver_tx_rst
+    GENERIC MAP(
+      g_nof_gx => g_nof_gx
+    )
+    PORT MAP (
+      tr_clk               => tr_clk,
+      tr_rst               => tr_rst,
+      trc_tx_pll_powerdown => trc_tx_pll_powerdown,
+      tx_pll_locked        => tx_pll_locked,
+      trc_tx_digital_rst   => trc_tx_digital_rst,
+      trc_tx_rdy           => trc_tx_rdy
+    );
+
+    gen_altgx: FOR i IN 0 to g_nof_gx-1 GENERATE
+
+      u_areset_tx_rst : ENTITY common_lib.common_areset
+      GENERIC MAP(
+        g_rst_level => '1'
+      )
+      PORT MAP(
+        clk     => i_tx_clk(i),
+        in_rst  => not_trc_tx_rdy,
+        out_rst => i_tx_rst(i)
+      );
+      
+      -- ALTGX in 16-bit mode supports and uses internal auto alignment state machine.
+      gen_tx_align: IF g_data_w=32 GENERATE
+        u_tech_transceiver_tx_align : ENTITY work.tech_transceiver_tx_align
+        GENERIC MAP(
+          g_sim    => g_sim,
+          g_data_w => g_data_w,
+          g_mbps   => g_mbps
+        )
+        PORT MAP (
+          tx_clk             => i_tx_clk(i), 
+          tx_rst             => i_tx_rst(i),
+          tx_align_en_in     => tx_align_en(i),
+          tx_align_en_out    => tx_align_en_out(i),
+          tx_state           => tx_state(2*i+1 DOWNTO 2*i)
+        );
+      END GENERATE;
+
+      -- TX is ready when it's not sending the alignment pattern
+      tx_siso_arr(i).ready     <= NOT tx_align_en_out(i);
+      tx_siso_arr(i).xon       <= NOT tx_align_en_out(i);
+      tx_datain(i)             <= c_align_pattern WHEN tx_align_en_out(i) = '1' ELSE tx_sosi_arr(i).data(g_data_w-1 DOWNTO 0) WHEN  tx_sosi_arr(i).valid = '1' ELSE c_inval_pattern;
+      txc_tx_ctrlenable(i)     <= (OTHERS=>'1') WHEN tx_align_en_out(i) = '1' ELSE (OTHERS=>'0') WHEN tx_sosi_arr(i).valid = '1' ELSE (OTHERS=>'1');
+
+    END GENERATE;
+  END GENERATE;
+
+  gen_rx : IF g_rx = TRUE GENERATE
+
+    rx_clk <= i_rx_clk;  
+    rx_rst <= i_rx_rst;
+
+    u_tech_transceiver_rx_rst : ENTITY work.tech_transceiver_rx_rst
+    GENERIC MAP(
+      g_nof_gx => g_nof_gx
+    )
+    PORT MAP (
+      tr_clk             => tr_clk,
+      tr_rst             => tr_rst,
+      rec_busy           => rec_busy,
+      rx_freq_locked     => rx_freq_locked,
+      trc_rx_analog_rst  => trc_rx_analog_rst,             
+      trc_rx_digital_rst => trc_rx_digital_rst,  
+      trc_rx_rdy         => trc_rx_rdy
+    );
+
+    not_trc_rx_rdy <= NOT(trc_rx_rdy);
+
+    i_rx_rst_align: FOR i IN 0 to g_nof_gx-1 GENERATE
+
+      u_areset_i_rx_rst : ENTITY common_lib.common_areset
+      GENERIC MAP(
+        g_rst_level => '1'
+      )
+      PORT MAP(
+        clk     => i_rx_clk(i),
+        in_rst  => not_trc_rx_rdy,
+        out_rst => i_rx_rst(i)
+      );
+
+      -- ALTGX in 16-bit mode supports and uses internal auto alignment state machine.
+      gen_rx_align: IF g_data_w=32 GENERATE
+        u_tech_transceiver_rx_align : ENTITY work.tech_transceiver_rx_align
+        GENERIC MAP(
+          g_sim    => g_sim,
+          g_data_w => g_data_w,
+          g_mbps   => g_mbps
+        )
+        PORT MAP (
+          rx_clk             => i_rx_clk(i), 
+          rx_rst             => i_rx_rst(i),
+          rx_align_en_in     => rx_align_en(i),
+          rx_align_en_out    => rxc_rx_align_en(i), 
+          rxc_rx_aligned     => rxc_rx_aligned(i),
+          rx_state           => rx_state(2*i+1 DOWNTO 2*i)
+        );
+
+        -- The transmitters will represent gaps as the control-encoded c_inval pattern
+        rx_sosi_arr(i).valid <= NOT(orv(rxc_rx_ctrldetect(i))) WHEN rxc_rx_aligned(i) = '1' ELSE '0';
+      END GENERATE;
+
+      gen_rx_order: IF g_data_w=16 GENERATE
+        u_tech_transceiver_rx_align : ENTITY work.tech_transceiver_rx_order
+        GENERIC MAP(
+          g_data_w    => g_data_w
+        )
+        PORT MAP (
+          rx_clk       => i_rx_clk(i), 
+          rx_rst       => i_rx_rst(i),
+
+          rx_data_in   => rx_dataout(i),
+          rx_ctrl_in   => rxc_rx_ctrldetect(i),                     
+                              
+          rx_data_out  => rx_sosi_arr(i).data(g_data_w-1 DOWNTO 0),
+          rx_valid_out => rx_sosi_arr(i).valid
+        );
+      END GENERATE;     
+    END GENERATE;
+  END GENERATE;
+
+
+  ------------------------------------------------------------------------------
+  -- ALTGX_RECONFIG Megafunction
+  ------------------------------------------------------------------------------
+    
+  gen_cond_reconfig : IF g_nof_gx = 12 GENERATE  
+    u_reconfig : ENTITY ip_altera_mf_lib.ip_altera_mf_gxb_reconfig_12_stratixiv --Create one reconfig module for all ALTGX instances
+    PORT MAP (
+      reconfig_clk        => cal_rec_clk,
+      reconfig_fromgxb    => reconfig_fromgxb,
+      busy                => rec_busy,
+      reconfig_togxb      => reconfig_togxb
+    );
+  END GENERATE;
+
+  gen_cond_reconfig_8 : IF g_nof_gx = 8 GENERATE  
+    u_reconfig : ENTITY ip_altera_mf_lib.ip_altera_mf_gxb_reconfig_8_stratixiv --Create one reconfig module for all ALTGX instances
+    PORT MAP (
+      reconfig_clk        => cal_rec_clk,
+      reconfig_fromgxb    => reconfig_fromgxb,
+      busy                => rec_busy,
+      reconfig_togxb      => reconfig_togxb
+    );
+  END GENERATE;
+
+  gen_cond_reconfig_4 : IF g_nof_gx = 4 GENERATE  
+    u_reconfig : ENTITY ip_altera_mf_lib.ip_altera_mf_gxb_reconfig_4_stratixiv --Create one reconfig module for all ALTGX instances
+    PORT MAP (
+      reconfig_clk        => cal_rec_clk,
+      reconfig_fromgxb    => reconfig_fromgxb,
+      busy                => rec_busy,
+      reconfig_togxb      => reconfig_togxb
+    );
+  END GENERATE;
+        
+  gen_cond_reconfig_sim : IF g_nof_gx = 2 GENERATE
+    u_reconfig_sim : ENTITY ip_altera_mf_lib.ip_altera_mf_gxb_reconfig_2_stratixiv -- The sim version is meant for 2 transceivers
+    PORT MAP (
+      reconfig_clk        => cal_rec_clk,
+      reconfig_fromgxb    => reconfig_fromgxb,
+      busy                => rec_busy,
+      reconfig_togxb      => reconfig_togxb
+    );
+  END GENERATE;
+
+END str;
+
diff --git a/libraries/technology/transceiver/tech_transceiver_rx_align.vhd b/libraries/technology/transceiver/tech_transceiver_rx_align.vhd
new file mode 100644
index 0000000000..c26c78cafa
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_rx_align.vhd
@@ -0,0 +1,163 @@
+--------------------------------------------------------------------------------
+--
+-- 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 IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.tr_nonbonded_pkg.ALL;
+
+ENTITY tech_transceiver_rx_align IS
+  GENERIC(
+    g_sim    : BOOLEAN;
+    g_data_w : NATURAL;
+    g_mbps   : NATURAL
+  );
+  PORT(      
+    rx_clk             : IN  STD_LOGIC;
+    rx_rst             : IN  STD_LOGIC;
+    rx_align_en_in     : IN  STD_LOGIC;
+    rx_align_en_out    : OUT STD_LOGIC;
+    rxc_rx_aligned     : OUT STD_LOGIC;
+    rx_state           : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
+   );  
+END tech_transceiver_rx_align;
+
+ARCHITECTURE rtl OF tech_transceiver_rx_align IS
+
+  CONSTANT c_rx_clk_freq : NATURAL := (g_mbps / g_data_w) / 10 * 8 *1000000;
+
+  CONSTANT c_timeout_1ms : NATURAL := c_rx_clk_freq/1000;
+  CONSTANT c_timeout_sim : NATURAL := 100;
+  CONSTANT c_timeout     : NATURAL := sel_a_b(g_sim, c_timeout_sim, 200*c_timeout_1ms);
+  CONSTANT c_timeout_w   : NATURAL := ceil_log2(c_timeout);
+
+  TYPE t_state_enum IS (s_init, s_wait, s_word_align, s_deassert_word_align, s_byte_order, s_deassert_byte_order, s_rx_aligned);
+
+  SIGNAL state                    : t_state_enum;
+  SIGNAL nxt_state                : t_state_enum; 
+
+  SIGNAL i_rx_align_en_out        : STD_LOGIC;
+  SIGNAL nxt_rx_align_en_out      : STD_LOGIC;
+
+  SIGNAL i_rxc_rx_aligned         : STD_LOGIC;
+  SIGNAL nxt_rxc_rx_aligned       : STD_LOGIC;
+
+  SIGNAL cycle_cnt                : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
+  SIGNAL nxt_cycle_cnt            : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
+
+  SIGNAL nxt_rx_state             : STD_LOGIC_VECTOR(1 DOWNTO 0);
+  SIGNAL i_rx_state               : STD_LOGIC_VECTOR(1 DOWNTO 0);
+
+BEGIN 
+
+  rx_state <= i_rx_state;
+
+  rx_align_en_out <= i_rx_align_en_out;
+  rxc_rx_aligned  <= i_rxc_rx_aligned;
+ 
+  p_clk : PROCESS(rx_rst, rx_clk)
+  BEGIN
+    IF rx_rst='1' THEN
+      state                <= s_init;  
+      i_rx_align_en_out    <= '0';
+      i_rxc_rx_aligned     <= '0';
+      cycle_cnt            <= (OTHERS=>'0');
+      i_rx_state           <= (OTHERS=>'0');
+    ELSIF rising_edge(rx_clk) THEN
+      state                <= nxt_state;
+      i_rx_align_en_out    <= nxt_rx_align_en_out;
+      i_rxc_rx_aligned     <= nxt_rxc_rx_aligned;
+      cycle_cnt            <= nxt_cycle_cnt;
+      i_rx_state           <= nxt_rx_state;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, i_rx_align_en_out, i_rxc_rx_aligned, cycle_cnt, i_rx_state, rx_align_en_in)
+  BEGIN  
+    nxt_state           <= state;  
+    nxt_rx_align_en_out <= i_rx_align_en_out;
+    nxt_rxc_rx_aligned  <= i_rxc_rx_aligned;
+    nxt_cycle_cnt       <= cycle_cnt;
+    nxt_rx_state        <= i_rx_state;
+ 
+    CASE state IS
+      WHEN s_init => 
+        nxt_state <= s_wait;
+  
+      WHEN s_wait =>
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state     <= s_word_align;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+  
+      WHEN s_word_align =>  -- First assertion of rx_align_en to perform word alignment
+        nxt_rx_state        <= "01";
+        nxt_rx_align_en_out <= '1';
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state     <= s_deassert_word_align;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+  
+      WHEN s_deassert_word_align =>  -- Deasssert rx_align_en, re-assert after delay
+        nxt_rx_align_en_out <= '0';
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state     <= s_byte_order;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+  
+      WHEN s_byte_order => -- Assert rx_align_en a second time to order the bytes
+        nxt_rx_state        <= "10";
+        nxt_rx_align_en_out <= '1';
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state     <= s_deassert_byte_order;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+  
+     WHEN s_deassert_byte_order =>  -- Deasssert rx_align_en
+        nxt_rx_align_en_out <= '0';
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state  <= s_rx_aligned;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+  
+      WHEN s_rx_aligned => -- Asserting rx_aligned on next cycle. 
+        nxt_rx_state        <= "11";
+        nxt_rx_align_en_out <= '0';
+        nxt_rxc_rx_aligned  <= '1';
+        IF rx_align_en_in = '1' THEN
+          nxt_state           <= s_wait;
+          nxt_rxc_rx_aligned  <= '0';
+        END IF;
+  
+      WHEN OTHERS =>
+        nxt_state <= s_init;
+    END CASE;
+  END PROCESS;
+  
+END rtl;
+
diff --git a/libraries/technology/transceiver/tech_transceiver_rx_order.vhd b/libraries/technology/transceiver/tech_transceiver_rx_order.vhd
new file mode 100644
index 0000000000..1f15e0a01a
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_rx_order.vhd
@@ -0,0 +1,106 @@
+--------------------------------------------------------------------------------
+--
+-- 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;
+USE IEEE.STD_LOGIC_1164.ALL; 
+USE common_lib.common_pkg.ALL;
+
+ENTITY tech_transceiver_rx_order IS
+  GENERIC (
+    g_data_w  : NATURAL := 16
+  );
+  PORT (
+    rx_clk       : IN  STD_LOGIC;    
+    rx_rst       : IN  STD_LOGIC;
+
+    rx_data_in   : IN  STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+    rx_ctrl_in   : IN  STD_LOGIC_VECTOR(g_data_w/c_byte_w-1 DOWNTO 0);   
+               
+    rx_data_out  : OUT STD_LOGIC_VECTOR(g_data_w-1 DOWNTO 0);
+    rx_valid_out : OUT STD_LOGIC
+  );
+END ENTITY;
+
+ARCHITECTURE rtl OF tech_transceiver_rx_order IS
+
+  SIGNAL in_hi_dat   : STD_LOGIC_VECTOR(g_data_w/2-1 DOWNTO 0);
+  SIGNAL in_lo_dat   : STD_LOGIC_VECTOR(g_data_w/2-1 DOWNTO 0);
+  SIGNAL in_hi_val   : STD_LOGIC;
+  SIGNAL in_lo_val   : STD_LOGIC;
+
+  SIGNAL nxt_rx_data_out : STD_LOGIC_VECTOR(rx_data_out'RANGE);
+  SIGNAL nxt_rx_valid_out : STD_LOGIC;
+  SIGNAL odd_dat     : STD_LOGIC_VECTOR(in_lo_dat'RANGE);
+  SIGNAL nxt_odd_dat : STD_LOGIC_VECTOR(odd_dat'RANGE);
+  SIGNAL odd_val     : STD_LOGIC;
+  SIGNAL nxt_odd_val : STD_LOGIC;
+
+BEGIN
+
+  in_hi_dat <= rx_data_in(g_data_w-1 DOWNTO g_data_w/2);
+  in_hi_val <= NOT rx_ctrl_in(rx_ctrl_in'HIGH);
+
+  in_lo_dat <= rx_data_in(g_data_w/2-1 DOWNTO 0);
+  in_lo_val <= NOT rx_ctrl_in(rx_ctrl_in'LOW);
+
+  regs: PROCESS (rx_rst, rx_clk)
+  BEGIN
+    IF rx_rst='1' THEN
+      rx_valid_out <= '0';
+      rx_data_out <= (OTHERS => '0');
+      odd_val <= '0';
+      odd_dat <= (OTHERS => '0');
+    ELSIF rising_edge(rx_clk) THEN
+      rx_valid_out <= nxt_rx_valid_out;
+      rx_data_out <= nxt_rx_data_out;
+      odd_val <= nxt_odd_val;
+      odd_dat <= nxt_odd_dat;
+    END IF;
+  END PROCESS;
+
+  odd_proc : PROCESS (in_hi_dat, in_hi_val, in_lo_dat, in_lo_val, odd_dat, odd_val)
+  BEGIN
+    nxt_odd_val <= '0';
+
+    IF in_hi_val = '1' AND in_lo_val = '0' AND odd_val = '0' THEN
+      nxt_odd_val <= '1';
+    ELSIF in_hi_val = '1' AND in_lo_val = '1' AND odd_val = '1' THEN
+      nxt_odd_val <= '1';
+    END IF;
+
+    nxt_odd_dat <= in_hi_dat;
+  END PROCESS;
+
+
+  out_proc : PROCESS (in_hi_dat, in_hi_val, in_lo_dat, in_lo_val, odd_dat, odd_val)
+  BEGIN
+    nxt_rx_valid_out <= (in_hi_val AND in_lo_val) OR (odd_val AND (in_hi_val OR in_lo_val));
+    nxt_rx_data_out <= (OTHERS => '0');
+
+    IF odd_val='0' THEN
+      nxt_rx_data_out(2*g_data_w/2-1 DOWNTO 0) <= in_hi_dat & in_lo_dat;
+    ELSE
+      nxt_rx_data_out(2*g_data_w/2-1 DOWNTO 0) <= in_lo_dat & odd_dat;
+    END IF;
+  END PROCESS;
+
+END rtl;
diff --git a/libraries/technology/transceiver/tech_transceiver_rx_rst.vhd b/libraries/technology/transceiver/tech_transceiver_rx_rst.vhd
new file mode 100644
index 0000000000..97e3f487ec
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_rx_rst.vhd
@@ -0,0 +1,156 @@
+--------------------------------------------------------------------------------
+--
+-- 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 IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+
+ENTITY tech_transceiver_rx_rst IS
+  GENERIC(
+    g_nof_gx           : NATURAL
+  ); 
+  PORT(      
+    tr_clk             : IN  STD_LOGIC;
+    tr_rst             : IN  STD_LOGIC;
+    rec_busy           : IN  STD_LOGIC;  
+    rx_freq_locked     : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    trc_rx_analog_rst  : OUT STD_LOGIC;
+    trc_rx_digital_rst : OUT STD_LOGIC;
+    trc_rx_rdy         : OUT STD_LOGIC
+   );  
+END tech_transceiver_rx_rst;
+
+ARCHITECTURE rtl OF tech_transceiver_rx_rst IS
+
+  -- tLTD_auto: 4us. At 156.25MHz this equals 625 clock cycles.
+  CONSTANT c_ltd_auto   : NATURAL := 625;
+  CONSTANT c_ltd_auto_w : NATURAL := ceil_log2(c_ltd_auto);
+
+  TYPE t_state_enum IS (s_init, s_wait_while_busy, s_wait_for_freq_lock, s_wait_for_tltd_auto, s_rx_rdy);
+
+  SIGNAL state                    : t_state_enum;
+  SIGNAL nxt_state                : t_state_enum; 
+
+  SIGNAL i_trc_rx_digital_rst     : STD_LOGIC;
+  SIGNAL nxt_trc_rx_digital_rst   : STD_LOGIC;
+
+  SIGNAL i_trc_rx_analog_rst      : STD_LOGIC;
+  SIGNAL nxt_trc_rx_analog_rst    : STD_LOGIC;
+
+  SIGNAL i_trc_rx_rdy             : STD_LOGIC;
+  SIGNAL nxt_trc_rx_rdy           : STD_LOGIC;
+
+  SIGNAL cycle_cnt                : STD_LOGIC_VECTOR(c_ltd_auto_w-1 DOWNTO 0);
+  SIGNAL nxt_cycle_cnt            : STD_LOGIC_VECTOR(c_ltd_auto_w-1 DOWNTO 0);
+
+  SIGNAL trc_rx_freq_locked       : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+  SIGNAL trc_rec_busy             : STD_LOGIC;
+
+BEGIN 
+
+  trc_rx_digital_rst   <= i_trc_rx_digital_rst;
+  trc_rx_analog_rst    <= i_trc_rx_analog_rst;
+  trc_rx_rdy           <= i_trc_rx_rdy;
+
+  p_clk : PROCESS(tr_rst, tr_clk)
+  BEGIN
+    IF tr_rst='1' THEN
+      state                <= s_init;  
+      i_trc_rx_analog_rst  <= '1';
+      i_trc_rx_digital_rst <= '1';
+      i_trc_rx_rdy         <= '0';
+      cycle_cnt            <= (OTHERS=>'0');
+    ELSIF rising_edge(tr_clk) THEN
+      state                <= nxt_state;
+      i_trc_rx_digital_rst <= nxt_trc_rx_digital_rst;
+      i_trc_rx_analog_rst  <= nxt_trc_rx_analog_rst;
+      i_trc_rx_rdy         <= nxt_trc_rx_rdy;
+      cycle_cnt            <= nxt_cycle_cnt;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, i_trc_rx_analog_rst, i_trc_rx_digital_rst, i_trc_rx_rdy, cycle_cnt, trc_rec_busy, trc_rx_freq_locked)
+  BEGIN  
+    nxt_state              <= state;  
+    nxt_trc_rx_analog_rst  <= i_trc_rx_analog_rst;
+    nxt_trc_rx_digital_rst <= i_trc_rx_digital_rst;
+    nxt_trc_rx_rdy         <= i_trc_rx_rdy;
+    nxt_cycle_cnt          <= cycle_cnt;
+
+    CASE state IS
+      WHEN s_init => 
+         nxt_state <= s_wait_for_freq_lock;
+       
+      WHEN s_wait_while_busy => -- Make sure there is no ALTGX reconfiguring going on.       
+        IF trc_rec_busy = '0' THEN
+          nxt_state <= s_wait_for_freq_lock;
+        END IF;   
+      
+      WHEN s_wait_for_freq_lock =>  -- Release analog receiver portion and wait for it to lock a an incoming frequency
+        nxt_trc_rx_analog_rst <= '0';
+        IF andv(trc_rx_freq_locked) = '1' THEN
+          nxt_state <= s_wait_for_tltd_auto;
+        END IF; 
+  
+      WHEN s_wait_for_tltd_auto => -- Wait for the parallel clock to be stable
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_ltd_auto, c_ltd_auto_w) THEN
+          nxt_trc_rx_digital_rst <= '0';
+          nxt_state              <= s_rx_rdy;
+        END IF;
+  
+      WHEN s_rx_rdy => -- Transmitter ready to use.
+        nxt_trc_rx_rdy <= '1';
+  
+      WHEN OTHERS =>
+        nxt_state <= s_wait_while_busy;
+    END CASE;
+    
+  END PROCESS;
+  
+  u_async_busy : ENTITY common_lib.common_async
+  GENERIC MAP(
+    g_rst_level => '0'
+  )
+  PORT MAP(
+    rst  => tr_rst,
+    clk  => tr_clk,
+    din  => rec_busy,
+    dout => trc_rec_busy
+  );
+
+  gen_asyncs: FOR i IN 0 TO g_nof_gx-1 GENERATE
+    u_async_rx_freqlocked: ENTITY common_lib.common_async
+      GENERIC MAP(
+        g_rst_level => '0'
+      )
+      PORT MAP(
+        rst  => tr_rst,
+        clk  => tr_clk,
+        din  => rx_freq_locked(i),
+        dout => trc_rx_freq_locked(i)
+      );
+  END GENERATE;
+
+END rtl;
+
diff --git a/libraries/technology/transceiver/tech_transceiver_tx_align.vhd b/libraries/technology/transceiver/tech_transceiver_tx_align.vhd
new file mode 100644
index 0000000000..662fdd72cc
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_tx_align.vhd
@@ -0,0 +1,129 @@
+--------------------------------------------------------------------------------
+--
+-- 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 IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+USE work.tr_nonbonded_pkg.ALL;
+
+ENTITY tech_transceiver_tx_align IS
+  GENERIC(
+    g_sim    : BOOLEAN;
+    g_data_w : NATURAL;
+    g_mbps   : NATURAL
+  );
+  PORT(      
+    tx_clk             : IN  STD_LOGIC;
+    tx_rst             : IN  STD_LOGIC;
+    tx_align_en_in     : IN  STD_LOGIC;
+    tx_align_en_out    : OUT STD_LOGIC;
+    tx_state           : OUT STD_LOGIC_VECTOR(1 DOWNTO 0)
+   );  
+END tech_transceiver_tx_align;
+
+ARCHITECTURE rtl OF tech_transceiver_tx_align IS
+
+  CONSTANT c_tx_clk_freq : NATURAL := (g_mbps / g_data_w) / 10 * 8 *1000000;
+
+  CONSTANT c_timeout_1s  : NATURAL := c_tx_clk_freq;
+  CONSTANT c_timeout_sim : NATURAL := 1000;
+  CONSTANT c_timeout     : NATURAL := sel_a_b(g_sim, c_timeout_sim, 2*c_timeout_1s);
+  CONSTANT c_timeout_w   : NATURAL := ceil_log2(c_timeout);
+
+  TYPE t_state_enum IS (s_init, s_init_send_pattern, s_send_user_data, s_force_pattern);
+
+  SIGNAL state                    : t_state_enum;
+  SIGNAL nxt_state                : t_state_enum; 
+
+  SIGNAL i_tx_align_en            : STD_LOGIC;
+  SIGNAL nxt_tx_align_en          : STD_LOGIC;
+
+  SIGNAL cycle_cnt                : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
+  SIGNAL nxt_cycle_cnt            : STD_LOGIC_VECTOR(c_timeout_w-1 DOWNTO 0);
+
+  SIGNAL nxt_tx_state             : STD_LOGIC_VECTOR(1 DOWNTO 0);
+  SIGNAL i_tx_state               : STD_LOGIC_VECTOR(1 DOWNTO 0);
+
+BEGIN 
+
+  tx_state        <= i_tx_state;
+  tx_align_en_out <= i_tx_align_en;
+ 
+  p_clk : PROCESS(tx_rst, tx_clk)
+  BEGIN
+    IF tx_rst='1' THEN
+      state                <= s_init;  
+      i_tx_align_en        <= '1';
+      cycle_cnt            <= (OTHERS=>'0');
+      i_tx_state           <= (OTHERS=>'0');
+    ELSIF rising_edge(tx_clk) THEN
+      state                <= nxt_state;
+      i_tx_align_en        <= nxt_tx_align_en;
+      cycle_cnt            <= nxt_cycle_cnt;
+      i_tx_state           <= nxt_tx_state;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, i_tx_align_en, cycle_cnt, i_tx_state, tx_align_en_in)
+  BEGIN  
+    nxt_state           <= state;  
+    nxt_tx_align_en     <= i_tx_align_en;
+    nxt_cycle_cnt       <= cycle_cnt;
+    nxt_tx_state        <= i_tx_state;
+ 
+    CASE state IS
+      WHEN s_init => 
+        nxt_state <= s_init_send_pattern;
+       
+      WHEN s_init_send_pattern =>        
+        nxt_tx_align_en <= '1';
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_timeout, c_timeout_w) THEN
+           nxt_state <= s_send_user_data;
+           nxt_cycle_cnt <= (OTHERS=>'0');
+        END IF;
+        nxt_tx_state <= "01";
+      
+      WHEN s_send_user_data => 
+        nxt_tx_align_en <= '0';
+        IF tx_align_en_in = '1' THEN
+          nxt_tx_align_en <= '1';
+          nxt_state <= s_force_pattern;
+        END IF;
+        nxt_tx_state <= "11";
+  
+      WHEN s_force_pattern => 
+        nxt_tx_align_en <= '1';
+        IF tx_align_en_in = '0' THEN
+          nxt_tx_align_en <= '0';
+          nxt_state <= s_send_user_data;
+        END IF;
+        nxt_tx_state <= "10";
+  
+      WHEN OTHERS =>
+        nxt_state <= s_init_send_pattern;
+    END CASE;
+  END PROCESS;
+  
+END rtl;
+
diff --git a/libraries/technology/transceiver/tech_transceiver_tx_rst.vhd b/libraries/technology/transceiver/tech_transceiver_tx_rst.vhd
new file mode 100644
index 0000000000..d59b4367ba
--- /dev/null
+++ b/libraries/technology/transceiver/tech_transceiver_tx_rst.vhd
@@ -0,0 +1,139 @@
+--------------------------------------------------------------------------------
+--
+-- 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 IEEE.NUMERIC_STD.ALL;
+USE common_lib.common_pkg.ALL;
+
+ENTITY tech_transceiver_tx_rst IS
+  GENERIC(
+    g_nof_gx             : NATURAL
+    );
+  PORT(      
+    tr_clk               : IN  STD_LOGIC;
+    tr_rst               : IN  STD_LOGIC;
+    trc_tx_pll_powerdown : OUT STD_LOGIC;
+    tx_pll_locked        : IN  STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+    trc_tx_digital_rst   : OUT STD_LOGIC;
+    trc_tx_rdy           : OUT STD_LOGIC
+   );  
+END tech_transceiver_tx_rst;
+
+ARCHITECTURE rtl OF tech_transceiver_tx_rst IS
+
+  -- The minimum pulse width in to keep trc_tx_pll_powerdown asserted = 1us (stratix iv device datasheet).
+  -- At 156.25Mhz (6.4ns) this takes 156.25 cycles. As a lower data rate increases the tx_clk period,
+  -- we're already on the safe side using this value.
+  CONSTANT c_pll_powerdown   : NATURAL := 157; -- 156.25 cycles
+  CONSTANT c_pll_powerdown_w : NATURAL := ceil_log2(c_pll_powerdown);
+
+  TYPE t_state_enum IS (s_init, s_power_down_pll, s_wait_for_pll_lock, s_trc_tx_rdy);
+
+  SIGNAL state                    : t_state_enum;
+  SIGNAL nxt_state                : t_state_enum; 
+
+  SIGNAL i_trc_tx_pll_powerdown   : STD_LOGIC;
+  SIGNAL nxt_trc_tx_pll_powerdown : STD_LOGIC;
+
+  SIGNAL i_trc_tx_digital_rst     : STD_LOGIC;
+  SIGNAL nxt_trc_tx_digital_rst   : STD_LOGIC;
+
+  SIGNAL i_trc_tx_rdy             : STD_LOGIC;
+  SIGNAL nxt_trc_tx_rdy           : STD_LOGIC;
+
+  SIGNAL cycle_cnt                : STD_LOGIC_VECTOR(c_pll_powerdown_w-1 DOWNTO 0);
+  SIGNAL nxt_cycle_cnt            : STD_LOGIC_VECTOR(c_pll_powerdown_w-1 DOWNTO 0);
+
+  SIGNAL trc_tx_pll_locked        : STD_LOGIC_VECTOR(g_nof_gx-1 DOWNTO 0);
+
+BEGIN 
+
+  trc_tx_pll_powerdown <= i_trc_tx_pll_powerdown;
+  trc_tx_digital_rst   <= i_trc_tx_digital_rst;
+  trc_tx_rdy           <= i_trc_tx_rdy;
+
+  p_clk : PROCESS(tr_rst, tr_clk)
+  BEGIN
+    IF tr_rst='1' THEN
+      state                  <= s_init;  
+      i_trc_tx_pll_powerdown <= '1';
+      i_trc_tx_digital_rst   <= '1';
+      i_trc_tx_rdy           <= '0';
+      cycle_cnt              <= (OTHERS=>'0');
+    ELSIF rising_edge(tr_clk) THEN
+      state                  <= nxt_state;
+      i_trc_tx_pll_powerdown <= nxt_trc_tx_pll_powerdown;
+      i_trc_tx_digital_rst   <= nxt_trc_tx_digital_rst;
+      i_trc_tx_rdy           <= nxt_trc_tx_rdy;
+      cycle_cnt              <= nxt_cycle_cnt;
+    END IF;
+  END PROCESS;
+
+  p_state : PROCESS(state, i_trc_tx_pll_powerdown, i_trc_tx_digital_rst, i_trc_tx_rdy, cycle_cnt, trc_tx_pll_locked)
+  BEGIN  
+    nxt_state                <= state;  
+    nxt_trc_tx_pll_powerdown <= i_trc_tx_pll_powerdown;
+    nxt_trc_tx_digital_rst   <= i_trc_tx_digital_rst;
+    nxt_trc_tx_rdy           <= i_trc_tx_rdy;
+    nxt_cycle_cnt            <= cycle_cnt;
+
+    CASE state IS
+      WHEN s_init => 
+        nxt_state <= s_power_down_pll;     
+    
+      WHEN s_power_down_pll => -- Wait until we're sure the PLL is powered down, then power it up
+        nxt_cycle_cnt <= INCR_UVEC(cycle_cnt, 1); 
+        IF cycle_cnt = TO_UVEC(c_pll_powerdown, c_pll_powerdown_w) THEN
+          nxt_trc_tx_pll_powerdown <= '0'; 
+          nxt_state                <= s_wait_for_pll_lock;
+        END IF;
+  
+      WHEN s_wait_for_pll_lock => -- Wait until PLL is locked    
+        IF andv(trc_tx_pll_locked) = '1' THEN
+          nxt_trc_tx_digital_rst <= '0';
+          nxt_state              <= s_trc_tx_rdy;
+        END IF; 
+    
+      WHEN s_trc_tx_rdy => -- Transmitter ready to use.
+        nxt_trc_tx_rdy <= '1';
+  
+      WHEN OTHERS =>
+        nxt_state <= s_power_down_pll;
+    END CASE;
+  END PROCESS;
+
+  gen_asyncs: FOR i IN 0 TO g_nof_gx-1 GENERATE
+    u_async_pll_locked : ENTITY common_lib.common_async
+    GENERIC MAP(
+      g_rst_level => '0'
+    )
+    PORT MAP(
+      rst  => tr_rst,
+      clk  => tr_clk,
+      din  => tx_pll_locked(i),
+      dout => trc_tx_pll_locked(i)
+    );
+  END GENERATE;
+
+END rtl;
+
-- 
GitLab