From d4c715011cc50b9c1f3688f007f62d119893b67f Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Tue, 9 May 2023 12:42:03 +0200
Subject: [PATCH] Use generics for dp_xonoff generate or not.

---
 .../base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd     | 131 +++++++++++++-----
 1 file changed, 94 insertions(+), 37 deletions(-)

diff --git a/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd b/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd
index fb93beff2e..7188c3417f 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_fifo_xonoff.vhd
@@ -21,18 +21,57 @@
 -- Author: Eric Kooistra
 -- Date: 26 Apr 2023
 -- Purpose:
--- . Test bench for dp_fifos to verify xon flow control when FIFO runs full
+-- . Test bench for dp_fifos to verify xon flow control when FIFO runs full.
+--   The dp_xonoff will discard blocks when its out_siso.xon = '0', to avoid
+--   downstream overflow. The dp_xonoff needs to be applied when the updstream
+--   source does not listen to flow control by siso.ready or by sisi.xon.
 -- 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
+--             g_use_in_xonoff                g_use_out_xonoff
+--   proc          |                              |
+--   dp_gen --> xonoff --> fifo_sc --> mux --> xonoff --> fifo <-- out_siso
+--   frame   |          |  arr      |       |          |  fill
+--           |          |           |       |          |  sc
+--           |          |           |       |          |
+--       bg_sosi_arr    |           |       |          |
+--             fifo_in_sosi_arr     |   mux_out_sosi   |
+--             fifo_in_siso_arr     |   mux_in_siso    |
+--                            mux_in_sosi_arr      fifo_fill_in_sosi
+--                            mux_in_siso_arr      fifo_fill_in_siso
 --
+--   Tb stimuli:
+--   . Enable input in_en after reset for 4*c_tb_nof_clk_cycles and disable it
+--     before tb_end, to read FIFOs empty in c_tb_nof_clk_cycles until tb_end.
+--   . Make external siso.xon = '0' for c_tb_nof_clk_cycles, to check xon flow
+--     control.
+--                    ______________________________________
+--   in_en        ___|                                      |_________
+--                _____________________            ___________________
+--   out_siso.xon                      |__________|
+--
+--   tb_end       ___________________________________________________|
+--
+-- Remark:
+-- . If g_gap_size is too small to fit g_nof_inputs on a multiplexed output,
+--   then g_use_in_xonoff needs to be TRUE to avoid u_in_fifo overflow.
+-- . It appears that the dp_xonoff at the mux output is not needed
+--   (g_use_out_xonoff = FALSE), because siso.ready or siso.xon at dp_xonoff
+--   of BG outputs can provide sufficient flow control to avoid u_out_fifo
+--   overflow.
 -- Usage:
 -- . as 12
 -- . run -all
+-- Observe in Wave Window:
+-- . near BG inputs:
+--   - fifo_in_siso_arr
+--   - dp_out_en_arr, to view dp_xonoff flushing
+--   - in_fifo_usedw_arr in analogue format
+-- . at MUX output:
+--   - fifo_fill_in_siso
+--   - dp_out_en, to view dp_xonoff flushing
+--   - out_fifo_usedw in analogue format
 -- Self test result is OK when there is no FAILURE due to FIFO overflow.
 
 LIBRARY IEEE, common_lib;
@@ -47,10 +86,12 @@ 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
+    g_nof_inputs     : NATURAL := 2;
+    g_nof_blocks     : NATURAL := 500;
+    g_block_size     : NATURAL := 10;
+    g_gap_size       : NATURAL := 0;
+    g_use_in_xonoff  : BOOLEAN := TRUE;
+    g_use_out_xonoff : BOOLEAN := FALSE
   );
 END tb_dp_fifo_xonoff;
 
@@ -61,16 +102,16 @@ ARCHITECTURE tb OF tb_dp_fifo_xonoff IS
 
   CONSTANT c_tb_nof_clk_cycles  : NATURAL := g_nof_blocks * g_block_size;
 
+  -- Use extrnal FIFO for per input of dp_mux
   -- 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_fifo_af_xon        : NATURAL := g_block_size + 50;
 
   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;
@@ -89,6 +130,7 @@ ARCHITECTURE tb OF tb_dp_fifo_xonoff IS
   
   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 dp_out_en_arr     : STD_LOGIC_VECTOR(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);
@@ -96,6 +138,7 @@ ARCHITECTURE tb OF tb_dp_fifo_xonoff IS
 
   SIGNAL mux_out_siso      : t_dp_siso := c_dp_siso_rdy;
   SIGNAL mux_out_sosi      : t_dp_sosi;
+  SIGNAL dp_out_en         : STD_LOGIC;
   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;
@@ -144,17 +187,24 @@ BEGIN
       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)
-    );
+    gen_dp_xonoff : IF g_use_in_xonoff GENERATE
+      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),
+        out_en      => dp_out_en_arr(I)
+      );
+    END GENERATE;
+    no_dp_xonoff : IF NOT g_use_in_xonoff GENERATE
+      fifo_in_sosi_arr <= bg_sosi_arr;
+      dp_out_en_arr <= (OTHERS => '1');
+    END GENERATE;
 
     u_in_fifo : ENTITY work.dp_fifo_sc
     GENERIC MAP (
@@ -183,7 +233,7 @@ BEGIN
     );
   END GENERATE;
 
-  -- Eanble input after reset and disable it before tb_end, to read FIFOs empty
+  -- Enable 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;
 
@@ -219,19 +269,28 @@ BEGIN
   -- 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
---  );
+  gen_dp_xonoff : IF g_use_out_xonoff GENERATE
+    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,
+      out_en      => dp_out_en
+    );
+  END GENERATE;
+  no_dp_xonoff : IF NOT g_use_out_xonoff GENERATE
+    fifo_fill_in_sosi <= mux_out_sosi;
+    mux_out_siso <= fifo_fill_in_siso;
+    dp_out_en <= '1';
+  END GENERATE;
 
   u_out_fifo : ENTITY work.dp_fifo_fill_sc
+  --u_out_fifo : ENTITY work.dp_fifo_fill_eop_sc
   GENERIC MAP (
     g_data_w         => c_data_w,
     g_bsn_w          => c_nof_input_w,
@@ -250,10 +309,8 @@ BEGIN
     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,
+    snk_out     => fifo_fill_in_siso,
+    snk_in      => fifo_fill_in_sosi,
     -- ST source
     src_in      => out_siso,
     src_out     => out_sosi
-- 
GitLab