diff --git a/libraries/base/diag/hdllib.cfg b/libraries/base/diag/hdllib.cfg
index 10d51293521cf0bbf384b5461308ba2af5a3719a..e1dd075816a3c6d3c67197fcd4be47e3821e62a4 100644
--- a/libraries/base/diag/hdllib.cfg
+++ b/libraries/base/diag/hdllib.cfg
@@ -34,7 +34,7 @@ test_bench_files =
     $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_wg_wideband.vhd
     $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_tx_seq.vhd
     $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_rx_seq.vhd
-    $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_tx_frm.vhd
+    tb/vhdl/tb_diag_tx_frm.vhd
     $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_frm_generator.vhd
     $UNB/Firmware/modules/Lofar/diag/tb/vhdl/tb_diag_frm_monitor.vhd
     tb/vhdl/tb_mms_diag_seq.vhd
diff --git a/libraries/base/diag/tb/vhdl/tb_diag_tx_frm.vhd b/libraries/base/diag/tb/vhdl/tb_diag_tx_frm.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9af57b3ee0549937bb388cf4cc1e269ad99c9670
--- /dev/null
+++ b/libraries/base/diag/tb/vhdl/tb_diag_tx_frm.vhd
@@ -0,0 +1,202 @@
+--------------------------------------------------------------------------------
+--
+-- Copyright (C) 2009
+-- 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 tb_diag_tx_frm IS
+END tb_diag_tx_frm;
+
+ARCHITECTURE tb OF tb_diag_tx_frm IS
+
+  CONSTANT c_period      : TIME    := 100 ns;
+  CONSTANT c_nof_cycles  : NATURAL := 83;  -- use prime number to avoid periodicity with sequence data, which can confuse interpretating the data
+  
+  CONSTANT c_sel         : STD_LOGIC := '1';   -- select COUNTER sequence
+  CONSTANT c_init        : NATURAL := 2;       -- test sequence init value
+  CONSTANT c_frame_len   : NATURAL := 20;      -- >= 2, test frame length
+  CONSTANT c_frame_len_w : NATURAL := ceil_log2(c_frame_len);
+  CONSTANT c_dat_w       : NATURAL := c_frame_len_w;
+  
+  SIGNAL rst            : STD_LOGIC;
+  SIGNAL clk            : STD_LOGIC := '1';
+  
+  SIGNAL diag_sel       : STD_LOGIC;
+  SIGNAL diag_frame_len : STD_LOGIC_VECTOR(c_frame_len_w-1 DOWNTO 0) := TO_UVEC(c_frame_len, c_frame_len_w);
+  SIGNAL diag_dat       : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL diag_ready     : STD_LOGIC;
+  SIGNAL diag_sop       : STD_LOGIC;
+  
+  SIGNAL seq_req        : STD_LOGIC;  
+  SIGNAL seq_dat        : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+  SIGNAL prev_seq_dat   : STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0) := TO_UVEC(c_init+c_frame_len-1, c_dat_w);
+  SIGNAL seq_val        : STD_LOGIC;  
+  SIGNAL seq_sop        : STD_LOGIC;  
+  SIGNAL seq_eop        : STD_LOGIC;  
+
+BEGIN
+
+  rst <= '1', '0' AFTER c_period/10;
+  clk <= NOT clk AFTER c_period/2;
+  
+  stimuli: PROCESS
+  -- run 100 us
+  BEGIN
+    diag_sel <= c_sel;
+    diag_dat <= TO_UVEC(c_init, c_dat_w);
+    diag_sop <= '0';
+    seq_req  <= '1';
+    WAIT FOR 10*c_period;
+    
+    -- Keep seq_req='1'
+    seq_req  <= '1';
+    WAIT FOR c_period;
+    diag_sop  <= '1';                  -- Generate one frame
+    WAIT FOR c_period;
+    diag_sop <= '0';
+    WAIT FOR c_nof_cycles*c_period;
+    WAIT FOR 10*c_period;
+    
+    -- Keep seq_req='1'
+    seq_req  <= '1';
+    diag_dat <= TO_UVEC(0, c_dat_w);
+    WAIT FOR 10*c_period;
+    diag_sop <= '1';                   -- Generate one frame with actual c_init only during diag_sop
+    diag_dat <= TO_UVEC(c_init, c_dat_w);
+    WAIT FOR c_period;
+    diag_sop <= '0';
+    diag_dat <= TO_UVEC(0, c_dat_w);
+    WAIT FOR c_nof_cycles*c_period;
+    WAIT FOR 10*c_period;
+    diag_dat <= TO_UVEC(c_init, c_dat_w);
+    
+    -- Keep diag_sop='1' to immediately request a next frame again
+    seq_req  <= '1';
+    diag_sop <= '1';                   -- Immediatly generate a frame when generator indicates ready
+    FOR I IN 0 TO 3*c_frame_len LOOP
+      WAIT FOR c_period;
+    END LOOP;
+    diag_sop <= '0';
+    WAIT FOR c_frame_len*c_period;
+    WAIT FOR 10*c_period;
+    
+    -- Use diag_ready to immediately request a next frame again
+    seq_req <= '1';
+    FOR I IN 0 TO 3*c_frame_len LOOP
+      diag_sop <= diag_ready;          -- Immediatly generate a frame when generator indicates ready
+      WAIT FOR c_period;
+    END LOOP;
+    diag_sop <= '0';
+    WAIT FOR c_frame_len*c_period;
+    WAIT FOR 10*c_period;
+    
+    -- Toggle seq_req='1'
+    seq_req  <= '1';
+    WAIT FOR c_period;
+    diag_sop  <= '1';                  -- Generate one frame
+    WAIT FOR c_period;
+    diag_sop <= '0';
+    WAIT FOR 10*c_period;
+    seq_req  <= '0';                   -- One inactive request cycle
+    WAIT FOR c_period;
+    seq_req  <= '1';
+    WAIT FOR c_nof_cycles*c_period;
+    WAIT FOR 10*c_period;
+    
+    -- Make seq_req='0' near end of frame
+    seq_req  <= '1';
+    WAIT FOR c_period;
+    diag_sop  <= '1';                  -- Generate one frame
+    WAIT FOR c_period;
+    diag_sop <= '0';
+    WAIT FOR (c_frame_len-1)*c_period;
+    seq_req  <= '0';                   -- Some inactive request cycles
+    WAIT FOR 5*c_period;
+    seq_req  <= '1';
+    WAIT FOR c_nof_cycles*c_period;
+    WAIT FOR 10*c_period;
+    
+    -- Keep diag_sop='1' and make seq_req='0' near end of frame
+    seq_req  <= '1';
+    WAIT FOR c_period;
+    diag_sop <= '1';                   -- Generate one frame
+    WAIT FOR c_period;
+    diag_sop <= '1';
+    WAIT FOR (c_frame_len-1)*c_period;
+    seq_req  <= '0';                   -- Some inactive request cycles
+    WAIT FOR 5*c_period;
+    seq_req  <= '1';
+    WAIT FOR 5*c_period;
+    diag_sop <= '0';
+    WAIT FOR c_nof_cycles*c_period;
+    WAIT FOR 10*c_period;
+    
+    WAIT;
+  END PROCESS;
+  
+  u_diag_tx_frm : ENTITY work.diag_tx_frm
+  GENERIC MAP (
+    g_sel       => c_sel,
+    g_init      => c_init,
+    g_frame_len => c_frame_len,
+    g_dat_w     => c_dat_w
+  )
+  PORT MAP (
+    rst            => rst,
+    clk            => clk,
+    clken          => '1',
+    -- 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      => seq_req,
+    out_dat        => seq_dat,
+    out_val        => seq_val,
+    out_sop        => seq_sop,
+    out_eop        => seq_eop
+  );
+  
+  
+  prev_seq_dat <= seq_dat WHEN rising_edge(clk) AND seq_val='1';
+  
+  p_verify : PROCESS(clk)
+  BEGIN
+    IF rising_edge(clk) THEN
+      IF seq_sop='1' THEN ASSERT seq_val='1' AND UNSIGNED(seq_dat)=c_init               REPORT "Unexpected seq_sop";  END IF;
+      IF seq_eop='1' THEN ASSERT seq_val='1' AND UNSIGNED(seq_dat)=c_init+c_frame_len-1 REPORT "Unexpected seq_eop";  END IF;
+      
+      IF seq_val='1' AND UNSIGNED(seq_dat)=c_init               THEN ASSERT seq_sop='1' REPORT "Missing seq_sop";  END IF;
+      IF seq_val='1' AND UNSIGNED(seq_dat)=c_init+c_frame_len-1 THEN ASSERT seq_eop='1' REPORT "Missing seq_eop";  END IF;
+      
+      IF seq_val='1' AND UNSIGNED(seq_dat)=c_init THEN ASSERT UNSIGNED(prev_seq_dat)=c_init+c_frame_len-1  REPORT "Wrong last seq_dat";  END IF;
+      IF seq_val='1' AND UNSIGNED(seq_dat)>c_init THEN ASSERT UNSIGNED(prev_seq_dat)= UNSIGNED(seq_dat)-1  REPORT "Wrong seq_dat";       END IF;
+    END IF;
+  END PROCESS;
+  
+END tb;
+