diff --git a/libraries/base/diag/hdllib.cfg b/libraries/base/diag/hdllib.cfg
index 9d2908c37881c121f32ace35a24ee7dba4391efc..10d51293521cf0bbf384b5461308ba2af5a3719a 100644
--- a/libraries/base/diag/hdllib.cfg
+++ b/libraries/base/diag/hdllib.cfg
@@ -14,7 +14,7 @@ synth_files =
     src/vhdl/diag_tx_seq.vhd
     $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_tx_frm.vhd
     src/vhdl/diag_rx_seq.vhd
-    $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_frm_generator.vhd
+    src/vhdl/diag_frm_generator.vhd
     $UNB/Firmware/modules/Lofar/diag/src/vhdl/diag_frm_monitor.vhd
     src/vhdl/mms_diag_tx_seq.vhd
     src/vhdl/mms_diag_rx_seq.vhd
diff --git a/libraries/base/diag/src/vhdl/diag_frm_generator.vhd b/libraries/base/diag/src/vhdl/diag_frm_generator.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e334b8f244d13e69753b84ce0f5f252ae8d7c582
--- /dev/null
+++ b/libraries/base/diag/src/vhdl/diag_frm_generator.vhd
@@ -0,0 +1,187 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2010
+-- 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;
+
+
+-- Purpose: Generate a stream of frames with test sequence data.
+-- Description:
+--   Each frame has g_frame_len words of out_dat. The test data can be PRSG or
+--   COUNTER dependent on diag_sel.
+--   The frame generator is enabled by diag_en. The actual frame rate depends
+--   on the g_sop_period and on out_ready.
+--   The out_ready acts as a data request. During a frame the out_dat is valid
+--   for every active out_ready, to support streaming flow control.
+-- Remark:
+-- . This component can be easily mapped to standard MM and ST interfaces.
+
+
+ENTITY diag_frm_generator IS
+  GENERIC (
+    g_sel         : STD_LOGIC := '1';  -- '0' = PRSG, '1' = COUNTER
+    g_frame_len   : NATURAL := 2;      -- >= 2, test frame length in nof dat words
+    g_sof_period  : NATURAL := 1;      -- >= 1, nof cycles between sop that start a frame, typically >> g_frame_len
+                                       --       to generate frames with idle in between
+    g_frame_cnt_w : NATURAL := 32;
+    g_dat_w       : NATURAL := 16;     -- >= 1, test data width
+    g_symbol_w    : NATURAL := 16;     -- >= 1, and nof_symbols_per_dat = g_dat_w/g_symbol_w, must be an integer
+    g_empty       : NATURAL := 0       -- >= 0 and < nof symbols per dat, 
+  );
+  PORT (
+    rst              : IN  STD_LOGIC;
+    clk              : IN  STD_LOGIC;
+    clken            : IN  STD_LOGIC := '1';
+    
+    -- Static control input (connect via MM or leave open to use default)
+    diag_en          : IN  STD_LOGIC;
+    diag_sel         : IN  STD_LOGIC := g_sel;
+    diag_frame_len   : IN  STD_LOGIC_VECTOR(ceil_log2(g_frame_len)-1 DOWNTO 0) := TO_UVEC(g_frame_len, ceil_log2(g_frame_len));
+    diag_frame_empty : IN  STD_LOGIC_VECTOR(ceil_log2(g_dat_w/g_symbol_w)-1 DOWNTO 0) := TO_UVEC(g_empty, ceil_log2(g_dat_w/g_symbol_w));
+    diag_sof_period  : IN  STD_LOGIC_VECTOR(ceil_log2(g_sof_period)-1 DOWNTO 0) := TO_UVEC(g_sof_period, ceil_log2(g_sof_period));
+    diag_frame_cnt   : OUT STD_LOGIC_VECTOR(g_frame_cnt_w-1 DOWNTO 0);
+    
+    -- ST output
+    out_ready       : IN  STD_LOGIC := '1';                      -- '1' = request ST test data output, '0' = halt ST test data output
+    out_dat         : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);  -- test sequence data
+    out_val         : OUT STD_LOGIC;                             -- '1' when out_data is valid
+    out_sop         : OUT STD_LOGIC;                             -- '1' for first valid frame data
+    out_eop         : OUT STD_LOGIC;                             -- '1' for last  valid frame data
+    out_empty       : OUT STD_LOGIC_VECTOR(ceil_log2(g_dat_w/g_symbol_w)-1 DOWNTO 0)  -- nof empty symbols in last out_dat word marked by out_eop
+  );
+END diag_frm_generator;
+
+
+ARCHITECTURE str OF diag_frm_generator IS
+
+  CONSTANT c_init           : NATURAL := 0;  -- first data word of first frame that is generated after diag_en = '1'
+  CONSTANT c_frame_len_w    : NATURAL := ceil_log2(g_frame_len);
+  
+  SIGNAL diag_en_revt       : STD_LOGIC;
+  SIGNAL diag_dat           : STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0) := TO_UVEC(c_init, g_dat_w);  -- init data for out_dat when diag_sop = '1'
+  SIGNAL nxt_diag_dat       : STD_LOGIC_VECTOR(diag_dat'RANGE);
+  SIGNAL diag_sop           : STD_LOGIC;
+  SIGNAL diag_ready         : STD_LOGIC;
+  
+  SIGNAL frame_cnt          : STD_LOGIC_VECTOR(diag_frame_cnt'RANGE);
+  SIGNAL nxt_diag_frame_cnt : STD_LOGIC_VECTOR(diag_frame_cnt'RANGE);
+  
+  SIGNAL i_out_sop          : STD_LOGIC;
+  SIGNAL i_out_eop          : STD_LOGIC;
+  
+BEGIN
+
+  out_sop   <= i_out_sop;
+  out_eop   <= i_out_eop;
+  out_empty <= diag_frame_empty;
+  
+  -- Signal begin of diag_en
+  u_diag_en_revt : ENTITY common_lib.common_evt
+  GENERIC MAP (
+    g_evt_type => "RISING",
+    g_out_reg  => FALSE
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    clken   => clken,
+    in_sig  => diag_en,
+    out_evt => diag_en_revt
+  );
+  
+  p_clk : PROCESS (rst, clk)
+  BEGIN
+    IF rst='1' THEN
+      diag_dat       <= TO_UVEC(c_init, g_dat_w);
+      diag_frame_cnt <= (OTHERS=>'0');
+    ELSIF rising_edge(clk) THEN
+      IF clken='1' THEN
+        diag_dat       <= nxt_diag_dat;
+        diag_frame_cnt <= nxt_diag_frame_cnt;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  nxt_diag_dat <= TO_UVEC(c_init, g_dat_w) WHEN diag_en='0' ELSE INCR_UVEC(diag_dat, 1) WHEN i_out_sop='1';
+  
+  u_pulse_sop : ENTITY common_lib.common_pulser
+  GENERIC MAP (
+    g_pulse_period => g_sof_period
+  )
+  PORT MAP (
+    rst            => rst,
+    clk            => clk,
+    clken          => clken,
+    pulse_period   => diag_sof_period,
+    pulse_en       => diag_en,
+    pulse_clr      => diag_en_revt,
+    pulse_out      => diag_sop
+  );
+  
+  -- Hold last frame count also when the generator is disabled, clear when it is restarted
+  nxt_diag_frame_cnt <= (OTHERS=>'0') WHEN diag_en_revt='1' ELSE frame_cnt;
+    
+  u_frm_cnt : ENTITY common_lib.common_counter
+  GENERIC MAP (
+    g_width     => g_frame_cnt_w
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    clken   => clken,
+    cnt_clr => diag_en_revt,
+    cnt_en  => i_out_eop,
+    count   => frame_cnt
+  );  
+    
+  u_tx_frm : ENTITY work.diag_tx_frm
+  GENERIC MAP (
+    g_sel       => g_sel,
+    g_init      => c_init,
+    g_frame_len => g_frame_len,
+    g_dat_w     => g_dat_w
+  )
+  PORT MAP (
+    rst            => rst,
+    clk            => clk,
+    clken          => clken,
+    
+    -- Static control input (connect via MM or leave open to use default)
+    diag_sel       => diag_sel,
+    diag_frame_len => diag_frame_len,
+    
+    -- Dynamic control input (connect via MM or via ST input or leave open to use defaults)
+    diag_ready     => diag_ready,
+    diag_dat       => diag_dat,
+    diag_sop       => diag_sop,
+    
+    -- ST output
+    out_ready      => out_ready,
+    out_dat        => out_dat,
+    out_val        => out_val,
+    out_sop        => i_out_sop,
+    out_eop        => i_out_eop
+  );
+    
+END str;
diff --git a/libraries/base/diag/src/vhdl/diag_tx_frm.vhd b/libraries/base/diag/src/vhdl/diag_tx_frm.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f5cc14a13f5868e597327bff50c59c81afa882ed
--- /dev/null
+++ b/libraries/base/diag/src/vhdl/diag_tx_frm.vhd
@@ -0,0 +1,172 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2010
+-- 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 common_lib.common_lfsr_sequences_pkg.ALL;
+
+-- Purpose: Transmit a frame with PRSG or COUNTER test sequence data.
+-- Description:
+--   The test data can be PRSG or COUNTER dependent on diag_sel.
+--   A frame generation is enabled (started) by diag_sop. It does not need
+--   diag_eop to end the frame generation, because the generator ends itself
+--   when it has generated g_frame_len words of out_dat.
+--   After a test frame has finished then diag_ready with RL=0 is active to
+--   indicate that a new diag_sof can be handled. The next frame will then
+--   immediatly follow the previous frame, so out_sop of new frame direct after
+--   out_eop of previous frame, if allowed by out_ready from the sink.
+--   It is allowed to keep diag_sop continue high or to make diag_sop =
+--   diag_ready, both will result in maximum frame rate.
+--   The out_ready acts as a data request. During a frame the out_dat is valid
+--   for every active out_ready, to support streaming flow control.
+-- Remark:
+-- . This component can be easily mapped to standard MM and ST interfaces.
+
+
+ENTITY diag_tx_frm IS
+  GENERIC (
+    g_sel       : STD_LOGIC := '1';  -- '0' = PRSG, '1' = COUNTER
+    g_init      : NATURAL := 0;      -- default test sequence init value
+    g_frame_len : NATURAL := 2;      -- >= 2, test frame length
+    g_dat_w     : NATURAL := 16      -- >= 1, test data width
+  );
+  PORT (
+    rst            : IN  STD_LOGIC;
+    clk            : IN  STD_LOGIC;
+    clken          : IN  STD_LOGIC := '1';
+    
+    -- Static control input (connect via MM or leave open to use default)
+    diag_sel       : IN  STD_LOGIC := g_sel;
+    diag_frame_len : IN  STD_LOGIC_VECTOR(ceil_log2(g_frame_len)-1 DOWNTO 0) := TO_UVEC(g_frame_len, ceil_log2(g_frame_len));
+    
+    -- Dynamic control input (connect via MM or via ST input or leave open to use defaults)
+    diag_ready     : OUT STD_LOGIC;                             -- '1' when the generator can accept a new diag_sop
+    diag_dat       : IN  STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0) := TO_UVEC(g_init, g_dat_w);  -- init data for out_dat when diag_sop = '1'
+    diag_sop       : IN  STD_LOGIC := '1';                      -- '1' start a frame generation
+    
+    -- ST output
+    out_ready      : IN  STD_LOGIC := '1';                      -- '1' = request ST test data output, '0' = halt ST test data output
+    out_dat        : OUT STD_LOGIC_VECTOR(g_dat_w-1 DOWNTO 0);  -- test sequence data
+    out_val        : OUT STD_LOGIC;                             -- '1' when out_data is valid
+    out_sop        : OUT STD_LOGIC;                             -- '1' for first valid frame data
+    out_eop        : OUT STD_LOGIC                              -- '1' for last  valid frame data
+  );
+END diag_tx_frm;
+
+
+ARCHITECTURE rtl OF diag_tx_frm IS
+
+  CONSTANT c_lfsr_nr          : NATURAL := g_dat_w - c_common_lfsr_first;
+  
+  SIGNAL i_diag_ready    : STD_LOGIC;
+  
+  SIGNAL frm_sop         : STD_LOGIC;  
+  SIGNAL frm_busy        : STD_LOGIC;
+  SIGNAL nxt_frm_busy    : STD_LOGIC;
+  
+  SIGNAL diag_en         : STD_LOGIC;
+  
+  SIGNAL cnt             : STD_LOGIC_VECTOR(diag_frame_len'RANGE);
+  SIGNAL cnt_clr         : STD_LOGIC;
+  SIGNAL cnt_en          : STD_LOGIC;
+  SIGNAL cnt_done        : STD_LOGIC;
+
+  SIGNAL nxt_out_val     : STD_LOGIC;
+  SIGNAL nxt_out_sop     : STD_LOGIC;
+  SIGNAL nxt_out_eop     : STD_LOGIC;
+  
+BEGIN
+
+  diag_ready <= i_diag_ready;
+  
+  p_clk : PROCESS (rst, clk)
+  BEGIN
+    IF rst='1' THEN
+      frm_busy        <= '0';
+      out_val         <= '0';
+      out_sop         <= '0';
+      out_eop         <= '0';
+    ELSIF rising_edge(clk) THEN
+      IF clken='1' THEN
+        frm_busy        <= nxt_frm_busy;
+        out_val         <= nxt_out_val;
+        out_sop         <= nxt_out_sop;
+        out_eop         <= nxt_out_eop;
+      END IF;
+    END IF;
+  END PROCESS;
+  
+  i_diag_ready <= NOT diag_en;
+  
+  -- Use frm_sop to support diag_sop pulse for frame rate control and also
+  -- diag_sop continue high for maximum frame rate.
+  frm_sop <= i_diag_ready AND diag_sop;
+  
+  nxt_frm_busy <= '1' WHEN frm_sop  = '1' ELSE
+                  '0' WHEN cnt_done = '1' ELSE frm_busy;
+                 
+  cnt_clr     <= frm_sop;
+  cnt_en      <= '1' WHEN frm_busy='1' AND out_ready='1' AND UNSIGNED(cnt)<=g_frame_len-1 ELSE '0';
+  cnt_done    <= '1' WHEN frm_busy='1' AND out_ready='1' AND UNSIGNED(cnt) =g_frame_len-1 ELSE '0';
+  
+  -- Distinguish between frm_busy and diag_en to be able to generated frames
+  -- that are output without idle cycles in between. The diag_en therefore
+  -- make uses of the feature of diag_tx_seq that the next sequence data is
+  -- already available at its output when out_val is still '0'.
+  diag_en     <= frm_busy AND NOT cnt_done;
+  
+  nxt_out_val <= cnt_en;
+  nxt_out_sop <= '1' WHEN frm_busy='1' AND out_ready='1' AND UNSIGNED(cnt) =0             ELSE '0';
+  nxt_out_eop <= cnt_done;
+                      
+  u_cnt_len : ENTITY common_lib.common_counter
+  GENERIC MAP (
+    g_width => diag_frame_len'LENGTH
+  )
+  PORT MAP (
+    rst     => rst,
+    clk     => clk,
+    clken   => clken,
+    cnt_clr => cnt_clr,
+    cnt_en  => cnt_en,
+    count   => cnt
+  );
+  
+  u_frame_dat : ENTITY work.diag_tx_seq
+  GENERIC MAP (
+    g_dat_w    => g_dat_w
+  )
+  PORT MAP (
+    rst        => rst,
+    clk        => clk,
+    clken      => clken,
+    diag_en    => diag_en,
+    diag_sel   => diag_sel,
+    diag_dat   => diag_dat,
+    diag_req   => out_ready,
+    out_dat    => out_dat,
+    out_val    => OPEN
+  );
+    
+END rtl;