diff --git a/libraries/base/diag/src/vhdl/diag_pkg.vhd b/libraries/base/diag/src/vhdl/diag_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..16d927402f0bdd6d88d9bc4fc97af187cbf64812
--- /dev/null
+++ b/libraries/base/diag/src/vhdl/diag_pkg.vhd
@@ -0,0 +1,162 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright (C) 2011
+-- 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;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.MATH_REAL.ALL;
+USE common_lib.common_pkg.ALL;
+
+PACKAGE diag_pkg IS
+
+  -----------------------------------------------------------------------------
+  -- PHY interface tests (e.g. for ethernet, transceivers, lvds, memory)
+  -----------------------------------------------------------------------------
+  
+  CONSTANT c_diag_test_mode_no_tst      : NATURAL := 0;   -- no test, the PHY interface runs in normal user mode
+  CONSTANT c_diag_test_mode_loop_local  : NATURAL := 1;   -- loop back via PHY chip
+  CONSTANT c_diag_test_mode_loop_remote : NATURAL := 2;   -- loop back via loopback cable or plug in the connector
+  CONSTANT c_diag_test_mode_tx          : NATURAL := 4;   -- transmit only
+  CONSTANT c_diag_test_mode_rx          : NATURAL := 5;   -- receive only
+  CONSTANT c_diag_test_mode_tx_rx       : NATURAL := 6;   -- transmit and receive
+  
+  CONSTANT c_diag_test_data_lfsr        : NATURAL := 0;   -- use pseudo random data
+  CONSTANT c_diag_test_data_incr        : NATURAL := 1;   -- use incrementing counter data
+  
+  CONSTANT c_diag_test_duration_quick   : NATURAL := 0;   -- end Rx test after 1 data frame or word, end Tx test after correspondingly sufficient data frames or words transmitted, or all memory lines
+  CONSTANT c_diag_test_duration_normal  : NATURAL := 1;   -- idem for e.g. 100 data frames or words, or full memory
+  CONSTANT c_diag_test_duration_extra   : NATURAL := 2;   -- idem for e.g. 100000 data frames or words
+  
+  CONSTANT c_diag_test_result_ok        : NATURAL := 0;   -- test went OK
+  CONSTANT c_diag_test_result_none      : NATURAL := 1;   -- test did not run, default
+  CONSTANT c_diag_test_result_timeout   : NATURAL := 2;   -- test started but no valid data was received
+  CONSTANT c_diag_test_result_error     : NATURAL := 3;   -- test received valid data, but the value was wrong for one or more
+  CONSTANT c_diag_test_result_illegal   : NATURAL := 4;   -- exception, condition that can not occur in the logic
+  
+  
+  -----------------------------------------------------------------------------
+  -- Waveform Generator
+  -----------------------------------------------------------------------------
+  
+  -- control register
+  CONSTANT c_diag_wg_mode_w             : NATURAL :=  8;
+  CONSTANT c_diag_wg_nofsamples_w       : NATURAL := 16;  -- >~ minimum data path block size
+  CONSTANT c_diag_wg_phase_w            : NATURAL := 16;  -- =  c_diag_wg_nofsamples_w
+  CONSTANT c_diag_wg_freq_w             : NATURAL := 31;  -- >> c_diag_wg_nofsamples_w, determines the minimum frequency = Fs / 2**c_diag_wg_freq_w
+  CONSTANT c_diag_wg_ampl_w             : NATURAL := 17;  -- Typically fit DSP multiply 18x18 element so use <= 17, to fit unsigned in 18 bit signed,
+                                                          -- = waveform data width-1 (sign bit) to be able to make a 1 LSBit amplitude sinus
+                                                          
+  CONSTANT c_diag_wg_mode_off           : NATURAL := 0;
+  CONSTANT c_diag_wg_mode_calc          : NATURAL := 1;
+  CONSTANT c_diag_wg_mode_repeat        : NATURAL := 2;
+  CONSTANT c_diag_wg_mode_single        : NATURAL := 3;
+  
+  TYPE t_diag_wg IS RECORD
+    mode        : STD_LOGIC_VECTOR(c_diag_wg_mode_w       -1 DOWNTO 0);
+    nof_samples : STD_LOGIC_VECTOR(c_diag_wg_nofsamples_w -1 DOWNTO 0);  -- unsigned value
+    phase       : STD_LOGIC_VECTOR(c_diag_wg_phase_w      -1 DOWNTO 0);  -- unsigned value
+    freq        : STD_LOGIC_VECTOR(c_diag_wg_freq_w       -1 DOWNTO 0);  -- unsigned value
+    ampl        : STD_LOGIC_VECTOR(c_diag_wg_ampl_w       -1 DOWNTO 0);  -- unsigned value, range [0:2**c_diag_wg_ampl_w> normalized to range [0 c_diag_wg_gain>
+  END RECORD;
+
+  CONSTANT c_diag_wg_ampl_norm          : REAL := 1.0;   -- Use this default amplitude norm = 1.0 when WG data width = WG waveform buffer data width,
+                                                         -- else use extra amplitude unit scaling by (WG data max)/(WG data max + 1)
+  CONSTANT c_diag_wg_gain_w             : NATURAL := 1;  -- Normalized range [0 1>  maps to fixed point range [0:2**c_diag_wg_ampl_w>
+                                                         -- . use gain 2**0             = 1 to have fulle scale without clipping
+                                                         -- . use gain 2**g_calc_gain_w > 1 to cause clipping
+  CONSTANT c_diag_wg_ampl_unit          : REAL := 2**REAL(c_diag_wg_ampl_w-c_diag_wg_gain_w)*c_diag_wg_ampl_norm;  -- ^= Full Scale range [-c_wg_full_scale +c_wg_full_scale] without clipping
+  CONSTANT c_diag_wg_freq_unit          : REAL := 2**REAL(c_diag_wg_freq_w);                                       -- ^= c_clk_freq = Fs (sample frequency), assuming one sinus waveform in the buffer
+  CONSTANT c_diag_wg_phase_unit         : REAL := 2**REAL(c_diag_wg_phase_w)/ 360.0;                               -- ^= 1 degree
+  
+  CONSTANT c_diag_wg_rst : t_diag_wg := (TO_UVEC(c_diag_wg_mode_off, c_diag_wg_mode_w),
+                                         TO_UVEC(              1024, c_diag_wg_nofsamples_w),
+                                         TO_UVEC(                 0, c_diag_wg_phase_w),
+                                         TO_UVEC(                 0, c_diag_wg_freq_w),
+                                         TO_UVEC(                 0, c_diag_wg_ampl_w));
+  
+  TYPE t_diag_wg_arr IS ARRAY (INTEGER RANGE <>) OF t_diag_wg;
+  
+  -----------------------------------------------------------------------------
+  -- Block Generator
+  -----------------------------------------------------------------------------
+  
+  -- control register
+  CONSTANT c_diag_bg_mode_w               : NATURAL :=  8;
+  CONSTANT c_diag_bg_samples_per_packet_w : NATURAL := 16;   
+  CONSTANT c_diag_bg_blocks_per_sync_w    : NATURAL := 24;   
+  CONSTANT c_diag_bg_gapsize_w            : NATURAL := 16;
+  CONSTANT c_diag_bg_mem_low_adrs_w       : NATURAL := 16;  
+  CONSTANT c_diag_bg_mem_high_adrs_w      : NATURAL := 16;  
+  CONSTANT c_diag_bg_bsn_init_w           : NATURAL := 64;
+                                                          
+  TYPE t_diag_block_gen IS RECORD
+    enable             : STD_LOGIC;  -- block enable
+    enable_sync        : STD_LOGIC;  -- block enable on sync pulse
+    samples_per_packet : STD_LOGIC_VECTOR(c_diag_bg_samples_per_packet_w -1 DOWNTO 0);  
+    blocks_per_sync    : STD_LOGIC_VECTOR(c_diag_bg_blocks_per_sync_w    -1 DOWNTO 0);  
+    gapsize            : STD_LOGIC_VECTOR(c_diag_bg_gapsize_w            -1 DOWNTO 0);  
+    mem_low_adrs       : STD_LOGIC_VECTOR(c_diag_bg_mem_low_adrs_w       -1 DOWNTO 0);  
+    mem_high_adrs      : STD_LOGIC_VECTOR(c_diag_bg_mem_high_adrs_w      -1 DOWNTO 0);  
+    bsn_init           : STD_LOGIC_VECTOR(c_diag_bg_bsn_init_w           -1 DOWNTO 0);  
+  END RECORD;   
+  
+  CONSTANT c_diag_block_gen_rst : t_diag_block_gen := (                       '0',      
+                                                                              '0',      
+                                                       TO_UVEC(               256, c_diag_bg_samples_per_packet_w), 
+                                                       TO_UVEC(                10, c_diag_bg_blocks_per_sync_w),      
+                                                       TO_UVEC(               128, c_diag_bg_gapsize_w), 
+                                                       TO_UVEC(                 0, c_diag_bg_mem_low_adrs_w),      
+                                                       TO_UVEC(                 1, c_diag_bg_mem_high_adrs_w), 
+                                                       TO_UVEC(                 0, c_diag_bg_bsn_init_w));      
+  
+  TYPE t_diag_block_gen_arr IS ARRAY (INTEGER RANGE <>) OF t_diag_block_gen;
+ 
+  -- Overloaded sel_a_b (from common_pkg) for t_diag_block_gen
+  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_diag_block_gen) RETURN t_diag_block_gen; 
+
+  -----------------------------------------------------------------------------
+  -- Data buffer
+  -----------------------------------------------------------------------------
+  CONSTANT c_diag_db_max_data_w : NATURAL := 32;
+  
+  TYPE t_diag_data_type_enum IS (
+    e_data,
+    e_complex,           -- im & re
+    e_real,
+    e_imag
+  );        
+  
+END diag_pkg;
+
+PACKAGE BODY diag_pkg IS
+
+  FUNCTION sel_a_b(sel : BOOLEAN; a, b : t_diag_block_gen) RETURN t_diag_block_gen IS
+  BEGIN
+    IF sel = TRUE THEN
+      RETURN a;
+    ELSE
+      RETURN b;
+    END IF;
+  END;
+
+END diag_pkg;
+
+
+