From 2835b8ce1fef444c95b4085b567596deee6ab345 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Fri, 28 Oct 2022 08:16:49 +0200
Subject: [PATCH] Multi tb passes.

---
 libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd | 119 +++++++++++++++---
 1 file changed, 101 insertions(+), 18 deletions(-)

diff --git a/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd b/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd
index 8afc5cbad6..a0b834bb4a 100644
--- a/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd
+++ b/libraries/io/eth/tb/vhdl/tb_tb_eth_tester.vhd
@@ -23,36 +23,77 @@
 --
 -- References:
 -- [1] https://support.astron.nl/confluence/display/L2M/L6+FWLIB+Design+Document%3A+ETH+tester+unit+for+1GbE
+-- [2] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Application+header+size+in+Ethernet+packets
 --
 -- Usage:
---   > as 3
+--   > as 8
 --   > run -all
 
 LIBRARY IEEE, diag_lib;
 USE IEEE.std_logic_1164.ALL;
 USE diag_lib.diag_pkg.ALL;
+USE work.tb_eth_tester_pkg.ALL;
 
 ENTITY tb_tb_eth_tester IS
 END tb_tb_eth_tester;
 
 ARCHITECTURE tb OF tb_tb_eth_tester IS
 
-  CONSTANT c_bg_ctrl_rst      : t_diag_block_gen_integer := func_diag_bg_ctrl_slv_to_integer(c_diag_block_gen_rst);
-  CONSTANT c_bg_ctrl_first    : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, 30, 0);  -- for first stream
-  CONSTANT c_bg_ctrl_others   : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, 30, 0);   -- for other streams
-  CONSTANT c_bg_ctrl_len_0    : t_diag_block_gen_integer := ('1', '1', 80, 8, 100, 0, 30, 0);  -- nof octets
-  CONSTANT c_bg_ctrl_len_1    : t_diag_block_gen_integer := ('1', '1', 81, 8, 100, 0, 30, 0);  -- nof octets
-  CONSTANT c_bg_ctrl_len_2    : t_diag_block_gen_integer := ('1', '1', 82, 8, 100, 0, 30, 0);  -- nof octets
-  CONSTANT c_bg_ctrl_len_3    : t_diag_block_gen_integer := ('1', '1', 83, 8, 100, 0, 30, 0);  -- nof octets
+  -- Multi tb
+  CONSTANT c_tb_w       : NATURAL := 50;  -- sufficiently long to fit all tb instances
+  CONSTANT c_tb_end_vec : STD_LOGIC_VECTOR(c_tb_w-1 DOWNTO 0) := (OTHERS=>'1');
+
+  SIGNAL tb_end_vec   : STD_LOGIC_VECTOR(c_tb_w-1 DOWNTO 0) := c_tb_end_vec;
+  SIGNAL tb_end       : STD_LOGIC := '0';
+
+  -- Tb
+  CONSTANT c_eth_clk_MHz   : NATURAL := 125;
+  CONSTANT c_st_clk_MHz    : NATURAL := 200;
+  CONSTANT c_nof_sync      : NATURAL := 3;
+  CONSTANT c_nof_sync_many : NATURAL := 100;
+  CONSTANT c_nof_streams   : NATURAL := 3;
+
+  -- Tx packet size and gap size in octets
+  CONSTANT c_block_len     : NATURAL := 50;  -- BG block length of first stream [0]
+  CONSTANT c_link_len      : NATURAL := func_eth_tester_eth_packet_on_link_length(c_block_len);
+
+  -- For near maximum 1Gbps link rate the c_block_len + c_gap_len_min time
+  -- in the st_clk domain equals c_link_len time in eth_clk domain.
+  CONSTANT c_gap_len_min   : NATURAL := c_link_len * c_st_clk_MHz / c_eth_clk_MHz - c_block_len;
+  CONSTANT c_slot_len_min  : NATURAL := c_block_len + c_gap_len_min;
+
+  -- Choose c_gap_len somewhat larger to have packet link rate < 1 Gbps
+  CONSTANT c_gap_len       : NATURAL := c_gap_len_min * 2;   -- for g_nof_streams = 1
+  CONSTANT c_short_gap     : NATURAL := 10;   -- to cause BG xon/xoff flow control
+  CONSTANT c_zero_gap      : NATURAL := 0;    -- to verify BG ready flow control
+
+  -- Choose c_others_len > c_block_len, so same c_gap_len is suitable to
+  -- keep Ethernet link rate < 1 Gbps
+  CONSTANT c_other_len     : NATURAL := 65;  -- BG block length of other streams [c_nof_streams-1 : 1]
+
+  -- BG ctrl
+  CONSTANT c_high             : NATURAL := c_diag_bg_mem_max_adr;  -- = 2**24
+
+  CONSTANT c_bg_ctrl_rst      : t_diag_block_gen_integer := ('0', '0', 1, 8, c_gap_len, 0, c_high, 0);  -- place holder for unused stream
+
+  CONSTANT c_bg_ctrl_one      : t_diag_block_gen_integer := ('1', '1', c_block_len, 8, c_gap_len, 0, c_high, 0);  -- for first stream
+  CONSTANT c_bg_ctrl_others   : t_diag_block_gen_integer := ('1', '1', c_other_len, 8, c_gap_len, 0, c_high, 0);  -- for other streams
+
+  CONSTANT c_bg_ctrl_len_0    : t_diag_block_gen_integer := ('1', '1', c_block_len+0, 8, c_gap_len, 0, c_high, 0);  -- nof octets
+  CONSTANT c_bg_ctrl_len_1    : t_diag_block_gen_integer := ('1', '1', c_block_len+1, 8, c_gap_len, 0, c_high, 0);  -- nof octets
+  CONSTANT c_bg_ctrl_len_2    : t_diag_block_gen_integer := ('1', '1', c_block_len+2, 8, c_gap_len, 0, c_high, 0);  -- nof octets
+  CONSTANT c_bg_ctrl_len_3    : t_diag_block_gen_integer := ('1', '1', c_block_len+3, 8, c_gap_len, 0, c_high, 0);  -- nof octets
+
+  CONSTANT c_bg_ctrl_multiple_first    : t_diag_block_gen_integer := ('1', '1', c_block_len, 8, c_nof_streams * c_gap_len, 0, c_high, 0);  -- for first stream
+  CONSTANT c_bg_ctrl_multiple_others   : t_diag_block_gen_integer := ('1', '1', c_other_len, 8, c_nof_streams * c_gap_len, 0, c_high, 0);  -- for other streams
 
-  SIGNAL tb_end       : STD_LOGIC := '0';  -- declare tb_end to avoid 'No objects found' error on 'when -label tb_end'
-  
 BEGIN
 
 --  g_tb_index         : NATURAL := 0;  -- use to incremental delay logging from tb instances in tb_tb
---  g_tb_str           : STRING := "";  -- use to distinguish logging from tb instances in tb_tb
+--  g_nof_sync         : NATURAL := 3;  -- number of BG sync intervals to set c_run_time
 --  g_nof_streams      : NATURAL := 2;
 --  g_loopback_eth     : BOOLEAN := FALSE;  -- FALSE = sosi loopback, TRUE = eth loopback
+--  g_eth_sim_level    : NATURAL := 0;  -- when g_loopback_eth = TRUE, then 0 = use IP; 1 = use fast serdes model
 --
 --  -- t_diag_block_gen_integer =
 --  --   sl:  enable
@@ -66,13 +107,55 @@ BEGIN
 --  g_bg_ctrl_first    : t_diag_block_gen_integer := ('1', '1', 50, 8, 100, 0, 30, 0);  -- for first stream
 --  g_bg_ctrl_others   : t_diag_block_gen_integer := ('1', '1', 30, 8, 10, 0, 30, 0)   -- for other streams
 
-  u_one_stream        : ENTITY work.tb_eth_tester GENERIC MAP (0, "tb_one_stream: ",       1, FALSE, c_bg_ctrl_first, c_bg_ctrl_rst);
-  u_multiple_streams  : ENTITY work.tb_eth_tester GENERIC MAP (1, "tb_multiple_streams: ", 3, FALSE, c_bg_ctrl_first, c_bg_ctrl_others);
+  -- Tb instance prefix:
+  -- . st   = streaming Tx-Rx interface
+  -- . sim  = sim_tse Tx-Rx interface
+  -- . tech = tech_tse Tx-Rx interface
+
+  -----------------------------------------------------------------------------
+  -- Single stream
+  -----------------------------------------------------------------------------
+  -- Try different loopback interfaces
+  u_st          : ENTITY work.tb_eth_tester GENERIC MAP (0, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(0));
+  u_sim_tse     : ENTITY work.tb_eth_tester GENERIC MAP (1, c_nof_sync, 1,  TRUE, 1, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(1));
+  u_tech_tse    : ENTITY work.tb_eth_tester GENERIC MAP (2, c_nof_sync, 1,  TRUE, 0, c_bg_ctrl_one, c_bg_ctrl_rst) PORT MAP (tb_end_vec(2));
+
+  -- Try different BG block lengths to verify sosi.empty nof octets in last word
+  u_st_bg_len_0 : ENTITY work.tb_eth_tester GENERIC MAP (10, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_0, c_bg_ctrl_rst) PORT MAP (tb_end_vec(10));
+  u_st_bg_len_1 : ENTITY work.tb_eth_tester GENERIC MAP (11, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_1, c_bg_ctrl_rst) PORT MAP (tb_end_vec(11));
+  u_st_bg_len_2 : ENTITY work.tb_eth_tester GENERIC MAP (12, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_2, c_bg_ctrl_rst) PORT MAP (tb_end_vec(12));
+  u_st_bg_len_3 : ENTITY work.tb_eth_tester GENERIC MAP (13, c_nof_sync, 1, FALSE, 1, c_bg_ctrl_len_3, c_bg_ctrl_rst) PORT MAP (tb_end_vec(13));
+
+  -- Try BG xon/xoff block flow control by using smaller gapsize that would exceed 1 Gbps
+  u_st_bg_flow_control : ENTITY work.tb_eth_tester
+                         GENERIC MAP (20, c_nof_sync, 1, FALSE, 1,
+                                      ('1', '1', c_block_len, 8, c_zero_gap, 0, c_high, 0),
+                                      c_bg_ctrl_rst)
+                         PORT MAP (tb_end_vec(20));
+
+  -----------------------------------------------------------------------------
+  -- Multiple streams
+  -----------------------------------------------------------------------------
+  u_st_multiple_streams : ENTITY work.tb_eth_tester
+                          GENERIC MAP (30, c_nof_sync, c_nof_streams, FALSE, 1,
+                                       c_bg_ctrl_multiple_first,
+                                       c_bg_ctrl_multiple_others)
+                          PORT MAP (tb_end_vec(30));
+
+  u_st_multiple_bg_flow_control : ENTITY work.tb_eth_tester
+                                  GENERIC MAP (31, c_nof_sync_many, c_nof_streams, FALSE, 1,
+                                               ('1', '1', c_block_len, 8, c_short_gap, 0, c_high, 0),
+                                               ('1', '1', c_other_len, 8, c_short_gap, 0, c_high, 0))
+                                  PORT MAP (tb_end_vec(31));
+
+  tb_end <= '1' WHEN tb_end_vec = c_tb_end_vec ELSE '0';
 
-  -- Try different BG block lengths to verify nof octets in last word
-  u_bg_len_0          : ENTITY work.tb_eth_tester GENERIC MAP (10, "tb_bg_len_0: ", 1, FALSE, c_bg_ctrl_len_0, c_bg_ctrl_rst);
-  u_bg_len_1          : ENTITY work.tb_eth_tester GENERIC MAP (11, "tb_bg_len_1: ", 1, FALSE, c_bg_ctrl_len_1, c_bg_ctrl_rst);
-  u_bg_len_2          : ENTITY work.tb_eth_tester GENERIC MAP (12, "tb_bg_len_2: ", 1, FALSE, c_bg_ctrl_len_2, c_bg_ctrl_rst);
-  u_bg_len_3          : ENTITY work.tb_eth_tester GENERIC MAP (13, "tb_bg_len_3: ", 1, FALSE, c_bg_ctrl_len_3, c_bg_ctrl_rst);
+  p_tb_end : PROCESS
+  BEGIN
+    WAIT UNTIL tb_end='1';
+    WAIT FOR 1 ns;
+    REPORT "Multi tb simulation finished." SEVERITY FAILURE;
+    WAIT;
+  END PROCESS;
 
 END tb;
-- 
GitLab