From aa24e599647f9ac7d2d390e5d5f0f185707f34be Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Wed, 17 Mar 2021 18:10:46 +0100
Subject: [PATCH] Read tx_hdr_dat and rx_hdr_dat to understand the byte and
 word order of the header fields in the MM register.

---
 .../base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd   | 176 +++++++++++++++---
 1 file changed, 145 insertions(+), 31 deletions(-)

diff --git a/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd b/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd
index 0856662122..0481f2ff99 100644
--- a/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd
+++ b/libraries/base/dp/tb/vhdl/tb_dp_offload_tx_v3.vhd
@@ -42,7 +42,9 @@ USE common_lib.common_pkg.ALL;
 USE common_lib.common_lfsr_sequences_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE common_lib.common_field_pkg.ALL;
+USE common_lib.common_str_pkg.ALL;
 USE common_lib.tb_common_pkg.ALL;
+USE common_lib.tb_common_mem_pkg.ALL;
 USE work.dp_stream_pkg.ALL;
 USE work.tb_dp_pkg.ALL;
 
@@ -84,7 +86,8 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
   CONSTANT c_expected_pkt_len         : NATURAL := g_pkt_len;
   CONSTANT c_sync_period              : NATURAL := 5;
   CONSTANT c_sync_offset              : NATURAL := 2;
-  
+  CONSTANT c_bsn_init                 : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := TO_DP_BSN(0);
+
   CONSTANT c_hdr_len                  : NATURAL := 7;
   CONSTANT c_wait_last_evt            : NATURAL := 100 + g_nof_repeat * c_hdr_len;
 
@@ -92,36 +95,96 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
   -- Tx offload
   -----------------------------------------------------------------------------
   -- From apertif_udp_offload_pkg.vhd:
-  CONSTANT c_udp_offload_nof_hdr_fields : NATURAL := 3+12+4+3; -- 448b; 7 64b words
-  -- Notes: 
+  CONSTANT c_udp_offload_nof_hdr_fields : NATURAL := 3+12+4+3; -- 22, 448b; 7 64b words
+  CONSTANT c_udp_offload_nof_hdr_words  : NATURAL := 26;       -- 23 single word + 3 double word = 26 32b words
+  -- Notes:
   -- . pre-calculated ip_header_checksum is valid only for UNB0, FN0 targeting IP 10.10.10.10
   -- . udp_total_length = 176 beamlets * 64b / 8b = 1408B + 14 DP bytes + 8 UDP bytes = 1430B 
-  CONSTANT c_udp_offload_hdr_field_arr : t_common_field_arr(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := (
-         ( field_name_pad("eth_dst_mac"            ), "RW", 48, field_default(x"001B214368AC") ),
-         ( field_name_pad("eth_src_mac"            ), "RW", 48, field_default(0) ),
-         ( field_name_pad("eth_type"               ), "RW", 16, field_default(x"0800") ),
-         ( field_name_pad("ip_version"             ), "RW",  4, field_default(4) ),
-         ( field_name_pad("ip_header_length"       ), "RW",  4, field_default(5) ),
-         ( field_name_pad("ip_services"            ), "RW",  8, field_default(0) ),
-         ( field_name_pad("ip_total_length"        ), "RW", 16, field_default(1450) ), 
-         ( field_name_pad("ip_identification"      ), "RW", 16, field_default(0) ),
-         ( field_name_pad("ip_flags"               ), "RW",  3, field_default(2) ),
-         ( field_name_pad("ip_fragment_offset"     ), "RW", 13, field_default(0) ),
-         ( field_name_pad("ip_time_to_live"        ), "RW",  8, field_default(127) ),
-         ( field_name_pad("ip_protocol"            ), "RW",  8, field_default(17) ),
-         ( field_name_pad("ip_header_checksum"     ), "RW", 16, field_default(29928) ),
-         ( field_name_pad("ip_src_addr"            ), "RW", 32, field_default(x"C0A80009") ),
-         ( field_name_pad("ip_dst_addr"            ), "RW", 32, field_default(x"C0A80001") ),
-         ( field_name_pad("udp_src_port"           ), "RW", 16, field_default(0) ), 
-         ( field_name_pad("udp_dst_port"           ), "RW", 16, field_default(0) ), 
-         ( field_name_pad("udp_total_length"       ), "RW", 16, field_default(1430) ),
-         ( field_name_pad("udp_checksum"           ), "RW", 16, field_default(0) ),
-         ( field_name_pad("dp_reserved"            ), "RW", 47, field_default(0) ),
-         ( field_name_pad("dp_sync"                ), "RW",  1, field_default(0) ),
-         ( field_name_pad("dp_bsn"                 ), "RW", 64, field_default(0) ) );
-
-  -- From apertif_unb1_fn_beamformer_udp_offload.vhd:
-  -- Override ('1') only the Ethernet fields so we can use MM defaults there.
+  CONSTANT c_udp_offload_hdr_field_arr : t_common_field_arr(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := ( -- index
+         ( field_name_pad("eth_dst_mac"            ), "RW", 48, field_default(x"001B214368AC") ),         -- 21
+         ( field_name_pad("eth_src_mac"            ), "RW", 48, field_default(x"0123456789AB") ),         -- 20
+         ( field_name_pad("eth_type"               ), "RW", 16, field_default(x"0800") ),                 -- 19
+         ( field_name_pad("ip_version"             ), "RW",  4, field_default(4) ),                       -- 18
+         ( field_name_pad("ip_header_length"       ), "RW",  4, field_default(5) ),                       -- 17
+         ( field_name_pad("ip_services"            ), "RW",  8, field_default(0) ),                       -- 16
+         ( field_name_pad("ip_total_length"        ), "RW", 16, field_default(1450) ),                    -- 15
+         ( field_name_pad("ip_identification"      ), "RW", 16, field_default(0) ),                       -- 14
+         ( field_name_pad("ip_flags"               ), "RW",  3, field_default(2) ),                       -- 13
+         ( field_name_pad("ip_fragment_offset"     ), "RW", 13, field_default(0) ),                       -- 12
+         ( field_name_pad("ip_time_to_live"        ), "RW",  8, field_default(127) ),                     -- 11
+         ( field_name_pad("ip_protocol"            ), "RW",  8, field_default(17) ),                      -- 10
+         ( field_name_pad("ip_header_checksum"     ), "RW", 16, field_default(29928) ),                   -- 9
+         ( field_name_pad("ip_src_addr"            ), "RW", 32, field_default(x"C0A80009") ),             -- 8
+         ( field_name_pad("ip_dst_addr"            ), "RW", 32, field_default(x"C0A80001") ),             -- 7
+         ( field_name_pad("udp_src_port"           ), "RW", 16, field_default(0) ),                       -- 6
+         ( field_name_pad("udp_dst_port"           ), "RW", 16, field_default(0) ),                       -- 5
+         ( field_name_pad("udp_total_length"       ), "RW", 16, field_default(1430) ),                    -- 4
+         ( field_name_pad("udp_checksum"           ), "RW", 16, field_default(0) ),                       -- 3
+         ( field_name_pad("dp_reserved"            ), "RW", 47, field_default(x"010203040506") ),         -- 2
+         ( field_name_pad("dp_sync"                ), "RW",  1, field_default(0) ),                       -- 1
+         ( field_name_pad("dp_bsn"                 ), "RW", 64, field_default(0) ) );                     -- 0
+
+  -- TX: Corresponding storage of c_udp_offload_hdr_field_arr in MM register words
+  -- . Note: It appears that the tx_hdr_word read values are the MM write values, so read of value from logic fields (with MM override '0', e.g. dp_bsn, eth_src_mac) is not supported.
+  CONSTANT c_expected_tx_hdr_word_arr : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words-1) := ( -- word address
+                                                                             X"00000000",     -- 0   = dp_bsn[31:0]        -- readback is MM value, not the logic value
+                                                                             X"00000000",     -- 1   = dp_bsn[63:32]
+                                                                             X"00000000",     -- 2   = dp_sync
+                                                                             X"03040506",     -- 3   = dp_reserved[31:0]
+                                                                             X"00000102",     -- 4   = dp_reserved[47:32]
+                                                                             X"00000000",     -- 5   = udp_checksum
+                                                                             X"00000596",     -- 6   = udp_total_length
+                                                                             X"00000000",     -- 7   = udp_dst_port
+                                                                             X"00000000",     -- 8   = udp_src_port        -- readback is MM value, not the logic value
+                                                                             X"C0A80001",     -- 9   = ip_dst_addr
+                                                                             X"C0A80009",     -- 10  = ip_src_addr
+                                                                             X"000074E8",     -- 11  = ip_header_checksum
+                                                                             X"00000011",     -- 12  = ip_protocol
+                                                                             X"0000007F",     -- 13  = ip_time_to_live
+                                                                             X"00000000",     -- 14  = ip_fragment_offset
+                                                                             X"00000002",     -- 15  = ip_flags
+                                                                             X"00000000",     -- 16  = ip_identification
+                                                                             X"000005AA",     -- 17  = ip_total_length
+                                                                             X"00000000",     -- 18  = ip_services
+                                                                             X"00000005",     -- 19  = ip_header_length
+                                                                             X"00000004",     -- 20  = ip_version
+                                                                             X"00000800",     -- 21  = eth_type[15:0]
+                                                                             X"456789AB",     -- 22  = eth_src_mac[31:0]   -- readback is MM value, not the logic value
+                                                                             X"00000123",     -- 23  = eth_src_mac[47:32]
+                                                                             X"214368AC",     -- 24  = eth_dst_mac[31:0]
+                                                                             X"0000001B");    -- 25  = eth_dst_mac[47:32]
+
+  -- RX: Corresponding storage of c_udp_offload_hdr_field_arr in MM register words
+  CONSTANT c_expected_rx_hdr_word_arr : t_slv_32_arr(0 TO c_udp_offload_nof_hdr_words-1) := ( -- word address
+                                                                             X"0000000B",     -- 0   = dp_bsn[31:0]        -- dynamic value obtained from simulation
+                                                                             X"00000000",     -- 1   = dp_bsn[63:32]
+                                                                             X"00000000",     -- 2   = dp_sync             -- dynamic value obtained from simulation
+                                                                             X"03040506",     -- 3   = dp_reserved[31:0]
+                                                                             X"00000102",     -- 4   = dp_reserved[47:32]
+                                                                             X"00000000",     -- 5   = udp_checksum
+                                                                             X"00000596",     -- 6   = udp_total_length
+                                                                             X"00000000",     -- 7   = udp_dst_port
+                                                                             X"00000000",     -- 8   = udp_src_port
+                                                                             X"C0A80001",     -- 9   = ip_dst_addr
+                                                                             X"C0A80009",     -- 10  = ip_src_addr
+                                                                             X"000074E8",     -- 11  = ip_header_checksum
+                                                                             X"00000011",     -- 12  = ip_protocol
+                                                                             X"0000007F",     -- 13  = ip_time_to_live
+                                                                             X"00000000",     -- 14  = ip_fragment_offset
+                                                                             X"00000002",     -- 15  = ip_flags
+                                                                             X"00000000",     -- 16  = ip_identification
+                                                                             X"000005AA",     -- 17  = ip_total_length
+                                                                             X"00000000",     -- 18  = ip_services
+                                                                             X"00000005",     -- 19  = ip_header_length
+                                                                             X"00000004",     -- 20  = ip_version
+                                                                             X"00000800",     -- 21  = eth_type[15:0]
+                                                                             X"86080000",     -- 22  = eth_src_mac[31:0]   -- readback is the logic value x"00228608" & id_backplane = 0 & id_chip = 0 (c_NODE_ID = 0)
+                                                                             X"00000022",     -- 23  = eth_src_mac[47:32]
+                                                                             X"214368AC",     -- 24  = eth_dst_mac[31:0]
+                                                                             X"0000001B");    -- 25  = eth_dst_mac[47:32]
+
+  -- From apertif_unb1_fn_beamformer_udp_offload.vhd:                                           221   111111111000   0000   000
+  -- Override ('1') only the Ethernet fields so we can use MM defaults there.                   109   876543210987   6543   210
   CONSTANT c_hdr_field_ovr_init : STD_LOGIC_VECTOR(c_udp_offload_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111111"&"1111"&"100";
 
   CONSTANT c_NODE_ID                    : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(0, 8);
@@ -137,7 +200,10 @@ ARCHITECTURE tb OF tb_dp_offload_tx_v3 IS
   
   SIGNAL tx_hdr_fields_in_arr           : t_slv_1024_arr(0 DOWNTO 0);
   SIGNAL tx_hdr_fields_out_arr          : t_slv_1024_arr(0 DOWNTO 0);
-  
+
+  SIGNAL tx_hdr_word                    : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  SIGNAL rx_hdr_word                    : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+
   SIGNAL reg_dp_offload_tx_hdr_dat_mosi : t_mem_mosi := c_mem_mosi_rst;
   SIGNAL reg_dp_offload_tx_hdr_dat_miso : t_mem_miso;
 
@@ -210,6 +276,7 @@ BEGIN
     -- initializations
     g_sync_period    => c_sync_period,
     g_sync_offset    => c_sync_offset,
+    g_bsn_init       => c_bsn_init,
     -- specific
     g_in_dat_w       => g_data_w,
     g_nof_repeat     => g_nof_repeat,
@@ -366,6 +433,29 @@ BEGIN
     hdr_fields_out_arr    => tx_hdr_fields_out_arr
   );
 
+
+  p_rd_tx_hdr_words : PROCESS
+    VARIABLE v_word : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  BEGIN
+    proc_common_wait_until_hi_lo(dp_clk, tx_offload_sosi_arr(0).sync);
+    proc_common_wait_until_hi_lo(dp_clk, tx_offload_sosi_arr(0).sync);
+    print_str("");
+    FOR I IN 0 TO c_udp_offload_nof_hdr_words-1 LOOP
+      proc_mem_mm_bus_rd(I, mm_clk, reg_dp_offload_tx_hdr_dat_mosi);
+      proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+      v_word := reg_dp_offload_tx_hdr_dat_miso.rddata(31 DOWNTO 0);
+      -- Log word in transcript window
+      print_str("tx_hdr_word(" & int_to_str(I) & ") = " & slv_to_hex(v_word));
+      -- View word in wave window
+      tx_hdr_word <= v_word;
+      -- Verify expected word
+      ASSERT c_expected_tx_hdr_word_arr(I) = v_word REPORT "Unexpected tx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_tx_hdr_word_arr(I)) SEVERITY ERROR;
+    END LOOP;
+    print_str("");
+    WAIT;
+  END PROCESS;
+
+
   ------------------------------------------------------------------------------
   -- Link
   ------------------------------------------------------------------------------
@@ -424,7 +514,31 @@ BEGIN
 
   dp_offload_rx_src_in_arr    <= (OTHERS=>c_dp_siso_rdy);
   dp_offload_rx_src_in_arr(0) <= verify_snk_out;
-  
+
+
+  p_rd_rx_hdr_words : PROCESS
+    VARIABLE v_word : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0);
+  BEGIN
+    proc_common_wait_until_hi_lo(dp_clk, verify_snk_in.sync);
+    proc_common_wait_until_hi_lo(dp_clk, verify_snk_in.sync);
+    proc_common_wait_until_hi_lo(dp_clk, verify_snk_in.sync);
+    print_str("");
+    FOR I IN 0 TO c_udp_offload_nof_hdr_words-1 LOOP
+      proc_mem_mm_bus_rd(I, mm_clk, reg_dp_offload_rx_hdr_dat_mosi);
+      proc_mem_mm_bus_rd_latency(c_mem_reg_rd_latency, mm_clk);
+      v_word := reg_dp_offload_rx_hdr_dat_miso.rddata(31 DOWNTO 0);
+      -- Log word in transcript window
+      print_str("rx_hdr_word(" & int_to_str(I) & ") : " & slv_to_hex(v_word));
+      -- View word in wave window
+      rx_hdr_word <= v_word;
+      -- Verify expected word
+      ASSERT c_expected_rx_hdr_word_arr(I) = v_word REPORT "Unexpected rx_hdr_word at address " & int_to_str(I) & ", expected " & slv_to_hex(c_expected_rx_hdr_word_arr(I)) SEVERITY ERROR;
+    END LOOP;
+    print_str("");
+    WAIT;
+  END PROCESS;
+
+
   ------------------------------------------------------------------------------
   -- Auxiliary
   ------------------------------------------------------------------------------
-- 
GitLab