diff --git a/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd b/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..fb93beff2e1e52c3fcbde9d4e0d5dec28f725289
--- /dev/null
+++ b/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd
@@ -0,0 +1,262 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2023
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-- Author: Eric Kooistra
+-- Date: 26 Apr 2023
+-- Purpose:
+-- . Test bench for dp_fifos to verify xon flow control when FIFO runs full
+-- Description:
+--   Verify that the dp_mux will not cause input FIFO overflow when the input
+--   load is too large for the output capacity.
+--
+--   BG  -> xonoff -> fifo_sc -> mux -> xonoff -> fifo <-- out_siso
+--   arr    arr       arr                         fill
+--                                                sc
+--
+-- Usage:
+-- . as 12
+-- . run -all
+-- Self test result is OK when there is no FAILURE due to FIFO overflow.
+
+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_str_pkg.ALL;
+USE common_lib.common_lfsr_sequences_pkg.ALL;
+USE common_lib.tb_common_pkg.ALL;
+USE work.dp_stream_pkg.ALL;
+USE work.tb_dp_pkg.ALL;
+
+ENTITY tb_dp_fifo_xonoff IS
+  GENERIC (
+    g_nof_inputs  : NATURAL := 5;
+    g_nof_blocks  : NATURAL := 300;
+    g_block_size  : NATURAL := 10;
+    g_gap_size    : NATURAL := 0
+  );
+END tb_dp_fifo_xonoff;
+
+
+ARCHITECTURE tb OF tb_dp_fifo_xonoff IS
+
+  CONSTANT c_clk_period         : TIME := 5 ns;
+
+  CONSTANT c_tb_nof_clk_cycles  : NATURAL := g_nof_blocks * g_block_size;
+
+  -- c_fifo_af_ready >= 4, nof words below max (full) at which fifo is considered almost full for snk_out.ready
+  -- c_fifo_af_xon   >= 0, nof words below max (full) at which fifo is considered almost full for snk_out.xon
+  CONSTANT c_fifo_af_ready      : NATURAL := 4;
+  CONSTANT c_fifo_af_xon        : NATURAL := g_block_size + 5;
+
+  CONSTANT c_in_fifo_size       : NATURAL := g_block_size * 20;
+
+  CONSTANT c_out_fifo_size      : NATURAL := g_block_size * 20;
+  CONSTANT c_out_fifo_fill      : NATURAL := g_block_size;
+  CONSTANT c_out_fifo_af_xon    : NATURAL := g_block_size + 5;
+
+  CONSTANT c_ready_latency      : NATURAL := 1;
+  CONSTANT c_data_w             : NATURAL := 16;
+  CONSTANT c_symbol_w           : NATURAL := c_data_w;
+  CONSTANT c_symbol_init        : NATURAL := 0;
+  CONSTANT c_nof_symbols        : NATURAL := g_block_size;
+  CONSTANT c_bsn                : NATURAL := 0;
+  CONSTANT c_sync               : STD_LOGIC := '0';
+
+  CONSTANT c_nof_input_w        : NATURAL := ceil_log2(g_nof_inputs);
+
+  SIGNAL clk               : STD_LOGIC := '1';
+  SIGNAL rst               : STD_LOGIC := '1';
+  SIGNAL in_en             : STD_LOGIC := '0';
+  SIGNAL tb_end            : STD_LOGIC := '0';
+  
+  SIGNAL bg_siso           : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL bg_sosi_arr       : t_dp_sosi_arr(0 TO g_nof_inputs-1);
+  SIGNAL fifo_in_siso_arr  : t_dp_siso_arr(0 TO g_nof_inputs-1);
+  SIGNAL fifo_in_sosi_arr  : t_dp_sosi_arr(0 TO g_nof_inputs-1);
+  SIGNAL mux_in_siso_arr   : t_dp_siso_arr(0 TO g_nof_inputs-1);
+  SIGNAL mux_in_sosi_arr   : t_dp_sosi_arr(0 TO g_nof_inputs-1);
+
+  SIGNAL mux_out_siso      : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL mux_out_sosi      : t_dp_sosi;
+  SIGNAL fifo_fill_in_siso : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL fifo_fill_in_sosi : t_dp_sosi;
+  SIGNAL out_siso          : t_dp_siso := c_dp_siso_rdy;
+  SIGNAL out_sosi          : t_dp_sosi;
+
+  -- Monitor FIFO filling
+  TYPE t_in_fifo_usedw_slv_arr IS ARRAY (INTEGER RANGE <>) OF STD_LOGIC_VECTOR(ceil_log2(c_out_fifo_size)-1 DOWNTO 0);
+
+  SIGNAL in_fifo_wr_ful_arr  : STD_LOGIC_VECTOR(0 TO g_nof_inputs-1);
+  SIGNAL in_fifo_usedw_arr   : t_in_fifo_usedw_slv_arr(0 TO g_nof_inputs-1);
+  SIGNAL in_fifo_rd_emp_arr  : STD_LOGIC_VECTOR(0 TO g_nof_inputs-1);
+  SIGNAL out_fifo_wr_ful     : STD_LOGIC;
+  SIGNAL out_fifo_usedw      : STD_LOGIC_VECTOR(ceil_log2(c_out_fifo_size)-1 DOWNTO 0);
+  SIGNAL out_fifo_rd_emp     : STD_LOGIC;
+
+BEGIN
+  
+  ------------------------------------------------------------------------------
+  -- Clock & reset
+  ------------------------------------------------------------------------------
+  clk <= (NOT clk) OR tb_end AFTER c_clk_period/2;
+  rst <= '1', '0' AFTER c_clk_period*7;
+
+  ------------------------------------------------------------------------------
+  -- Stimuli: 
+  ------------------------------------------------------------------------------
+  gen_bg_arr : FOR I IN 0 TO g_nof_inputs-1 GENERATE
+    p_bg_arr : PROCESS
+    BEGIN
+      WHILE TRUE LOOP
+        proc_dp_gen_frame(c_ready_latency,
+                          c_data_w,
+                          c_symbol_w,
+                          c_symbol_init,
+                          c_nof_symbols,
+                          c_bsn + I,  -- use bsn to identify the inputs
+                          c_sync,
+                          clk,
+                          in_en,
+                          bg_siso,
+                          bg_sosi_arr(I));
+        WAIT FOR g_gap_size * c_clk_period;
+      END LOOP;
+      -- Use WHILE LOOP and WAIT to avoid warning (vcom-1090) Possible infinite loop:
+      -- Process contains no WAIT statement.
+      WAIT;
+    END PROCESS;
+
+    u_dp_xonoff : ENTITY work.dp_xonoff
+    PORT MAP (
+      rst         => rst,
+      clk         => clk,
+      -- Frame in
+      in_siso     => OPEN,
+      in_sosi     => bg_sosi_arr(I),
+      -- Frame out
+      out_siso    => fifo_in_siso_arr(I),
+      out_sosi    => fifo_in_sosi_arr(I)
+    );
+
+    u_in_fifo : ENTITY work.dp_fifo_sc
+    GENERIC MAP (
+      g_data_w         => c_data_w,
+      g_bsn_w          => c_nof_input_w,
+      g_use_bsn        => TRUE,  -- use bsn to identify the inputs
+      g_use_ctrl       => TRUE,  -- sop & eop
+      g_fifo_size      => c_in_fifo_size,
+      g_fifo_af_margin => c_fifo_af_ready,
+      g_fifo_af_xon    => c_fifo_af_xon,
+      g_fifo_rl        => c_ready_latency
+    )
+    PORT MAP (
+      rst         => rst,
+      clk         => clk,
+      -- Monitor FIFO filling
+      wr_ful      => in_fifo_wr_ful_arr(I),
+      usedw       => in_fifo_usedw_arr(I),
+      rd_emp      => in_fifo_rd_emp_arr(I),
+      -- ST sink
+      snk_out     => fifo_in_siso_arr(I),  -- flush control via out_siso.xon
+      snk_in      => fifo_in_sosi_arr(I),
+      -- ST source
+      src_in      => mux_in_siso_arr(I),
+      src_out     => mux_in_sosi_arr(I)
+    );
+  END GENERATE;
+
+  -- Eanble input after reset and disable it before tb_end, to read FIFOs empty
+  in_en <= '0', '1' AFTER c_clk_period*17,
+                '0' AFTER 4 * c_tb_nof_clk_cycles * c_clk_period;
+
+  -- Also verify toggling external siso.xon flow control
+  out_siso.xon <= '1',
+                  '0' AFTER 2 * c_tb_nof_clk_cycles * c_clk_period,
+                  '1' AFTER 3 * c_tb_nof_clk_cycles * c_clk_period;
+
+  -- End test
+  tb_end <= '0', '1' AFTER 5 * c_tb_nof_clk_cycles * c_clk_period;
+
+  ------------------------------------------------------------------------------
+  -- Multiplexer
+  ------------------------------------------------------------------------------
+  u_dp_mux : ENTITY work.dp_mux
+  GENERIC MAP (
+    g_nof_input   => g_nof_inputs,
+    g_fifo_size   => array_init(1024, g_nof_inputs),  -- must match g_nof_input, even when g_use_fifo=FALSE
+    g_fifo_fill   => array_init(   0, g_nof_inputs)   -- must match g_nof_input, even when g_use_fifo=FALSE
+  )
+  PORT MAP (
+    rst         => rst,
+    clk         => clk,
+    -- ST sinks
+    snk_out_arr => mux_in_siso_arr,
+    snk_in_arr  => mux_in_sosi_arr,
+    -- ST source
+    src_in      => mux_out_siso,
+    src_out     => mux_out_sosi
+  );
+
+  ------------------------------------------------------------------------------
+  -- Output
+  ------------------------------------------------------------------------------
+
+--  u_dp_xonoff : ENTITY work.dp_xonoff
+--  PORT MAP (
+--    rst         => rst,
+--    clk         => clk,
+--    -- Frame in
+--    in_siso     => mux_out_siso,
+--    in_sosi     => mux_out_sosi,
+--    -- Frame out
+--    out_siso    => fifo_fill_in_siso,
+--    out_sosi    => fifo_fill_in_sosi
+--  );
+
+  u_out_fifo : ENTITY work.dp_fifo_fill_sc
+  GENERIC MAP (
+    g_data_w         => c_data_w,
+    g_bsn_w          => c_nof_input_w,
+    g_use_bsn        => TRUE,  -- use bsn to identify the inputs
+    g_fifo_fill      => c_out_fifo_fill,
+    g_fifo_size      => c_out_fifo_size,
+    g_fifo_af_margin => c_fifo_af_ready,
+    g_fifo_af_xon    => c_fifo_af_xon,
+    g_fifo_rl        => c_ready_latency
+  )
+  PORT MAP (
+    rst         => rst,
+    clk         => clk,
+    -- Monitor FIFO filling
+    wr_ful      => out_fifo_wr_ful,
+    usedw       => out_fifo_usedw,
+    rd_emp      => out_fifo_rd_emp,
+    -- ST sink
+    snk_out     => mux_out_siso,
+    snk_in      => mux_out_sosi,
+--    snk_out     => fifo_fill_in_siso,
+--    snk_in      => fifo_fill_in_sosi,
+    -- ST source
+    src_in      => out_siso,
+    src_out     => out_sosi
+  );
+
+END tb;