diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.gold b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.gold index b7930ace991471892f2a4bfce04a65da8d21153c..f043831ce7b608b4ba22e11b2b1fee586ff98ad3 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.gold +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.gold @@ -186,8 +186,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x000e8011 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x000e8012 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x000e8013 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x000e8014 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x000e8015 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x000e8014 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x000e8015 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x000e8016 1 RW uint32 b[15:0] - - - - - - - udp_length 0x000e8017 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x000e8018 1 RW uint32 b[15:0] - - - @@ -204,8 +204,8 @@ number_of_columns = 13 - - - - ip_services 0x000e8023 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x000e8024 1 RW uint32 b[3:0] - - - - - - - ip_version 0x000e8025 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x000e8026 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x000e8027 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x000e8026 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x000e8027 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x000e8028 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x000e8029 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x000e802a - - - b[15:0] b[47:32] - - @@ -264,8 +264,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x00128011 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x00128012 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x00128013 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x00128014 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x00128015 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x00128014 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x00128015 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x00128016 1 RW uint32 b[15:0] - - - - - - - udp_length 0x00128017 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x00128018 1 RW uint32 b[15:0] - - - @@ -282,8 +282,8 @@ number_of_columns = 13 - - - - ip_services 0x00128023 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x00128024 1 RW uint32 b[3:0] - - - - - - - ip_version 0x00128025 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x00128026 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x00128027 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x00128026 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x00128027 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00128028 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x00128029 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x0012802a - - - b[15:0] b[47:32] - - @@ -595,8 +595,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x001e0010 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x001e0011 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x001e0012 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x001e0013 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x001e0014 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x001e0013 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x001e0014 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x001e0015 1 RW uint32 b[15:0] - - - - - - - udp_length 0x001e0016 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x001e0017 1 RW uint32 b[15:0] - - - @@ -613,8 +613,8 @@ number_of_columns = 13 - - - - ip_services 0x001e0022 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x001e0023 1 RW uint32 b[3:0] - - - - - - - ip_version 0x001e0024 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x001e0025 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x001e0026 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x001e0025 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x001e0026 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x001e0027 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x001e0028 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x001e0029 - - - b[15:0] b[47:32] - - @@ -644,8 +644,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x00200011 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x00200012 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x00200013 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x00200014 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x00200015 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x00200014 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x00200015 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x00200016 1 RW uint32 b[15:0] - - - - - - - udp_length 0x00200017 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x00200018 1 RW uint32 b[15:0] - - - @@ -662,8 +662,8 @@ number_of_columns = 13 - - - - ip_services 0x00200023 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x00200024 1 RW uint32 b[3:0] - - - - - - - ip_version 0x00200025 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x00200026 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x00200027 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x00200026 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x00200027 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00200028 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x00200029 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x0020002a - - - b[15:0] b[47:32] - - diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.qsys.gold b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.qsys.gold index 112df5030f7541e6bd7cfabc34dfb6040efd2dc0..87fe42da7df062e99457cdfb312af7ec649e47b6 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.qsys.gold +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/lofar2_unb2b_sdp_station.mmap.qsys.gold @@ -186,8 +186,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x00000c51 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x00000c52 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x00000c53 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x00000c54 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x00000c55 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x00000c54 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x00000c55 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x00000c56 1 RW uint32 b[15:0] - - - - - - - udp_length 0x00000c57 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x00000c58 1 RW uint32 b[15:0] - - - @@ -204,8 +204,8 @@ number_of_columns = 13 - - - - ip_services 0x00000c63 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x00000c64 1 RW uint32 b[3:0] - - - - - - - ip_version 0x00000c65 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x00000c66 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x00000c67 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x00000c66 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x00000c67 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00000c68 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x00000c69 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00000c6a - - - b[15:0] b[47:32] - - @@ -264,8 +264,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x00000051 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x00000052 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x00000053 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x00000054 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x00000055 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x00000054 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x00000055 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x00000056 1 RW uint32 b[15:0] - - - - - - - udp_length 0x00000057 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x00000058 1 RW uint32 b[15:0] - - - @@ -282,8 +282,8 @@ number_of_columns = 13 - - - - ip_services 0x00000063 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x00000064 1 RW uint32 b[3:0] - - - - - - - ip_version 0x00000065 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x00000066 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x00000067 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x00000066 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x00000067 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00000068 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x00000069 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x0000006a - - - b[15:0] b[47:32] - - @@ -595,8 +595,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x0004d010 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x0004d011 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x0004d012 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x0004d013 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x0004d014 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x0004d013 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x0004d014 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x0004d015 1 RW uint32 b[15:0] - - - - - - - udp_length 0x0004d016 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x0004d017 1 RW uint32 b[15:0] - - - @@ -613,8 +613,8 @@ number_of_columns = 13 - - - - ip_services 0x0004d022 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x0004d023 1 RW uint32 b[3:0] - - - - - - - ip_version 0x0004d024 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x0004d025 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x0004d026 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x0004d025 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x0004d026 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x0004d027 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x0004d028 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x0004d029 - - - b[15:0] b[47:32] - - @@ -644,8 +644,8 @@ number_of_columns = 13 - - - - sdp_source_info_antenna_band_index 0x00000d91 1 RW uint32 b[15:15] - - - - - - - sdp_station_id 0x00000d92 1 RW uint32 b[15:0] - - - - - - - sdp_observation_id 0x00000d93 1 RW uint32 b[31:0] - - - - - - - - sdp_version_id 0x00000d94 1 RO uint32 b[7:0] - - - - - - - - sdp_marker 0x00000d95 1 RO uint32 b[7:0] - - - + - - - - sdp_version_id 0x00000d94 1 RW uint32 b[7:0] - - - + - - - - sdp_marker 0x00000d95 1 RW uint32 b[7:0] - - - - - - - udp_checksum 0x00000d96 1 RW uint32 b[15:0] - - - - - - - udp_length 0x00000d97 1 RW uint32 b[15:0] - - - - - - - udp_destination_port 0x00000d98 1 RW uint32 b[15:0] - - - @@ -662,8 +662,8 @@ number_of_columns = 13 - - - - ip_services 0x00000da3 1 RW uint32 b[7:0] - - - - - - - ip_header_length 0x00000da4 1 RW uint32 b[3:0] - - - - - - - ip_version 0x00000da5 1 RW uint32 b[3:0] - - - - - - - - eth_type 0x00000da6 1 RO uint32 b[15:0] - - - - - - - - eth_source_mac 0x00000da7 1 RO uint64 b[31:0] b[31:0] - - + - - - - eth_type 0x00000da6 1 RW uint32 b[15:0] - - - + - - - - eth_source_mac 0x00000da7 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00000da8 - - - b[15:0] b[47:32] - - - - - - eth_destination_mac 0x00000da9 1 RW uint64 b[31:0] b[31:0] - - - - - - - 0x00000daa - - - b[15:0] b[47:32] - - diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd index db72ccae4fc97d40718982ba01b4fa0b1862757f..817983875cabf4dde810826b3a5d3acc0902dab7 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd @@ -127,10 +127,6 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin -- header fields - CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0 - CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000 - CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0 CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id @@ -252,8 +248,11 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_bf IS -- MM SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst; SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL rd_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL rd_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL rd_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0); -- WG @@ -609,17 +608,53 @@ BEGIN -- ); v_offset := bset * c_mm_span_reg_hdr_dat; - -- . Use defaults, so no need to write + -- Default destination MAC/IP/UDP = 0 -- . Read + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- . verify read + ASSERT UNSIGNED(rd_cep_eth_src_mac) = 0 REPORT "Wrong MM read rd_cep_eth_src_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_src_addr) = 0 REPORT "Wrong MM read rd_cep_ip_src_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_src_port) = 0 REPORT "Wrong MM read rd_cep_udp_src_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_eth_dst_mac) = 0 REPORT "Wrong MM read rd_cep_eth_dst_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_dst_addr) = 0 REPORT "Wrong MM read rd_cep_ip_dst_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_dst_port) = 0 REPORT "Wrong MM read rd_cep_udp_dst_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + + -- Write tb defaults + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 39, TO_UINT(c_cep_eth_src_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 38, TO_SINT(c_cep_eth_src_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 26, TO_SINT(c_cep_ip_src_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 24, TO_UINT(c_cep_udp_src_port), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 41, TO_UINT(c_sdp_cep_eth_dst_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 40, TO_SINT(c_sdp_cep_eth_dst_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 25, TO_SINT(c_sdp_cep_ip_dst_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 23, TO_UINT(c_sdp_cep_udp_dst_port), tb_clk); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); + + -- . Read back + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); proc_common_wait_some_cycles(tb_clk, 1); - -- verify read - ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0 - ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000 + -- . verify read back + ASSERT rd_cep_eth_src_mac = c_cep_eth_src_mac REPORT "Wrong MM read rd_cep_eth_src_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_src_addr = c_cep_ip_src_addr REPORT "Wrong MM read rd_cep_ip_src_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_src_port = c_cep_udp_src_port REPORT "Wrong MM read rd_cep_udp_src_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; ---------------------------------------------------------------------------- -- Enable beamlet UDP offload (dp_xonoff) @@ -1000,7 +1035,7 @@ BEGIN p_exp_sdp_cep_header : PROCESS(exp_dp_bsn) BEGIN -- eth header - exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac; + exp_sdp_cep_header.eth.dst_mac <= c_sdp_cep_eth_dst_mac; exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac; exp_sdp_cep_header.eth.eth_type <= x"0800"; @@ -1016,11 +1051,11 @@ BEGIN exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w); exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w); exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w - exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w + exp_sdp_cep_header.ip.dst_ip_addr <= c_sdp_cep_ip_dst_addr; -- c_network_ip_addr_w -- udp header exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port; - exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port; + exp_sdp_cep_header.udp.dst_port <= c_sdp_cep_udp_dst_port; exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w); diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index da901213a23fee1782471b330fee9210c8d33a0d..11061969673828bf1d6f69fa944d35f0f5960062 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -26,8 +26,8 @@ -- -- Description: -- This tb is a balance between verification coverage and keeping it simple: --- - Use only one signal input (g_sp). Put same remnant WG signal on the --- other signal inputs. +-- - Use only one signal input (g_sp) with strong WG. Put same remnant weak +-- WG signal on the other signal inputs. -- - Use different BF weight for the two beamlet polarizations (g_bf_x_gain, -- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_sp. -- Using different BF weights for the N_pol_bf = 2 BF polarizations allows @@ -36,9 +36,9 @@ -- The remnant signal inputs and BF weights allow verifying the BF sum if -- they are not 0. Using the same settings for all remnant SP simplyfies -- the tb, while still testing the BF sum. --- - Select one beamlet for the subband (g_beamlet). Selecting one beamlet --- other than the default beamlet for the subband is sufficient to verify --- the beamlet subband select. +-- - Select one beamlet (g_beamlet) for the subband (g_subband). Selecting +-- one beamlet other than the default beamlet for the subband is sufficient +-- to verify the beamlet subband select. -- - Use same stimuli for both beamsets. -- -- MM control actions: @@ -59,8 +59,8 @@ -- 4) Select subband g_subband for beamlets in g_beamlet -- -- 5) Apply BF weight to g_beamlet X beam and Y beam, so for example if g_sp --- = 3, then w_x3 = g_bf_x_gain/phase and w_y3 = = g_bf_x_gain/phase. The --- other BF weights are 0. +-- = 3, then w_x3 = g_bf_x_gain,phase and w_y3 = g_bf_y_gain,phase. The +-- BF weights for all other beamlets (/= g_beamlet) are 0. -- -- WG BF BF -- si weight weight @@ -93,7 +93,6 @@ -- \----------------|---> beamlet_x -- \--> beamlet_y -- --- -- 6) Read and verify beamlet statistics (BST) -- View sp_sst in Wave window -- View bst_x_arr, bst_y_arr in Wave window @@ -109,7 +108,7 @@ -- Usage: -- > as 7 # default -- > as 12 # for detailed debugging --- # Manually add missing signal +-- # Manually add missing signals and constants using objects in GUI -- > add wave -position insertpoint \ -- sim:/tb_lofar2_unb2c_sdp_station_bf/sp_ssts_arr2 \ -- sim:/tb_lofar2_unb2c_sdp_station_bf/bsts_arr2 @@ -154,8 +153,9 @@ ENTITY tb_lofar2_unb2c_sdp_station_bf IS g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp g_bf_remnant_x_gain : REAL := 0.05; -- g_beamlet X BF weight normalized gain for remnant sp g_bf_remnant_y_gain : REAL := 0.04; -- g_beamlet Y BF weight normalized gain for remnant sp - g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp - g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp + g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for remnant sp + g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for remnant sp + g_read_all_sub_sel : BOOLEAN := FALSE; -- when FALSE only read subband selection for g_beamlet, to save sim time g_read_all_SST : BOOLEAN := TRUE; -- when FALSE only read SST for g_subband, to save sim time g_read_all_BST : BOOLEAN := TRUE -- when FALSE only read BST for g_beamlet, to save sim time ); @@ -200,13 +200,9 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin -- header fields - CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0 - CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000 - - CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node - CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id + CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(c_gn_index); + CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(c_gn_index); + CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDE#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window @@ -384,8 +380,11 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS -- MM SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst; SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL rd_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL rd_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL rd_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0); -- WG @@ -409,7 +408,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf IS -- BF -- . beamlet subband selection SIGNAL sp_subband_select : NATURAL := 0; - SIGNAL sp_subband_select_arr : t_natural_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => 0); -- Q_fft = N_pol = 2 + SIGNAL sp_subband_select_arr : t_integer_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => -1); -- Q_fft = N_pol = 2 -- . beamlet X-pol SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(0 TO c_sdp_S_pn-1) := (OTHERS => 0); @@ -632,8 +631,6 @@ BEGIN p_mm_stimuli : PROCESS VARIABLE v_bsn : NATURAL; - VARIABLE v_sp_sst : REAL := 0.0; - VARIABLE v_bst : REAL := 0.0; VARIABLE v_data_lo, v_data_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); VARIABLE v_stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); VARIABLE v_len, v_span, v_offset, v_addr, v_sel : NATURAL; -- address ranges, indices @@ -714,7 +711,7 @@ BEGIN -- . write v_offset := bset * c_mm_span_reg_bf_scale; mmf_mm_bus_wr(c_mm_file_reg_bf_scale, v_offset + 0, c_exp_beamlet_scale, tb_clk); - proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); -- . readback mmf_mm_bus_rd(c_mm_file_reg_bf_scale, v_offset + 0, rd_data, tb_clk); @@ -771,17 +768,54 @@ BEGIN -- ); v_offset := bset * c_mm_span_reg_hdr_dat; - -- . Use defaults, so no need to write + -- Default destination MAC/IP/UDP = 0 -- . Read + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); proc_common_wait_some_cycles(tb_clk, 1); - -- verify read - ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0 - ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000 + -- . verify read + ASSERT UNSIGNED(rd_cep_eth_src_mac) = 0 REPORT "Wrong MM read rd_cep_eth_src_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_src_addr) = 0 REPORT "Wrong MM read rd_cep_ip_src_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_src_port) = 0 REPORT "Wrong MM read rd_cep_udp_src_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_eth_dst_mac) = 0 REPORT "Wrong MM read rd_cep_eth_dst_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_dst_addr) = 0 REPORT "Wrong MM read rd_cep_ip_dst_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_dst_port) = 0 REPORT "Wrong MM read rd_cep_udp_dst_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + + -- Write tb defaults + -- . Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on c_gn_index + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 39, TO_UINT(c_cep_eth_src_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 38, TO_SINT(c_cep_eth_src_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 26, TO_SINT(c_cep_ip_src_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 24, TO_UINT(c_cep_udp_src_port), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 41, TO_UINT(c_sdp_cep_eth_dst_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 40, TO_SINT(c_sdp_cep_eth_dst_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 25, TO_SINT(c_sdp_cep_ip_dst_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 23, TO_UINT(c_sdp_cep_udp_dst_port), tb_clk); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); + + -- . Read back + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- . verify read back + ASSERT rd_cep_eth_src_mac = c_cep_eth_src_mac REPORT "Wrong MM read rd_cep_eth_src_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_src_addr = c_cep_ip_src_addr REPORT "Wrong MM read rd_cep_ip_src_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_src_port = c_cep_udp_src_port REPORT "Wrong MM read rd_cep_udp_src_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; ---------------------------------------------------------------------------- -- Enable BST offload (not verified here, but only for view in Wave window) @@ -819,12 +853,14 @@ BEGIN -- . Put wanted signal on g_sp input and remnant signal on the other inputs FOR S IN 0 TO c_sdp_S_pn-1 LOOP v_offset := S * c_mm_span_reg_diag_wg; - IF s = g_sp THEN + IF S = g_sp THEN + -- Strong WG signal at g_sp mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl ELSE + -- Weak WG signal on all other (remnant) SP mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 1, INTEGER(c_wg_remnant_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees mmf_mm_bus_wr(c_mm_file_reg_diag_wg, v_offset + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq @@ -894,15 +930,18 @@ BEGIN FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP -- Same selection for both beamsets, so fine to use only one sp_subband_select_arr() FOR B IN 0 TO c_sdp_S_sub_bf-1 LOOP - -- Same selection for all SP, so fine to only read subband selection for g_sp - v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; - mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); - v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; - sp_subband_select_arr(B) <= v_sel; - sp_subband_select <= v_sel; -- for time series view in Wave window + IF g_read_all_sub_sel OR B = g_beamlet THEN + -- Same selection for all SP, so fine to only read subband selection for g_sp + v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; + mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); + v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; + sp_subband_select_arr(B * c_sdp_N_pol + v_P) <= v_sel; + sp_subband_select <= v_sel; -- for time series view in Wave window + END IF; END LOOP; END LOOP; proc_common_wait_some_cycles(tb_clk, 1); + ASSERT sp_subband_select_arr(g_beamlet * c_sdp_N_pol + v_P) = g_subband REPORT "Wrong subband select at beamlet index." SEVERITY ERROR; proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window ---------------------------------------------------------------------------- @@ -915,10 +954,11 @@ BEGIN FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP -- Same BF weights for both beamsets FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP - -- Same BF weights for both beamlet polarizations + -- Different BF weights for both beamlet polarizations FOR A IN 0 TO c_sdp_A_pn-1 LOOP FOR P IN 0 TO c_sdp_N_pol-1 LOOP v_S := A * c_sdp_N_pol + P; + -- Different BF weights for g_sp and the remnant sp IF v_S = g_sp THEN -- use generic BF weight for g_sp in g_beamlet IF PB = 0 THEN @@ -934,6 +974,7 @@ BEGIN v_weight := pack_complex(re => c_bf_remnant_y_weight_re, im => c_bf_remnant_y_weight_im, w => c_sdp_W_bf_weight); END IF; END IF; + -- Only need to set BF weight for g_beamlet, keep other beamlet BF weights at zero rst default. v_addr := g_beamlet; -- beamlet index v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset v_addr := v_addr + A * v_span; -- antenna input address offset @@ -1212,71 +1253,15 @@ BEGIN test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit rx_beamlet_sosi -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that - -- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop. + -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop. - exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_eth_dst_mac, - c_cep_eth_src_mac, - c_cep_ip_src_addr, - c_cep_ip_dst_addr, - c_exp_ip_header_checksum, + exp_sdp_cep_header <= func_sdp_compose_cep_header(c_exp_ip_header_checksum, c_exp_sdp_info, c_gn_index, c_exp_beamlet_scale, c_exp_beamlet_index, exp_dp_bsn); - --p_exp_sdp_cep_header : PROCESS(exp_dp_bsn) - --BEGIN - -- -- eth header - -- exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac; - -- exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac; - -- exp_sdp_cep_header.eth.eth_type <= x"0800"; - -- - -- -- ip header - -- exp_sdp_cep_header.ip.version <= TO_UVEC( 4, c_network_ip_version_w); - -- exp_sdp_cep_header.ip.header_length <= TO_UVEC( 5, c_network_ip_header_length_w); - -- exp_sdp_cep_header.ip.services <= TO_UVEC( 0, c_network_ip_services_w); - -- exp_sdp_cep_header.ip.total_length <= c_sdp_cep_ip_total_length; -- 7868, see ICD STAT-CEP - -- exp_sdp_cep_header.ip.identification <= TO_UVEC( 0, c_network_ip_identification_w); - -- exp_sdp_cep_header.ip.flags <= TO_UVEC( 2, c_network_ip_flags_w); - -- exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC( 0, c_network_ip_fragment_offset_w); - -- exp_sdp_cep_header.ip.time_to_live <= TO_UVEC( 127, c_network_ip_time_to_live_w); - -- exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w); - -- exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w); - -- exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w - -- exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w - -- - -- -- udp header - -- exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port; - -- exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port; - -- exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP - -- exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w); - -- - -- -- app header - -- exp_sdp_cep_header.app.sdp_marker <= TO_UVEC(c_sdp_marker_beamlets, 8); -- 98 = x"62" = 'b' - -- exp_sdp_cep_header.app.sdp_version_id <= TO_UVEC(c_sdp_cep_version_id, 8); -- 5 - -- exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id; - -- exp_sdp_cep_header.app.sdp_station_id <= c_exp_sdp_info.station_id; - -- - -- exp_sdp_cep_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index); - -- exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index; - -- exp_sdp_cep_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc); - -- exp_sdp_cep_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type); - -- exp_sdp_cep_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1); - -- exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag); - -- exp_sdp_cep_header.app.sdp_source_info_beamlet_width <= TO_UVEC(c_sdp_W_beamlet, 4); - -- exp_sdp_cep_header.app.sdp_source_info_gn_id <= TO_UVEC(c_gn_index, 5); - -- - -- exp_sdp_cep_header.app.sdp_reserved <= TO_UVEC( 0, 40); - -- exp_sdp_cep_header.app.sdp_beamlet_scale <= TO_UVEC( c_exp_beamlet_scale, 16); - -- exp_sdp_cep_header.app.sdp_beamlet_index <= TO_UVEC( 0, 16); -- depends on bset - -- exp_sdp_cep_header.app.sdp_nof_blocks_per_packet <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet, 8); - -- exp_sdp_cep_header.app.sdp_nof_beamlets_per_block <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16); - -- exp_sdp_cep_header.app.sdp_block_period <= c_exp_sdp_info.block_period; - -- - -- exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64); -- depends on bset and time - --END PROCESS; - rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); p_verify_cep_header : PROCESS diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd index 270ce27dea1c2cf60728dd488e7e075267b6d1be..41634dcb4f229b0d31eb3ac08933f3fd86bc8350 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf_bst_offload.vhd @@ -35,7 +35,7 @@ -- > as 7 # default -- > as 12 # for detailed debugging -- > run -a --- Takes about 10 m +-- Takes about 20 m -- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2c_sdp_station_lib, eth_lib; @@ -52,6 +52,7 @@ USE mm_lib.mm_file_unb_pkg.ALL; USE diag_lib.diag_pkg.ALL; USE wpfb_lib.wpfb_pkg.ALL; USE lofar2_sdp_lib.sdp_pkg.ALL; +USE lofar2_sdp_lib.tb_sdp_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_bf_bst_offload IS END tb_lofar2_unb2c_sdp_station_bf_bst_offload; @@ -60,13 +61,15 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 - CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; + CONSTANT c_node_nr : NATURAL := 0; + CONSTANT c_gn_nr : NATURAL := c_unb_nr*4 + c_node_nr; + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_nr, 8); CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard CONSTANT c_ext_clk_period : TIME := 5 ns; + CONSTANT c_mm_clk_period : TIME := 10 ns; -- 100 MHz internal mm_clk CONSTANT c_bck_ref_clk_period : TIME := 5 ns; CONSTANT c_tb_clk_period : TIME := 100 ps; -- use fast tb_clk to speed up M&C @@ -77,9 +80,25 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS CONSTANT c_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync); CONSTANT c_nof_sync : NATURAL := 1; - -- MM - CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2"; - CONSTANT c_mm_file_reg_stat_enable_bst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_STAT_ENABLE_BST"; + -- header fields + CONSTANT c_exp_beamlet_index : NATURAL := 0; -- depends on beamset bset * c_sdp_S_sub_bf + + CONSTANT c_exp_sdp_info : t_sdp_info := ( + TO_UVEC(601, 16), -- station_id + '0', -- antenna_band_index + x"7FFFFFFF", -- observation_id, use > 0 to avoid Warning: (vsim-151) NUMERIC_STD.TO_INTEGER: Value -2 is not in bounds of subtype NATURAL. + b"01", -- nyquist_zone_index, 0 = first, 1 = second, 2 = third + '1', -- f_adc, 0 = 160 MHz, 1 = 200 MHz + '0', -- fsub_type, 0 = critically sampled, 1 = oversampled + '0', -- beam_repositioning_flag + x"1400" -- block_period = 5120 + ); + + -- MM + CONSTANT c_mm_file_reg_sdp_info : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_SDP_INFO"; + CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2"; + CONSTANT c_mm_file_reg_stat_enable_bst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_STAT_ENABLE_BST"; + CONSTANT c_mm_file_reg_stat_hdr_dat_bst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_STAT_HDR_DAT_BST"; -- Tb SIGNAL tb_end : STD_LOGIC := '0'; @@ -94,13 +113,17 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS CONSTANT c_eth_crc_size : NATURAL := 1; -- word CONSTANT c_eth_packet_size : NATURAL := c_eth_header_size + c_eth_crc_size + (c_sdp_W_statistic / c_word_w) * c_sdp_S_sub_bf * c_sdp_N_pol; -- 20 + 2 * 488 * 2 = 1972 CONSTANT c_eth_check_nof_valid : NATURAL := c_eth_check_nof_packets * c_eth_packet_size; - CONSTANT c_eth_runtime_timeout : TIME := (c_nof_sync + 1) * c_nof_clk_per_sync * c_ext_clk_period; -- eth statistics should be done after c_nof_sync intervals + + -- eth statistics should be done after c_nof_sync + 1 intervals (+1 because first new_interval is skipped) + CONSTANT c_eth_runtime_timeout : TIME := (c_nof_sync + 2) * c_nof_clk_per_sync * c_ext_clk_period; + CONSTANT c_exp_ip_header_checksum : NATURAL := 16#C76C#; -- value obtained from rx_sdp_stat_header.ip.header_checksum in wave window + -- DUT SIGNAL ext_clk : STD_LOGIC := '0'; SIGNAL pps : STD_LOGIC := '0'; SIGNAL ext_pps : STD_LOGIC := '0'; - SIGNAL pps_rst : STD_LOGIC := '0'; + SIGNAL pps_rst : STD_LOGIC := '1'; SIGNAL WDI : STD_LOGIC; SIGNAL INTA : STD_LOGIC; @@ -119,6 +142,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_bst_offload IS SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); SIGNAL rx_sdp_stat_header : t_sdp_stat_header; + SIGNAL exp_sdp_stat_header : t_sdp_stat_header; -- back transceivers SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0); @@ -199,7 +223,26 @@ BEGIN BEGIN -- Wait for DUT power up after reset WAIT FOR 1 us; - + pps_rst <= '0'; + + ---------------------------------------------------------------------------- + -- Offload destination MAC/IP/UDP + ---------------------------------------------------------------------------- + mmf_mm_bus_wr(c_mm_file_reg_stat_hdr_dat_bst, 42, TO_UINT(c_sdp_stat_eth_dst_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_stat_hdr_dat_bst, 41, TO_SINT(c_sdp_stat_eth_dst_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_stat_hdr_dat_bst, 26, TO_SINT(c_sdp_stat_ip_dst_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_stat_hdr_dat_bst, 24, TO_UINT(c_sdp_stat_udp_dst_port), tb_clk); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period); + + ---------------------------------------------------------------------------- + -- Set SDP info + ---------------------------------------------------------------------------- + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_sdp_info, 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + ---------------------------------------------------------------------------- -- Enable BSN ---------------------------------------------------------------------------- @@ -244,7 +287,7 @@ BEGIN eth_rx_data <= eth_rx_sosi.data(c_32-1 DOWNTO 0); -- . Verify XST packet header - u_rx_statistics : ENTITY dp_lib.dp_offload_rx + u_dp_offload_rx : ENTITY dp_lib.dp_offload_rx GENERIC MAP ( g_nof_streams => 1, g_data_w => c_word_w, @@ -269,4 +312,26 @@ BEGIN rx_sdp_stat_header <= func_sdp_map_stat_header(rx_hdr_fields_raw); + exp_sdp_stat_header <= func_sdp_compose_stat_header(c_exp_ip_header_checksum, -- calculated by IO eth + c_exp_sdp_info, + "BST", + '1', -- fixed '1' for BST and XST, weighted_subbands_flag + c_gn_nr, + c_nof_block_per_sync, + 0, -- not used for BST, sst_signal_input + c_exp_beamlet_index, + 0, -- not used for BST, subband_index + 0, -- not used for BST, xst_signal_input_A + 0, -- not used for BST, xst_signal_input_B + 0); -- dp_bsn + + p_verify_header : PROCESS(rx_offload_sosi) + VARIABLE v_bool : BOOLEAN; + BEGIN + -- Prepare exp_sdp_stat_header before rx_offload_sosi.eop, so that it can be verified at rx_offload_sosi.eop + IF rx_offload_sosi.eop = '1' THEN + v_bool := func_sdp_verify_stat_header("BST", rx_sdp_stat_header, exp_sdp_stat_header); + END IF; + END PROCESS; + END tb; diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd index 859fae39cb632915528c05b5d6ad543ade8e86f7..ae3d8b5d299778cd66403c2b11ecdc62114d5307 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd @@ -26,41 +26,41 @@ -- -- Description: -- This tb is a balance between verification coverage and keeping it simple: --- - Use only one signal input (g_sp). Put same remnant WG signal on the --- other signal inputs. +-- - Use only one signal input (g_global_sp) with strong WG. Put same remnant +-- weak WG signal on the other g_nof_rn * S_pn - 1 signal inputs. -- - Use different BF weight for the two beamlet polarizations (g_bf_x_gain, --- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_sp. +-- g_bf_x_phase and g_bf_y_phase, g_bf_y_phase) of signal input g_global_sp. -- Using different BF weights for the N_pol_bf = 2 BF polarizations allows -- verification of the dual polarization beamlet. --- - Use same remnant BF weight for the other S_pn - 1 = 11 signal inputs. +-- - Use same remnant BF weight for the other g_nof_rn * S_pn - 1 signal inputs. -- The remnant signal inputs and BF weights allow verifying the BF sum if -- they are not 0. Using the same settings for all remnant SP simplyfies -- the tb, while still testing the BF sum. --- - Select one beamlet for the subband (g_beamlet). Selecting one beamlet --- other than the default beamlet for the subband is sufficient to verify --- the beamlet subband select. +-- - Select one beamlet (g_beamlet) for the subband (g_subband). Selecting +-- one beamlet other than the default beamlet for the subband is sufficient +-- to verify the beamlet subband select. -- - Use same stimuli for both beamsets. -- -- MM control actions: -- --- 1) Enable calc mode for WG on signal input (si) g_sp via reg_diag_wg with: +-- 1) Enable calc mode for WG on signal input (si) g_global_sp via reg_diag_wg with: -- g_subband = 102 --> 102 * f_sub = 19.921875 MHz -- g_sp_ampl = 1.0 --> 1.0 yield WG ampl = 2**13 -- g_sp_phase --> subband phase --- Use g_sp_remnant_ampl = 0.1 and g_sp_remnant_phase = 0.0 for the other --- S_pn-1 = 11 signal inputs, than g_sp, that are not used in the BF. +-- Use g_sp_remnant_ampl = 0.1 and g_sp_remnant_phase = 0.0 for all other +-- g_nof_rn * S_pn - 1 signal inputs, than g_global_sp, that are not used in the BF. -- -- 2) Read current BSN from reg_bsn_scheduler_wg and write -- reg_bsn_scheduler_wg to trigger start of WG at BSN. -- --- 3) Read and verify subband statistics (SST) for g_sp. This also reads the --- SST of the other signal input of the WPFB that processes g_sp. +-- 3) Read and verify subband statistics (SST) for g_global_sp. This also reads the +-- SST of the other signal input of the WPFB that processes g_global_sp. -- -- 4) Select subband g_subband for beamlets in g_beamlet -- --- 5) Apply BF weight to g_beamlet X beam and Y beam, so for example if g_sp --- = 3, then w_x3 = g_bf_x_gain/phase and w_y3 = = g_bf_x_gain/phase. The --- other BF weights are 0. +-- 5) Apply BF weight to g_beamlet X beam and Y beam, so for example if g_global_sp +-- = 3, then w_x3 = g_bf_x_gain,phase and w_y3 = g_bf_y_gain,phase. The +-- BF weights for all other beamlets (/= g_beamlet) are 0. -- -- WG BF BF -- si weight weight @@ -93,7 +93,6 @@ -- \----------------|---> beamlet_x -- \--> beamlet_y -- --- -- 6) Read and verify beamlet statistics (BST) -- View sp_sst in Wave window -- View bst_x_arr, bst_y_arr in Wave window @@ -109,7 +108,7 @@ -- Usage: -- > as 7 # default -- > as 12 # for detailed debugging --- # Manually add missing signal +-- # Manually add missing signals and constants using objects in GUI -- > add wave -position insertpoint \ -- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/sp_ssts_arr2 \ -- sim:/tb_lofar2_unb2c_sdp_station_bf_ring/bsts_arr2 @@ -139,7 +138,9 @@ USE tech_pll_lib.tech_pll_component_pkg.ALL; ENTITY tb_lofar2_unb2c_sdp_station_bf_ring IS GENERIC ( - g_sp : NATURAL := 3; -- WG signal path (SP) index in range(S_pn = 12) + g_first_gn : NATURAL := 1; -- first global node (GN) in ring + g_nof_rn : NATURAL := 2; -- nof ring nodes (RN) in ring + g_global_sp : NATURAL := 15; -- WG global signal path (SP) index in range [c_first_sp : c_last_sp] g_sp_ampl : REAL := 0.5; -- WG normalized amplitude g_sp_phase : REAL := -110.0; -- WG phase in degrees = subband phase g_sp_remnant_ampl : REAL := 0.1; -- WG normalized amplitude for remnant sp @@ -147,14 +148,15 @@ ENTITY tb_lofar2_unb2c_sdp_station_bf_ring IS g_subband : NATURAL := 102; -- select g_subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz g_beamlet : NATURAL := c_sdp_S_sub_bf-1; -- map g_subband to g_beamlet index in beamset in range(c_sdp_S_sub_bf = 488) g_beamlet_scale : REAL := 1.0 / 2.0**9; -- g_beamlet output scale factor - g_bf_x_gain : REAL := 0.7; -- g_beamlet X BF weight normalized gain for g_sp - g_bf_y_gain : REAL := 0.6; -- g_beamlet Y BF weight normalized gain for g_sp - g_bf_x_phase : REAL := 30.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp - g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp + g_bf_x_gain : REAL := 0.7; -- g_beamlet X BF weight normalized gain for g_global_sp + g_bf_y_gain : REAL := 0.6; -- g_beamlet Y BF weight normalized gain for g_global_sp + g_bf_x_phase : REAL := 30.0; -- g_beamlet X BF weight phase rotation in degrees for g_global_sp + g_bf_y_phase : REAL := 40.0; -- g_beamlet Y BF weight phase rotation in degrees for g_global_sp g_bf_remnant_x_gain : REAL := 0.05; -- g_beamlet X BF weight normalized gain for remnant sp g_bf_remnant_y_gain : REAL := 0.04; -- g_beamlet Y BF weight normalized gain for remnant sp - g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for g_sp - g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for g_sp + g_bf_remnant_x_phase : REAL := 170.0; -- g_beamlet X BF weight phase rotation in degrees for remnant sp + g_bf_remnant_y_phase : REAL := -135.0; -- g_beamlet Y BF weight phase rotation in degrees for remnant sp + g_read_all_sub_sel : BOOLEAN := FALSE; -- when FALSE only read subband selection for g_beamlet, to save sim time g_read_all_SST : BOOLEAN := FALSE; -- when FALSE only read SST for g_subband, to save sim time g_read_all_BST : BOOLEAN := FALSE -- when FALSE only read BST for g_beamlet, to save sim time ); @@ -163,22 +165,26 @@ END tb_lofar2_unb2c_sdp_station_bf_ring; ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_sim : BOOLEAN := TRUE; - CONSTANT c_unb_nr : NATURAL := 0; -- UniBoard 0 - CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_nof_rn : NATURAL := 2; - CONSTANT c_last_unb_nr : NATURAL := (c_nof_rn-1) / c_quad; - CONSTANT c_last_rn_nr : NATURAL := c_nof_rn-1; - CONSTANT c_gn_index : NATURAL := c_unb_nr * c_quad + c_nof_rn-1; -- end node GN + CONSTANT c_first_unb_nr : NATURAL := g_first_gn / c_quad; -- c_quad = 4 FPGAs per UniBoard2 + CONSTANT c_first_node_nr : NATURAL := g_first_gn MOD c_quad; -- first node_nr in range(c_quad) = [0:3] on c_first_unb_nr + CONSTANT c_last_rn : NATURAL := g_nof_rn - 1; -- first RN has index 0 by definition. + CONSTANT c_last_gn : NATURAL := g_first_gn + c_last_rn; -- last global node (GN) in ring + CONSTANT c_last_unb_nr : NATURAL := c_last_gn / c_quad; + CONSTANT c_last_node_nr : NATURAL := c_last_gn MOD c_quad; + CONSTANT c_global_sp_gn : NATURAL := g_global_sp / c_sdp_S_pn; -- global node (GN) of where g_global_sp is located + CONSTANT c_local_sp : NATURAL := g_global_sp MOD c_sdp_S_pn; -- local SP index of g_global_sp on c_global_sp_gn + CONSTANT c_global_sp_unb_nr : NATURAL := c_global_sp_gn / c_quad; -- unb_nr of where g_global_sp is located + CONSTANT c_global_sp_node_nr : NATURAL := c_global_sp_gn MOD c_quad; -- unb_nr of where g_global_sp is located + CONSTANT c_first_sp : NATURAL := g_first_gn * c_sdp_S_pn; + CONSTANT c_last_sp : NATURAL := c_first_sp + g_nof_rn * c_sdp_S_pn - 1; + CONSTANT c_init_bsn : NATURAL := 17; -- some recognizable value >= 0 CONSTANT c_nof_lanes : NATURAL := c_sdp_N_beamsets; - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_gn_index, 8); + CONSTANT c_last_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(c_last_gn, 8); CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_fw_version : t_unb2c_board_fw_version := (1, 0); - CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr + c_last_unb_nr, 8) & TO_UVEC(c_last_rn_nr MOD c_quad, 8); - CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr + c_last_unb_nr, 8) & TO_UVEC((c_last_rn_nr MOD c_quad) +1, 8); -- +1 to avoid IP = *.*.*.0 - CONSTANT c_eth_clk_period : TIME := 8 ns; -- 125 MHz XO on UniBoard CONSTANT c_ext_clk_period : TIME := 5 ns; CONSTANT c_mm_clk_period : TIME := 10 ns; -- 100 MHz internal mm_clk @@ -202,17 +208,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_beamlet_output_delta : INTEGER := 2; -- +-delta margin -- header fields - CONSTANT c_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_dst_mac; -- 00074306C700 = DOP36-eth0 - CONSTANT c_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_dst_addr; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - CONSTANT c_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_dst_port; -- 5000 - - CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; -- x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node - CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_id; -- D0 & c_id - - CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDD#; -- value obtained from rx_sdp_cep_header.ip.header_checksum in wave window for c_nof_rn = 2. + -- . Use gn = 1 for c_cep_ip_src_addr to have fixed c_exp_ip_header_checksum + CONSTANT c_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_cep_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(c_last_gn); + CONSTANT c_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(1); + CONSTANT c_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := c_sdp_cep_udp_src_port_15_8 & c_last_id; -- D0 & c_last_id + -- . The ip_header_checksum depends on src IP, and therefore on the c_last_gn. The expected + -- value is obtained from rx_sdp_cep_header.ip.header_checksum in wave window for + -- c_last_gn = 1. Therefore in this tb use func_sdp_gn_index_to_ip_15_0(1) to have fixed + -- c_exp_ip_header_checksum, independent of actual c_last_gn. + CONSTANT c_exp_ip_header_checksum : NATURAL := 16#5BDD#; CONSTANT c_exp_beamlet_scale : NATURAL := NATURAL(g_beamlet_scale * REAL(c_sdp_unit_beamlet_scale)); -- c_sdp_unit_beamlet_scale = 2**15; + CONSTANT c_exp_beamlet_index : NATURAL := 0; -- depends on beamset bset * c_sdp_S_sub_bf CONSTANT c_exp_sdp_info : t_sdp_info := ( TO_UVEC(601, 16), -- station_id @@ -240,8 +247,8 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_wg_remnant_phase : REAL := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees -- WPFB - CONSTANT c_pol_index : NATURAL := g_sp MOD c_sdp_Q_fft; - CONSTANT c_pfb_index : NATURAL := g_sp / c_sdp_Q_fft; -- only read used WPFB unit out of range(c_sdp_P_pfb = 6) + CONSTANT c_pol_index : NATURAL := c_local_sp MOD c_sdp_Q_fft; + CONSTANT c_pfb_index : NATURAL := c_local_sp / c_sdp_Q_fft; -- only read used WPFB unit out of range(c_sdp_P_pfb = 6) CONSTANT c_subband_phase_offset : REAL := -90.0; -- WG with zero phase sinus yields subband with -90 degrees phase (negative Im, zero Re) CONSTANT c_subband_weight_gain : REAL := 1.0; -- use default unit subband weights CONSTANT c_subband_weight_phase : REAL := 0.0; -- use default unit subband weights @@ -261,7 +268,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS -- . select CONSTANT c_exp_beamlet_x_index : NATURAL := g_beamlet * c_sdp_N_pol_bf; -- X index in beamset 0 CONSTANT c_exp_beamlet_y_index : NATURAL := g_beamlet * c_sdp_N_pol_bf + 1; -- Y index in beamset 0 - -- . Beamlet weights for selected g_sp + -- . Beamlet weights for selected g_global_sp CONSTANT c_bf_x_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase)); CONSTANT c_bf_x_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_x_gain * REAL(c_sdp_unit_bf_weight), g_bf_x_phase)); CONSTANT c_bf_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_y_phase)); @@ -271,10 +278,10 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_bf_remnant_y_weight_re : INTEGER := INTEGER(COMPLEX_RE(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase)); CONSTANT c_bf_remnant_y_weight_im : INTEGER := INTEGER(COMPLEX_IM(g_bf_remnant_y_gain * REAL(c_sdp_unit_bf_weight), g_bf_remnant_y_phase)); - -- Model the SDP beamformer for one g_sp and S_pn-1 = 11 remnant signal inputs + -- Model the SDP beamformer for one g_global_sp and g_nof_rn * S_pn - 1 remnant signal inputs FUNCTION bf_calculate_expected_beamlet(sp_subband_ampl, sp_subband_phase, sp_bf_gain, sp_bf_phase, rem_subband_ampl, rem_subband_phase, rem_bf_gain, rem_bf_phase : REAL) RETURN t_real_arr IS -- 0:3 = ampl, phase, re, im - CONSTANT c_nof_rem : REAL := REAL(c_nof_rn * c_sdp_S_pn - 1); -- BF for one g_sp and N_rn * S_PN - 1 remnant signal inputs + CONSTANT c_nof_rem : REAL := REAL(g_nof_rn * c_sdp_S_pn - 1); -- BF for one g_global_sp and N_rn * S_PN - 1 remnant signal inputs VARIABLE v_sp_ampl, v_sp_phase, v_sp_re, v_sp_im : REAL; VARIABLE v_rem_ampl, v_rem_phase, v_rem_re, v_rem_im : REAL; VARIABLE v_sum_ampl, v_sum_phase, v_sum_re, v_sum_im : REAL; @@ -351,21 +358,19 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS CONSTANT c_mm_span_reg_dp_xonoff : NATURAL := 2**c_addr_w_reg_dp_xonoff; CONSTANT c_mm_span_ram_st_bst : NATURAL := 2**c_addr_w_ram_st_bst; - CONSTANT c_mm_file_reg_ppsh : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_PPS"; - CONSTANT c_mm_file_reg_bsn_source_v2 : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SOURCE_V2"; - CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER"; - CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG"; - CONSTANT c_mm_file_ram_equalizer_gains : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_EQUALIZER_GAINS"; - CONSTANT c_mm_file_reg_dp_selector : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SELECTOR"; - CONSTANT c_mm_file_ram_st_sst : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_ST_SST"; - CONSTANT c_mm_file_ram_st_bst : STRING := mmf_unb_file_prefix(c_unb_nr + c_last_unb_nr, c_last_rn_nr MOD c_quad) & "RAM_ST_BST"; --end RN - CONSTANT c_mm_file_reg_stat_enable_bst : STRING := mmf_unb_file_prefix(c_unb_nr + c_last_unb_nr, c_last_rn_nr MOD c_quad) & "REG_STAT_ENABLE_BST"; --end RN - CONSTANT c_mm_file_reg_dp_xonoff : STRING := mmf_unb_file_prefix(c_unb_nr + c_last_unb_nr, c_last_rn_nr MOD c_quad) & "REG_DP_XONOFF"; --end RN - CONSTANT c_mm_file_ram_ss_ss_wide : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_SS_SS_WIDE"; - CONSTANT c_mm_file_ram_bf_weights : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "RAM_BF_WEIGHTS"; - CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BF_SCALE"; - CONSTANT c_mm_file_reg_sdp_info : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_SDP_INFO"; - CONSTANT c_mm_file_reg_hdr_dat : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_HDR_DAT"; -- c_sdp_N_beamsets = 2 beamsets + -- Use c_mm_file_reg_* on c_last_gn for MM accesses to only last node in ring, e.g. for control beamlet output, read BSN, read back + -- Use mmf_unb_file_prefix() and range(g_nof_rn) for MM access loop to all nodes in ring, e.g. for control BSN source, BF weights + CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_BSN_SCHEDULER"; -- read current BSN + CONSTANT c_mm_file_ram_equalizer_gains : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "RAM_EQUALIZER_GAINS"; -- read default subband weight + CONSTANT c_mm_file_reg_dp_selector : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_DP_SELECTOR"; -- read sst_weighted_subbands_flag + CONSTANT c_mm_file_ram_st_sst : STRING := mmf_unb_file_prefix(c_global_sp_unb_nr, c_global_sp_node_nr) & "RAM_ST_SST"; -- read SST from GN with g_global_sp + CONSTANT c_mm_file_ram_st_bst : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "RAM_ST_BST"; -- read BST + CONSTANT c_mm_file_reg_stat_enable_bst : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_STAT_ENABLE_BST"; -- control BST offload + CONSTANT c_mm_file_reg_dp_xonoff : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_DP_XONOFF"; -- beamlet output + CONSTANT c_mm_file_ram_ss_ss_wide : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "RAM_SS_SS_WIDE"; --readback + CONSTANT c_mm_file_ram_bf_weights : STRING := mmf_unb_file_prefix(c_global_sp_unb_nr, c_global_sp_node_nr) & "RAM_BF_WEIGHTS"; -- readback from GN with g_global_sp + CONSTANT c_mm_file_reg_bf_scale : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_BF_SCALE"; -- readback + CONSTANT c_mm_file_reg_hdr_dat : STRING := mmf_unb_file_prefix(c_last_unb_nr, c_last_node_nr) & "REG_HDR_DAT"; -- control beamlet output -- Tb SIGNAL stimuli_done : STD_LOGIC := '0'; @@ -385,15 +390,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS -- MM SIGNAL rd_sdp_info : t_sdp_info := c_sdp_info_rst; SIGNAL rd_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0); + SIGNAL rd_cep_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); SIGNAL rd_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); + SIGNAL rd_cep_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL rd_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL rd_cep_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL rd_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0); -- WG SIGNAL current_bsn_wg : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); -- FSUB - -- . Read sp_ssts_arr2 = SST for one WPFB unit that processes g_sp + -- . Read sp_ssts_arr2 = SST for one WPFB unit that processes g_global_sp SIGNAL sp_ssts_arr2 : t_slv_64_subbands_arr(c_sdp_N_pol-1 DOWNTO 0); -- [pol][sub], for X,Y pair of A, B SIGNAL sp_sst : REAL := 0.0; SIGNAL stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); @@ -410,18 +418,18 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS -- BF -- . beamlet subband selection SIGNAL sp_subband_select : NATURAL := 0; - SIGNAL sp_subband_select_arr : t_natural_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => 0); -- Q_fft = N_pol = 2 + SIGNAL sp_subband_select_arr : t_integer_arr(0 TO c_sdp_S_sub_bf * c_sdp_N_pol-1) := (OTHERS => -1); -- Q_fft = N_pol = 2 -- . beamlet X-pol - SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); - SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); + SIGNAL sp_bf_x_weights_re_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_x_weights_im_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_x_weights_gain_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); + SIGNAL sp_bf_x_weights_phase_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); -- . beamlet Y-pol - SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0); - SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); - SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(0 TO c_nof_rn * c_sdp_S_pn-1) := (OTHERS => 0.0); + SIGNAL sp_bf_y_weights_re_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_y_weights_im_arr : t_integer_arr(c_first_sp TO c_last_sp) := (OTHERS => 0); + SIGNAL sp_bf_y_weights_gain_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); + SIGNAL sp_bf_y_weights_phase_arr : t_real_arr(c_first_sp TO c_last_sp) := (OTHERS => 0.0); -- . BST SIGNAL bsts_arr2 : t_slv_64_beamlets_arr(c_sdp_N_pol_bf-1 DOWNTO 0); -- [pol_bf][blet] @@ -475,13 +483,13 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_bf_ring IS SIGNAL eth_rxp : STD_LOGIC_VECTOR(c_unb2c_board_nof_eth-1 downto 0); SIGNAL SA_CLK : STD_LOGIC := '1'; - SIGNAL i_QSFP_0_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_QSFP_0_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_RING_0_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_RING_0_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_RING_1_TX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_RING_1_RX : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); - SIGNAL i_QSFP_1_lpbk : t_unb2c_board_qsfp_bus_2arr(c_nof_rn -1 DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_QSFP_0_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_QSFP_0_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_RING_0_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_RING_0_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_RING_1_TX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_RING_1_RX : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); + SIGNAL i_QSFP_1_lpbk : t_unb2c_board_qsfp_bus_2arr(c_last_rn DOWNTO 0) := (OTHERS => (OTHERS => '0')); -- back transceivers SIGNAL JESD204B_SERIAL_DATA : STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0); @@ -515,14 +523,14 @@ BEGIN ------------------------------------------------------------------------------ -- DUT ------------------------------------------------------------------------------ - gen_dut : FOR RN IN 0 TO c_nof_rn -1 GENERATE + gen_dut : FOR RN IN 0 TO c_last_rn GENERATE u_lofar_unb2c_sdp_station_bf : ENTITY lofar2_unb2c_sdp_station_lib.lofar2_unb2c_sdp_station GENERIC MAP ( g_design_name => "lofar2_unb2c_sdp_station_bf_ring", g_design_note => "", g_sim => c_sim, - g_sim_unb_nr => c_unb_nr + (RN / c_quad), - g_sim_node_nr => RN MOD c_quad, + g_sim_unb_nr => (g_first_gn + RN) / c_quad, + g_sim_node_nr => (g_first_gn + RN) MOD c_quad, g_wpfb => c_wpfb_sim, g_bsn_nof_clk_per_sync => c_nof_clk_per_sync, g_scope_selected_subband => g_subband @@ -537,7 +545,7 @@ BEGIN -- Others VERSION => c_version, - ID => ( TO_UVEC(RN / c_quad, c_unb2c_board_nof_uniboard_w) & TO_UVEC(RN MOD c_quad, c_unb2c_board_nof_chip_w) ), + ID => ( TO_UVEC((g_first_gn + RN) / c_quad, c_unb2c_board_nof_uniboard_w) & TO_UVEC((g_first_gn + RN) MOD c_quad, c_unb2c_board_nof_chip_w) ), TESTIO => open, -- 1GbE Control Interface @@ -575,17 +583,16 @@ BEGIN END GENERATE; -- Ring connections - gen_ring : FOR I IN 0 TO c_nof_rn -2 GENERATE + gen_ring : FOR RN IN 0 TO c_last_rn-1 GENERATE -- Connect consecutive nodes with RING interfaces (PCB) - i_RING_0_RX(I+1) <= i_RING_1_TX(I); - i_RING_1_RX(I) <= i_RING_0_TX(I+1); + i_RING_0_RX(RN + 1) <= i_RING_1_TX(RN); + i_RING_1_RX(RN) <= i_RING_0_TX(RN + 1); END GENERATE; -- Connect first and last nodes with QSFP interface. - i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_nof_rn-1); - i_QSFP_0_RX(c_nof_rn-1) <= i_QSFP_0_TX(0); + i_QSFP_0_RX(0) <= i_QSFP_0_TX(c_last_rn); + i_QSFP_0_RX(c_last_rn) <= i_QSFP_0_TX(0); - ------------------------------------------------------------------------------ -- CEP model @@ -622,7 +629,7 @@ BEGIN dp_rst => dest_rst, dp_clk => ext_clk, - serial_rx_arr(0) => i_QSFP_1_lpbk(c_nof_rn-1)(0), -- Last RN must be used as end node. + serial_rx_arr(0) => i_QSFP_1_lpbk(c_last_rn)(0), -- Last RN must be used as end node. src_out_arr(0) => tr_10GbE_src_out, src_in_arr(0) => tr_10GbE_src_in @@ -663,9 +670,8 @@ BEGIN tb_clk <= NOT tb_clk AFTER c_tb_clk_period/2; -- Testbench MM clock p_mm_stimuli : PROCESS + VARIABLE v_gn : NATURAL; VARIABLE v_bsn : NATURAL; - VARIABLE v_sp_sst : REAL := 0.0; - VARIABLE v_bst : REAL := 0.0; VARIABLE v_data_lo, v_data_hi : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); VARIABLE v_stat_data : STD_LOGIC_VECTOR(c_longword_w-1 DOWNTO 0); VARIABLE v_len, v_span, v_offset, v_addr, v_sel : NATURAL; -- address ranges, indices @@ -673,6 +679,12 @@ BEGIN VARIABLE v_re, v_im, v_weight : INTEGER; VARIABLE v_re_exp, v_im_exp : REAL := 0.0; BEGIN + -- Check g_global_sp + IF g_global_sp < c_first_sp OR g_global_sp > c_last_sp THEN + ASSERT FALSE REPORT "g_global_sp not in ring GN range." SEVERITY ERROR; + ASSERT FALSE REPORT "g_global_sp not in ring GN range." SEVERITY FAILURE; + END IF; + -- Wait for DUT power up after reset WAIT FOR 1 us; @@ -725,16 +737,17 @@ BEGIN -- . Write - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk); - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk); - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 7, TO_UINT(c_exp_sdp_info.station_id), tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 6, TO_UINT(slv(c_exp_sdp_info.antenna_band_index)), tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 5, TO_UINT(c_exp_sdp_info.observation_id), tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 4, TO_UINT(c_exp_sdp_info.nyquist_zone_index), tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 1, TO_UINT(slv(c_exp_sdp_info.beam_repositioning_flag)), tb_clk); -- . Read - mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 3, rd_data, tb_clk); rd_sdp_info.f_adc <= rd_data(0); - mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 2, rd_data, tb_clk); rd_sdp_info.fsub_type <= rd_data(0); - mmf_mm_bus_rd(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_SDP_INFO", 0, rd_data, tb_clk); rd_sdp_info.block_period <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 3, rd_data, tb_clk); rd_sdp_info.f_adc <= rd_data(0); + mmf_mm_bus_rd(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 2, rd_data, tb_clk); rd_sdp_info.fsub_type <= rd_data(0); + mmf_mm_bus_rd(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_SDP_INFO", 0, rd_data, tb_clk); rd_sdp_info.block_period <= rd_data(15 DOWNTO 0); END LOOP; proc_common_wait_some_cycles(tb_clk, 1); @@ -747,13 +760,13 @@ BEGIN ---- Set and check BF per beamset ------------------------------------------------------------------------------ FOR bset IN 0 TO c_sdp_N_beamsets-1 LOOP - -- MM beamlet_scale + ---------------------------------------------------------------------------- + -- MM beamlet_scale on last node + ---------------------------------------------------------------------------- -- . write v_offset := bset * c_mm_span_reg_bf_scale; - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BF_SCALE", v_offset + 0, c_exp_beamlet_scale, tb_clk); - END LOOP; - proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period); + mmf_mm_bus_wr(c_mm_file_reg_bf_scale, v_offset + 0, c_exp_beamlet_scale, tb_clk); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); -- . readback mmf_mm_bus_rd(c_mm_file_reg_bf_scale, v_offset + 0, rd_data, tb_clk); @@ -761,6 +774,9 @@ BEGIN proc_common_wait_some_cycles(tb_clk, 1); ASSERT TO_UINT(rd_beamlet_scale) = c_exp_beamlet_scale REPORT "Wrong MM read beamlet_scale for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ---------------------------------------------------------------------------- + -- Set CEP beamlets output MAC,IP,UDP port on last node + ---------------------------------------------------------------------------- -- CEP beamlet output header -- c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( -- 40 "eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ), @@ -810,27 +826,63 @@ BEGIN -- ); v_offset := bset * c_mm_span_reg_hdr_dat; - -- . Use defaults, so no need to write + -- Default destination MAC/IP/UDP = 0 -- . Read + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); proc_common_wait_some_cycles(tb_clk, 1); - - -- verify read - ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 00074306C700 = DOP36-eth0 - ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- C0A80001 = '192.168.0.1' = DOP36-eth0 - ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; -- 5000 + -- . verify read + ASSERT UNSIGNED(rd_cep_eth_src_mac) = 0 REPORT "Wrong MM read rd_cep_eth_src_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_src_addr) = 0 REPORT "Wrong MM read rd_cep_ip_src_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_src_port) = 0 REPORT "Wrong MM read rd_cep_udp_src_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_eth_dst_mac) = 0 REPORT "Wrong MM read rd_cep_eth_dst_mac != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_ip_dst_addr) = 0 REPORT "Wrong MM read rd_cep_ip_dst_addr != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT UNSIGNED(rd_cep_udp_dst_port) = 0 REPORT "Wrong MM read rd_cep_udp_dst_port != 0 for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + + -- Write tb defaults + -- . Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on c_last_gn + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 39, TO_UINT(c_cep_eth_src_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 38, TO_SINT(c_cep_eth_src_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 26, TO_SINT(c_cep_ip_src_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 24, TO_UINT(c_cep_udp_src_port), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 41, TO_UINT(c_sdp_cep_eth_dst_mac(47 DOWNTO 32)), tb_clk); + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 40, TO_SINT(c_sdp_cep_eth_dst_mac(31 DOWNTO 0)), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 25, TO_SINT(c_sdp_cep_ip_dst_addr), tb_clk); -- use signed to fit 32 b in INTEGER + mmf_mm_bus_wr(c_mm_file_reg_hdr_dat, v_offset + 23, TO_UINT(c_sdp_cep_udp_dst_port), tb_clk); + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_ext_clk_period, c_common_cross_clock_domain_latency*2); + + -- . Read back + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 39, rd_data, tb_clk); rd_cep_eth_src_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 38, rd_data, tb_clk); rd_cep_eth_src_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 26, rd_data, tb_clk); rd_cep_ip_src_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 24, rd_data, tb_clk); rd_cep_udp_src_port <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 41, rd_data, tb_clk); rd_cep_eth_dst_mac(47 DOWNTO 32) <= rd_data(15 DOWNTO 0); + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 40, rd_data, tb_clk); rd_cep_eth_dst_mac(31 DOWNTO 0) <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 25, rd_data, tb_clk); rd_cep_ip_dst_addr <= rd_data; + mmf_mm_bus_rd(c_mm_file_reg_hdr_dat, v_offset + 23, rd_data, tb_clk); rd_cep_udp_dst_port <= rd_data(15 DOWNTO 0); + proc_common_wait_some_cycles(tb_clk, 1); + -- . verify read back + ASSERT rd_cep_eth_src_mac = c_cep_eth_src_mac REPORT "Wrong MM read rd_cep_eth_src_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_src_addr = c_cep_ip_src_addr REPORT "Wrong MM read rd_cep_ip_src_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_src_port = c_cep_udp_src_port REPORT "Wrong MM read rd_cep_udp_src_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_eth_dst_mac = c_sdp_cep_eth_dst_mac REPORT "Wrong MM read rd_cep_eth_dst_mac for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_ip_dst_addr = c_sdp_cep_ip_dst_addr REPORT "Wrong MM read rd_cep_ip_dst_addr for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; + ASSERT rd_cep_udp_dst_port = c_sdp_cep_udp_dst_port REPORT "Wrong MM read rd_cep_udp_dst_port for beamset " & NATURAL'IMAGE(bset) SEVERITY ERROR; ---------------------------------------------------------------------------- - -- Enable BST offload on end node (not verified here, but only for view in Wave window) + -- Enable BST offload on last node (not verified here, but only for view in Wave window) ---------------------------------------------------------------------------- v_offset := bset * c_mm_span_reg_stat_enable_bst; mmf_mm_bus_wr(c_mm_file_reg_stat_enable_bst, v_offset + 0, 1, tb_clk); ---------------------------------------------------------------------------- - -- Enable beamlet output on end node (dp_xonoff) + -- Enable beamlet output on last node (dp_xonoff) ---------------------------------------------------------------------------- v_offset := bset * c_mm_span_reg_dp_xonoff; mmf_mm_bus_wr(c_mm_file_reg_dp_xonoff, v_offset + 0, 1, tb_clk); @@ -839,11 +891,12 @@ BEGIN ---------------------------------------------------------------------------- -- Enable BS ---------------------------------------------------------------------------- - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 2, c_init_bsn, tb_clk); -- Init BSN - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 3, 0, tb_clk); -- Write high part a - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_syn - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SOURCE_V2", 0, 16#00000003#, tb_clk); -- Enable BS at PPS + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SOURCE_V2", 2, c_init_bsn, tb_clk); -- Init BSN + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SOURCE_V2", 3, 0, tb_clk); -- Write high part a + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SOURCE_V2", 1, c_nof_clk_per_sync, tb_clk); -- nof_block_per_syn + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SOURCE_V2", 0, 16#00000003#, tb_clk); -- Enable BS at PPS END LOOP; -- Release PPS pulser, to get first PPS now and to start BSN source @@ -854,28 +907,41 @@ BEGIN -- Ring config ---------------------------------------------------------------------------- -- Write ring configuration to all nodes. - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_INFO", 2, c_nof_rn, tb_clk); -- N_rn - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_INFO", 3, 0, tb_clk); -- O_rn + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 2, g_nof_rn, tb_clk); -- N_rn + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 3, g_first_gn, tb_clk); -- O_rn END LOOP; - -- Start node specific settings - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr, 0) & "REG_RING_INFO", 0, 1, tb_clk); -- use_ring_to_previous_rn = 1 - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr, 0) & "REG_RING_INFO", 1, 0, tb_clk); -- use_ring_to_next_rn = 0 - - -- End node specific settings - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + c_last_unb_nr, c_last_rn_nr MOD c_quad) & "REG_RING_INFO", 0, 0, tb_clk); -- use_ring_to_previous_rn = 0 - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + c_last_unb_nr, c_last_rn_nr MOD c_quad) & "REG_RING_INFO", 1, 1, tb_clk); -- use_ring_to_next_rn = 1 - - -- Access scheme 1. Each RN uses and sends them along the ring. - FOR RN IN 0 TO c_nof_rn-1 LOOP + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + IF v_gn = g_first_gn THEN + -- Start node specific settings + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 0, 1, tb_clk); -- use_cable_to_previous_rn = 1 + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 1, 0, tb_clk); -- use_cable_to_next_rn = 0 + ELSIF v_gn = c_last_gn THEN + -- End node specific settings + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 0, 0, tb_clk); -- use_cable_to_previous_rn = 0 + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 1, 1, tb_clk); -- use_cable_to_next_rn = 1 + ELSE + -- Use same settings for all nodes in between + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 0, 0, tb_clk); -- use_cable_to_previous_rn = 0 + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_INFO", 1, 0, tb_clk); -- use_cable_to_next_rn = 0 + END IF; + END LOOP; + + -- Access scheme 1 for beamformer. + -- Use transport_nof_hops = 0 on last node to stop remote input for first node. No + -- need to also disable the remote input of the BSN aligner on the first node. + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; FOR I IN 0 TO c_nof_lanes-1 LOOP - IF RN = c_nof_rn-1 THEN + IF RN = c_last_rn THEN -- End RN, so set transport_nof_hops to 0. - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 0, tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 0, tb_clk); ELSE -- Set transport_nof_hops to 1 on all nodes. - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 1, tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_RING_LANE_INFO_BF", I*2+1, 1, tb_clk); END IF; END LOOP; END LOOP; @@ -888,24 +954,26 @@ BEGIN -- 1 : phase[15:0] -- 2 : freq[30:0] -- 3 : ampl[16:0] - -- . Put wanted signal on g_sp input and remnant signal on the other inputs - FOR RN IN 0 TO c_nof_rn-1 LOOP - FOR I IN 0 TO c_sdp_S_pn-1 LOOP - IF RN * c_sdp_S_pn + I = g_sp THEN - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl + -- . Put wanted signal on g_global_sp input and remnant signal on all g_nof_rn * S_pn - 1 other inputs + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + FOR S IN 0 TO c_sdp_S_pn-1 LOOP + IF v_gn * c_sdp_S_pn + S = g_global_sp THEN + -- Strong WG signal at g_global_sp + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 1, INTEGER(c_wg_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 3, INTEGER(REAL(c_wg_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl ELSE - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 1, INTEGER(c_wg_remnant_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_WG", I*4 + 3, INTEGER(REAL(c_wg_remnant_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl + -- Weak WG signal on all other (remnant) SP + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 0, 1024*2**16 + 1, tb_clk); -- nof_samples, mode calc + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 1, INTEGER(c_wg_remnant_phase * c_diag_wg_phase_unit), tb_clk); -- phase offset in degrees + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 2, INTEGER(REAL(g_subband) * c_sdp_wg_subband_freq_unit), tb_clk); -- freq + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_WG", S*4 + 3, INTEGER(REAL(c_wg_remnant_ampl) * c_sdp_wg_ampl_lsb), tb_clk); -- ampl END IF; END LOOP; END LOOP; - -- Read current BSN mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 0, current_bsn_wg(31 DOWNTO 0), tb_clk); mmf_mm_bus_rd(c_mm_file_reg_bsn_scheduler_wg, 1, current_bsn_wg(63 DOWNTO 32), tb_clk); @@ -915,9 +983,10 @@ BEGIN v_bsn := TO_UINT(current_bsn_wg) + 2; ASSERT v_bsn <= c_bsn_start_wg REPORT "Too late to start WG: " & int_to_str(v_bsn) & " > " & int_to_str(c_bsn_start_wg) SEVERITY ERROR; - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SCHEDULER", 0, c_bsn_start_wg, tb_clk); -- first write low then high part - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "REG_BSN_SCHEDULER", 1, 0, tb_clk); -- assume v_bsn < 2**31-1 + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SCHEDULER", 0, c_bsn_start_wg, tb_clk); -- first write low then high part + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "REG_BSN_SCHEDULER", 1, 0, tb_clk); -- assume v_bsn < 2**31-1 END LOOP; ---------------------------------------------------------------------------- @@ -932,7 +1001,7 @@ BEGIN ---------------------------------------------------------------------------- -- . MM format: (cint16)RAM_EQUALIZER_GAINS[S_pn/Q_fft]_[Q_fft][N_sub] = [S_pn][N_sub] - v_addr := g_sp * c_sdp_N_sub + g_subband; + v_addr := c_local_sp * c_sdp_N_sub + g_subband; -- . read mmf_mm_bus_rd(c_mm_file_ram_equalizer_gains, v_addr, rd_data, tb_clk); v_re := unpack_complex_re(rd_data, c_sdp_W_sub_weight); @@ -959,28 +1028,32 @@ BEGIN FOR P IN 0 TO c_sdp_N_pol-1 LOOP v_addr := P + g_beamlet * c_sdp_N_pol + A * v_span + U * c_mm_span_ram_ss_ss_wide; v_sel := P + g_subband * c_sdp_N_pol; - FOR RN IN 0 TO c_nof_rn-1 LOOP - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "RAM_SS_SS_WIDE", v_addr, v_sel, tb_clk); + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "RAM_SS_SS_WIDE", v_addr, v_sel, tb_clk); END LOOP; END LOOP; END LOOP; END LOOP; - -- . read back selection for g_sp = c_pfb_index * c_sdp_N_pol + c_pol_index + -- . read back selection for c_local_sp = c_pfb_index * c_sdp_N_pol + c_pol_index v_P := c_pol_index; v_A := c_pfb_index; FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP -- Same selection for both beamsets, so fine to use only one sp_subband_select_arr() FOR B IN 0 TO c_sdp_S_sub_bf-1 LOOP - -- Same selection for all SP, so fine to only read subband selection for g_sp - v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; - mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); - v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; - sp_subband_select_arr(B) <= v_sel; - sp_subband_select <= v_sel; -- for time series view in Wave window + IF g_read_all_sub_sel OR B = g_beamlet THEN + -- Same selection for all SP, so fine to only read subband selection for c_local_sp on last node + v_addr := v_P + B * c_sdp_N_pol + v_A * v_span + U * c_mm_span_ram_ss_ss_wide; + mmf_mm_bus_rd(c_mm_file_ram_ss_ss_wide, v_addr, rd_data, tb_clk); + v_sel := (TO_UINT(rd_data) - v_P) / c_sdp_N_pol; + sp_subband_select_arr(B * c_sdp_N_pol + v_P) <= v_sel; + sp_subband_select <= v_sel; -- for time series view in Wave window + END IF; END LOOP; END LOOP; proc_common_wait_some_cycles(tb_clk, 1); + ASSERT sp_subband_select_arr(g_beamlet * c_sdp_N_pol + v_P) = g_subband REPORT "Wrong subband select at beamlet index." SEVERITY ERROR; proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window ---------------------------------------------------------------------------- @@ -990,16 +1063,18 @@ BEGIN -- . write BF weights, only for g_beamlet to save sim time v_span := true_log_pow2(c_sdp_N_pol * c_sdp_S_sub_bf); -- = 1024 - FOR RN IN 0 TO c_nof_rn-1 LOOP + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP -- Same BF weights for both beamsets FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP - -- Same BF weights for both beamlet polarizations + -- Different BF weights for both beamlet polarizations FOR A IN 0 TO c_sdp_A_pn-1 LOOP FOR P IN 0 TO c_sdp_N_pol-1 LOOP - v_S := RN * c_sdp_S_pn + A * c_sdp_N_pol + P; - IF v_S = g_sp THEN - -- use generic BF weight for g_sp in g_beamlet + v_S := v_gn * c_sdp_S_pn + A * c_sdp_N_pol + P; + -- Different BF weights for g_global_sp and the remnant sp + IF v_S = g_global_sp THEN + -- use generic BF weight for g_global_sp in g_beamlet IF PB = 0 THEN v_weight := pack_complex(re => c_bf_x_weight_re, im => c_bf_x_weight_im, w => c_sdp_W_bf_weight); ELSE @@ -1013,12 +1088,13 @@ BEGIN v_weight := pack_complex(re => c_bf_remnant_y_weight_re, im => c_bf_remnant_y_weight_im, w => c_sdp_W_bf_weight); END IF; END IF; + -- Only need to set BF weight for g_beamlet, keep other beamlet BF weights at zero rst default. v_addr := g_beamlet; -- beamlet index v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset v_addr := v_addr + A * v_span; -- antenna input address offset v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset - mmf_mm_bus_wr(mmf_unb_file_prefix(c_unb_nr + (RN / c_quad), RN MOD c_quad) & "RAM_BF_WEIGHTS", v_addr, v_weight, tb_clk); + mmf_mm_bus_wr(mmf_unb_file_prefix(v_gn / c_quad, v_gn MOD c_quad) & "RAM_BF_WEIGHTS", v_addr, v_weight, tb_clk); END LOOP; END LOOP; END LOOP; @@ -1026,32 +1102,35 @@ BEGIN END LOOP; -- . read back BF weights for g_beamlet in S_sub_bf - FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP - FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP - FOR A IN 0 TO c_sdp_A_pn-1 LOOP - FOR P IN 0 TO c_sdp_N_pol-1 LOOP - v_addr := g_beamlet; -- beamlet index - v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset - v_addr := v_addr + A * v_span; -- antenna input address offset - v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset - v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset - mmf_mm_bus_rd(c_mm_file_ram_bf_weights, v_addr, rd_data, tb_clk); - v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight); - v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight); - -- same BF weights for both beamsets and both beamlet polarizations, - -- so fine to use only one sp_bf_x_weights_*_arr() - v_S := A * c_sdp_N_pol + P; - IF PB = 0 THEN - sp_bf_x_weights_re_arr(v_S) <= v_re; - sp_bf_x_weights_im_arr(v_S) <= v_im; - sp_bf_x_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); - sp_bf_x_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); - ELSE - sp_bf_y_weights_re_arr(v_S) <= v_re; - sp_bf_y_weights_im_arr(v_S) <= v_im; - sp_bf_y_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); - sp_bf_y_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); - END IF; + FOR RN IN 0 TO c_last_rn LOOP + v_gn := g_first_gn + RN; + FOR U IN 0 TO c_sdp_N_beamsets-1 LOOP + FOR PB IN 0 TO c_sdp_N_pol_bf-1 LOOP + FOR A IN 0 TO c_sdp_A_pn-1 LOOP + FOR P IN 0 TO c_sdp_N_pol-1 LOOP + v_addr := g_beamlet; -- beamlet index + v_addr := v_addr + P * c_sdp_S_sub_bf; -- antenna input polarization address offset + v_addr := v_addr + A * v_span; -- antenna input address offset + v_addr := v_addr + PB * c_sdp_A_pn * v_span; -- beamlet polarization address offset + v_addr := v_addr + U * c_mm_span_ram_bf_weights; -- beamset address offset + mmf_mm_bus_rd(c_mm_file_ram_bf_weights, v_addr, rd_data, tb_clk); + v_re := unpack_complex_re(rd_data, c_sdp_W_bf_weight); + v_im := unpack_complex_im(rd_data, c_sdp_W_bf_weight); + -- same BF weights for both beamsets and both beamlet polarizations, + -- so fine to use only one sp_bf_x_weights_*_arr() + v_S := v_gn * c_sdp_S_pn + A * c_sdp_N_pol + P; + IF PB = 0 THEN + sp_bf_x_weights_re_arr(v_S) <= v_re; + sp_bf_x_weights_im_arr(v_S) <= v_im; + sp_bf_x_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); + sp_bf_x_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); + ELSE + sp_bf_y_weights_re_arr(v_S) <= v_re; + sp_bf_y_weights_im_arr(v_S) <= v_im; + sp_bf_y_weights_gain_arr(v_S) <= COMPLEX_RADIUS(v_re, v_im) / REAL(c_sdp_unit_bf_weight); + sp_bf_y_weights_phase_arr(v_S) <= COMPLEX_PHASE(v_re, v_im); + END IF; + END LOOP; END LOOP; END LOOP; END LOOP; @@ -1070,13 +1149,13 @@ BEGIN stimuli_done <= '1'; --------------------------------------------------------------------------- - -- Read subband statistics + -- Read subband statistics from node with g_global_sp --------------------------------------------------------------------------- -- . the subband statistics are c_stat_data_sz = 2 word power values. -- . there are c_sdp_S_pn = 12 signal inputs A, B, C, D, E, F, G, H, I, J, K, L -- . there are c_sdp_N_sub = 512 subbands per signal input (SI, = signal path, SP) -- . one complex WPFB can process two real inputs A, B, so there are c_sdp_P_pfb = 6 WPFB units, - -- but only read for the 1 WPFB unit of the selected g_sp, to save sim time + -- but only read for the 1 WPFB unit of the selected g_global_sp, to save sim time -- . the outputs for A, B are time multiplexed, c_sdp_Q_fft = 2, assume that they -- correspond to the c_sdp_N_pol = 2 signal polarizations -- . the subbands are output alternately so A0 B0 A1 B1 ... A511 B511 for input A, B @@ -1108,13 +1187,13 @@ BEGIN END LOOP; proc_common_wait_some_cycles(tb_clk, 1); - -- Subband power of g_subband in g_sp + -- Subband power of g_subband in g_global_sp sp_sst <= TO_UREAL(sp_ssts_arr2(c_pol_index)(g_subband)); proc_common_wait_some_cycles(tb_clk, 1); proc_common_wait_some_cycles(ext_clk, 100); -- delay for ease of view in Wave window --------------------------------------------------------------------------- - -- Read beamlet statistics from end node + -- Read beamlet statistics from last node --------------------------------------------------------------------------- -- . the beamlet statistics are c_stat_data_sz = 2 word power values. -- . there are c_sdp_S_sub_bf = 488 dual pol beamlets per beamset @@ -1225,8 +1304,8 @@ BEGIN -- Verify SST --------------------------------------------------------------------------- -- verify expected subband power based on WG power - ASSERT sp_sst > c_stat_lo_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; - ASSERT sp_sst < c_stat_hi_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_sp) SEVERITY ERROR; + ASSERT sp_sst > c_stat_lo_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_global_sp) SEVERITY ERROR; + ASSERT sp_sst < c_stat_hi_factor * c_exp_subband_sst REPORT "Wrong subband power for SP " & NATURAL'IMAGE(g_global_sp) SEVERITY ERROR; --------------------------------------------------------------------------- -- Verify BST @@ -1291,59 +1370,15 @@ BEGIN test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit rx_beamlet_sosi -- Prepare exp_sdp_cep_header before rx_beamlet_sosi.eop, so that - -- p_exp_sdp_cep_header can verify it at rx_beamlet_sosi.eop. + -- p_verify_cep_header can verify it at rx_beamlet_sosi.eop. - p_exp_sdp_cep_header : PROCESS(exp_dp_bsn) - BEGIN - -- eth header - exp_sdp_cep_header.eth.dst_mac <= c_cep_eth_dst_mac; - exp_sdp_cep_header.eth.src_mac <= c_cep_eth_src_mac; - exp_sdp_cep_header.eth.eth_type <= x"0800"; - - -- ip header - exp_sdp_cep_header.ip.version <= TO_UVEC( 4, c_network_ip_version_w); - exp_sdp_cep_header.ip.header_length <= TO_UVEC( 5, c_network_ip_header_length_w); - exp_sdp_cep_header.ip.services <= TO_UVEC( 0, c_network_ip_services_w); - exp_sdp_cep_header.ip.total_length <= c_sdp_cep_ip_total_length; -- 7868, see ICD STAT-CEP - exp_sdp_cep_header.ip.identification <= TO_UVEC( 0, c_network_ip_identification_w); - exp_sdp_cep_header.ip.flags <= TO_UVEC( 2, c_network_ip_flags_w); - exp_sdp_cep_header.ip.fragment_offset <= TO_UVEC( 0, c_network_ip_fragment_offset_w); - exp_sdp_cep_header.ip.time_to_live <= TO_UVEC( 127, c_network_ip_time_to_live_w); - exp_sdp_cep_header.ip.protocol <= TO_UVEC( 17, c_network_ip_protocol_w); - exp_sdp_cep_header.ip.header_checksum <= TO_UVEC( c_exp_ip_header_checksum, c_network_ip_header_checksum_w); - exp_sdp_cep_header.ip.src_ip_addr <= c_cep_ip_src_addr; -- c_network_ip_addr_w - exp_sdp_cep_header.ip.dst_ip_addr <= c_cep_ip_dst_addr; -- c_network_ip_addr_w - - -- udp header - exp_sdp_cep_header.udp.src_port <= c_cep_udp_src_port; - exp_sdp_cep_header.udp.dst_port <= c_cep_udp_dst_port; - exp_sdp_cep_header.udp.total_length <= c_sdp_cep_udp_total_length; -- 7848, see ICD STAT-CEP - exp_sdp_cep_header.udp.checksum <= TO_UVEC( 0, c_network_udp_checksum_w); - - -- app header - exp_sdp_cep_header.app.sdp_marker <= TO_UVEC(c_sdp_marker_beamlets, 8); -- 98 = x"62" = 'b' - exp_sdp_cep_header.app.sdp_version_id <= TO_UVEC(c_sdp_cep_version_id, 8); -- 5 - exp_sdp_cep_header.app.sdp_observation_id <= c_exp_sdp_info.observation_id; - exp_sdp_cep_header.app.sdp_station_id <= c_exp_sdp_info.station_id; - - exp_sdp_cep_header.app.sdp_source_info_antenna_band_id <= slv(c_exp_sdp_info.antenna_band_index); - exp_sdp_cep_header.app.sdp_source_info_nyquist_zone_id <= c_exp_sdp_info.nyquist_zone_index; - exp_sdp_cep_header.app.sdp_source_info_f_adc <= slv(c_exp_sdp_info.f_adc); - exp_sdp_cep_header.app.sdp_source_info_fsub_type <= slv(c_exp_sdp_info.fsub_type); - exp_sdp_cep_header.app.sdp_source_info_payload_error <= TO_UVEC(0, 1); - exp_sdp_cep_header.app.sdp_source_info_repositioning_flag <= slv(c_exp_sdp_info.beam_repositioning_flag); - exp_sdp_cep_header.app.sdp_source_info_beamlet_width <= TO_UVEC(c_sdp_W_beamlet, 4); - exp_sdp_cep_header.app.sdp_source_info_gn_id <= TO_UVEC(c_gn_index, 5); - - exp_sdp_cep_header.app.sdp_reserved <= TO_UVEC( 0, 40); - exp_sdp_cep_header.app.sdp_beamlet_scale <= TO_UVEC( c_exp_beamlet_scale, 16); - exp_sdp_cep_header.app.sdp_beamlet_index <= TO_UVEC( 0, 16); -- depends on bset - exp_sdp_cep_header.app.sdp_nof_blocks_per_packet <= TO_UVEC( c_sdp_cep_nof_blocks_per_packet, 8); - exp_sdp_cep_header.app.sdp_nof_beamlets_per_block <= TO_UVEC(c_sdp_cep_nof_beamlets_per_block, 16); - exp_sdp_cep_header.app.sdp_block_period <= c_exp_sdp_info.block_period; - - exp_sdp_cep_header.app.dp_bsn <= TO_UVEC(exp_dp_bsn, 64); -- depends on bset and time - END PROCESS; + exp_sdp_cep_header <= func_sdp_compose_cep_header(c_cep_ip_src_addr, + c_exp_ip_header_checksum, + c_exp_sdp_info, + c_last_gn, + c_exp_beamlet_scale, + c_exp_beamlet_index, + exp_dp_bsn); rx_sdp_cep_header <= func_sdp_map_cep_header(rx_hdr_fields_raw); @@ -1424,4 +1459,5 @@ BEGIN -- To view the 64 bit 10GbE offload data more easily in the Wave window rx_beamlet_data <= rx_beamlet_sosi.data(c_longword_w-1 DOWNTO 0); + END tb; diff --git a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml index 94c9ce8b457e0347216606a067062f7a58981f36..17ecf33f68ea58c091536657741177c6ea315f25 100644 --- a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml +++ b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml @@ -189,11 +189,15 @@ peripherals: https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L1%20Interface%20Control%20Documents/STAT%20to%20CEP%20ICD + The RO value reads the MM value, not the used data path value. Therefore simply use access + mode RW for all fields. Whether the write RW MM value is used in the packet header depends + on the c_sdp_cep_hdr_field_sel bit selection setting in sdp_pkg.vhd. + From tb_dp_offload_tx_v3.vhd simulation it follows that: . the header fields are stored in reversed address order due to that the array in VHDL has range (h downto 0) where the first header field (eth_destination_mac) is at index h. . the RO fields are filled in by the logic, when the packet header is transmitted, however - the read value does not still represents the MM write value, not the transmitted value. + the read value still represents the MM value, not the transmitted value. . dp_bsn with user_width = 64 is stored as: word byte addr addr bits @@ -208,8 +212,8 @@ peripherals: fields: # eth field group - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0xA0 } - - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RO, address_offset: 0x98 } - - - { field_name: eth_type, mm_width: 16, access_mode: RO, address_offset: 0x94 } + - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x98 } + - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x94 } # ip field group - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x90 } - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x8C } @@ -229,8 +233,8 @@ peripherals: - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x58 } - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x54 } # application field group - - - { field_name: sdp_marker, mm_width: 8, access_mode: RO, address_offset: 0x50 } - - - { field_name: sdp_version_id, mm_width: 8, access_mode: RO, address_offset: 0x4C } + - - { field_name: sdp_marker, mm_width: 8, access_mode: RW, address_offset: 0x50 } + - - { field_name: sdp_version_id, mm_width: 8, access_mode: RW, address_offset: 0x4C } - - { field_name: sdp_observation_id, mm_width: 32, access_mode: RW, address_offset: 0x48 } - - { field_name: sdp_station_id, mm_width: 16, access_mode: RW, address_offset: 0x44 } - - { field_name: sdp_source_info_antenna_band_index, mm_width: 1, bit_offset: 15, access_mode: RW, address_offset: 0x40 } @@ -266,14 +270,18 @@ peripherals: The statistics offload header fields are described in ICD SC-SDP [1]. + The RO value reads the MM value, not the used data path value. Therefore simply use access + mode RW for all fields. Whether the write RW MM value is used in the packet header depends + on the c_sdp_stat_hdr_field_sel bit selection setting in sdp_pkg.vhd. + [1] https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD " fields: # eth field group - - { field_name: word_align, mm_width: 16, access_mode: RW, address_offset: 0xAC } - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0xA4 } - - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RO, address_offset: 0x9C } - - - { field_name: eth_type, mm_width: 16, access_mode: RO, address_offset: 0x98 } + - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x9C } + - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x98 } # ip field group - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x94 } - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x90 } @@ -293,8 +301,8 @@ peripherals: - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x5C } - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x58 } # application field group - - - { field_name: sdp_marker, mm_width: 8, access_mode: RO, address_offset: 0x54 } - - - { field_name: sdp_version_id, mm_width: 8, access_mode: RO, address_offset: 0x50 } + - - { field_name: sdp_marker, mm_width: 8, access_mode: RW, address_offset: 0x54 } + - - { field_name: sdp_version_id, mm_width: 8, access_mode: RW, address_offset: 0x50 } - - { field_name: sdp_observation_id, mm_width: 32, access_mode: RW, address_offset: 0x4C } - - { field_name: sdp_station_id, mm_width: 16, access_mode: RW, address_offset: 0x48 } - - { field_name: sdp_source_info_antenna_band_index, mm_width: 1, bit_offset: 15, access_mode: RW, address_offset: 0x44 } @@ -335,14 +343,18 @@ peripherals: The statistics offload header fields are described in ICD SC-SDP [1]. + The RO value reads the MM value, not the used data path value. Therefore simply use access + mode RW for all fields. Whether the write RW MM value is used in the packet header depends + on the c_sdp_stat_hdr_field_sel bit selection setting in sdp_pkg.vhd. + [1] https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD " fields: # eth field group - - { field_name: word_align, mm_width: 16, access_mode: RW, address_offset: 0xAC } - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0xA4 } - - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RO, address_offset: 0x9C } - - - { field_name: eth_type, mm_width: 16, access_mode: RO, address_offset: 0x98 } + - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x9C } + - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x98 } # ip field group - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x94 } - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x90 } @@ -362,8 +374,8 @@ peripherals: - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x5C } - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x58 } # application field group - - - { field_name: sdp_marker, mm_width: 8, access_mode: RO, address_offset: 0x54 } - - - { field_name: sdp_version_id, mm_width: 8, access_mode: RO, address_offset: 0x50 } + - - { field_name: sdp_marker, mm_width: 8, access_mode: RW, address_offset: 0x54 } + - - { field_name: sdp_version_id, mm_width: 8, access_mode: RW, address_offset: 0x50 } - - { field_name: sdp_observation_id, mm_width: 32, access_mode: RW, address_offset: 0x4C } - - { field_name: sdp_station_id, mm_width: 16, access_mode: RW, address_offset: 0x48 } - - { field_name: sdp_source_info_antenna_band_index, mm_width: 1, bit_offset: 15, access_mode: RW, address_offset: 0x44 } @@ -405,14 +417,18 @@ peripherals: The statistics offload header fields are described in ICD SC-SDP [1]. + The RO value reads the MM value, not the used data path value. Therefore simply use access + mode RW for all fields. Whether the write RW MM value is used in the packet header depends + on the c_sdp_stat_hdr_field_sel bit selection setting in sdp_pkg.vhd. + [1] https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD " fields: # eth field group - - { field_name: word_align, mm_width: 16, access_mode: RW, address_offset: 0xAC } - - { field_name: eth_destination_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0xA4 } - - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RO, address_offset: 0x9C } - - - { field_name: eth_type, mm_width: 16, access_mode: RO, address_offset: 0x98 } + - - { field_name: eth_source_mac, mm_width: 32, user_width: 48, radix: uint64, access_mode: RW, address_offset: 0x9C } + - - { field_name: eth_type, mm_width: 16, access_mode: RW, address_offset: 0x98 } # ip field group - - { field_name: ip_version, mm_width: 4, access_mode: RW, address_offset: 0x94 } - - { field_name: ip_header_length, mm_width: 4, access_mode: RW, address_offset: 0x90 } @@ -432,8 +448,8 @@ peripherals: - - { field_name: udp_length, mm_width: 16, access_mode: RW, address_offset: 0x5C } - - { field_name: udp_checksum, mm_width: 16, access_mode: RW, address_offset: 0x58 } # application field group - - - { field_name: sdp_marker, mm_width: 8, access_mode: RO, address_offset: 0x54 } - - - { field_name: sdp_version_id, mm_width: 8, access_mode: RO, address_offset: 0x50 } + - - { field_name: sdp_marker, mm_width: 8, access_mode: RW, address_offset: 0x54 } + - - { field_name: sdp_version_id, mm_width: 8, access_mode: RW, address_offset: 0x50 } - - { field_name: sdp_observation_id, mm_width: 32, access_mode: RW, address_offset: 0x4C } - - { field_name: sdp_station_id, mm_width: 16, access_mode: RW, address_offset: 0x48 } - - { field_name: sdp_source_info_antenna_band_index, mm_width: 1, bit_offset: 15, access_mode: RW, address_offset: 0x44 } diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd index 6fa7c9cf74f206ff9710b89107ab1822c7f389f4..d77c55d4e5833d2bb638e62cc1da3c5ee73f34cc 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd @@ -103,8 +103,8 @@ ENTITY node_sdp_adc_input_and_timing IS -- Streaming data output out_sosi_arr : OUT t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0); - dp_bsn_source_restart : OUT STD_LOGIC - + dp_bsn_source_restart : OUT STD_LOGIC; + dp_bsn_source_new_interval : OUT STD_LOGIC ); END node_sdp_adc_input_and_timing; @@ -120,6 +120,7 @@ ARCHITECTURE str OF node_sdp_adc_input_and_timing IS -- Frame parameters CONSTANT c_bs_sync_timeout : NATURAL := g_bsn_nof_clk_per_sync + g_bsn_nof_clk_per_sync / 10; -- +10% margin CONSTANT c_bs_bsn_w : NATURAL := 64; -- > 51; + CONSTANT c_bs_aux_w : NATURAL := 2; CONSTANT c_bs_block_size : NATURAL := c_sdp_N_fft; -- =1024; CONSTANT c_dp_fifo_dc_size : NATURAL := 64; @@ -129,6 +130,9 @@ ARCHITECTURE str OF node_sdp_adc_input_and_timing IS SIGNAL rx_sysref : STD_LOGIC; SIGNAL rx_bsn_source_restart : STD_LOGIC; + SIGNAL rx_bsn_source_new_interval : STD_LOGIC; + SIGNAL rx_aux : STD_LOGIC_VECTOR(c_bs_aux_w-1 DOWNTO 0); + SIGNAL dp_aux : STD_LOGIC_VECTOR(c_bs_aux_w-1 DOWNTO 0); -- Sosis and sosi arrays SIGNAL rx_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); @@ -283,7 +287,8 @@ BEGIN -- Streaming clock domain bs_sosi => bs_sosi, - bs_restart => rx_bsn_source_restart + bs_restart => rx_bsn_source_restart, + bs_new_interval => rx_bsn_source_new_interval ); u_bsn_trigger_wg : ENTITY dp_lib.mms_dp_bsn_scheduler @@ -494,12 +499,22 @@ BEGIN -- Output Stage -- . Thin dual clock fifo to cross from jesd frame clock (rx_clk) to dp_clk domain ----------------------------------------------------------------------------- + + -- rx_aux is synchronous with st_sosi_arr + rx_aux(0) <= rx_bsn_source_restart; + rx_aux(1) <= rx_bsn_source_new_interval; + + -- dp_aux is synchronous with out_sosi_arr + dp_bsn_source_restart <= dp_aux(0); + dp_bsn_source_new_interval <= dp_aux(1); + u_dp_fifo_dc_arr : ENTITY dp_lib.dp_fifo_dc_arr GENERIC MAP ( g_nof_streams => c_sdp_S_pn, g_data_w => c_sdp_W_adc, g_data_signed => TRUE, g_bsn_w => c_bs_bsn_w, + g_aux_w => c_bs_aux_w, g_use_empty => FALSE, g_use_ctrl => TRUE, g_use_sync => TRUE, @@ -514,12 +529,12 @@ BEGIN rd_clk => dp_clk, snk_in_arr => st_sosi_arr, src_out_arr => out_sosi_arr, - in_aux(0) => rx_bsn_source_restart, - out_aux(0) => dp_bsn_source_restart + in_aux => rx_aux, + out_aux => dp_aux ); ------------------------------------------------------------------------------ + ----------------------------------------------------------------------------- -- JESD Control register ----------------------------------------------------------------------------- u_mm_jesd_ctrl_reg : ENTITY common_lib.common_reg_r_w diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd index e94ce343eca19537f3c2d7b261c7f9e187b5471d..a9d90d2212382da37e08c0c84863e4b143aa2bee 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_beamformer.vhd @@ -49,6 +49,8 @@ ENTITY node_sdp_beamformer IS dp_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; + dp_bsn_source_new_interval : IN STD_LOGIC; + in_sosi_arr : IN t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0); from_ri_sosi : IN t_dp_sosi; to_ri_sosi : OUT t_dp_sosi; @@ -377,7 +379,9 @@ BEGIN reg_bsn_monitor_v2_offload_copi => reg_bsn_monitor_v2_bst_offload_copi, reg_bsn_monitor_v2_offload_cipo => reg_bsn_monitor_v2_bst_offload_cipo, - in_sosi => bf_sum_sosi, + in_sosi => bf_sum_sosi, + new_interval => dp_bsn_source_new_interval, + out_sosi => bst_udp_sosi, out_siso => bst_udp_siso, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd index 5c11d1481a6dbf3c7ea9edb10ebb7dbdb7031fa8..8f37ffab21acff1c735cf1f091cea7a41c204913 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_filterbank.vhd @@ -57,14 +57,15 @@ ENTITY node_sdp_filterbank IS dp_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; + dp_bsn_source_restart : IN STD_LOGIC; + dp_bsn_source_new_interval : IN STD_LOGIC; + in_sosi_arr : IN t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0); pfb_sosi_arr : OUT t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0); fsub_sosi_arr : OUT t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0); sst_udp_sosi : OUT t_dp_sosi; sst_udp_siso : IN t_dp_siso := c_dp_siso_rst; - dp_bsn_source_restart : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; mm_clk : IN STD_LOGIC; @@ -128,6 +129,7 @@ ARCHITECTURE str OF node_sdp_filterbank IS SIGNAL selector_en : STD_LOGIC; SIGNAL weighted_subbands_flag : STD_LOGIC; SIGNAL dp_bsn_source_restart_pipe : STD_LOGIC; + BEGIN --------------------------------------------------------------- -- SPECTRAL INVERSION @@ -360,7 +362,9 @@ BEGIN reg_bsn_monitor_v2_offload_copi => reg_bsn_monitor_v2_sst_offload_copi, reg_bsn_monitor_v2_offload_cipo => reg_bsn_monitor_v2_sst_offload_cipo, - in_sosi => dp_selector_out_sosi_arr(0), + in_sosi => dp_selector_out_sosi_arr(0), + new_interval => dp_bsn_source_new_interval, + out_sosi => sst_udp_sosi, out_siso => sst_udp_siso, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd index ad2e2a4f969f647dd066c35e6d2b598202e39210..ba01e264bb1e097b4c52a0d4b5eb161fcdb2f528 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_oversampled_filterbank.vhd @@ -59,14 +59,15 @@ ENTITY node_sdp_oversampled_filterbank IS dp_clk : IN STD_LOGIC; dp_rst : IN STD_LOGIC; + dp_bsn_source_restart : IN STD_LOGIC; + dp_bsn_source_new_interval : IN STD_LOGIC; + in_sosi_arr : IN t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0); pfb_sosi_arr : OUT t_dp_sosi_arr(c_sdp_R_os * c_sdp_P_pfb-1 DOWNTO 0); fsub_sosi_arr : OUT t_dp_sosi_arr(c_sdp_R_os * c_sdp_P_pfb-1 DOWNTO 0); sst_udp_sosi : OUT t_dp_sosi; sst_udp_siso : IN t_dp_siso := c_dp_siso_rst; - dp_bsn_source_restart : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; mm_clk : IN STD_LOGIC; @@ -670,7 +671,9 @@ BEGIN reg_bsn_monitor_v2_offload_copi => reg_bsn_monitor_v2_sst_offload_copi, reg_bsn_monitor_v2_offload_cipo => reg_bsn_monitor_v2_sst_offload_cipo, - in_sosi => dp_selector_out_sosi_arr(0), + in_sosi => dp_selector_out_sosi_arr(0), + new_interval => dp_bsn_source_new_interval, + out_sosi => sst_udp_sosi, out_siso => sst_udp_siso, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd index 091abd86db86fa50bb89b62b9838ed5ff845e22b..b14d63d3cc046861baef44eebfb98dce5ab46a48 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_output.vhd @@ -64,6 +64,7 @@ ENTITY sdp_beamformer_output IS beamlet_scale : IN STD_LOGIC_VECTOR(c_sdp_W_beamlet_scale-1 DOWNTO 0); gn_id : IN STD_LOGIC_VECTOR(c_sdp_W_gn_id-1 DOWNTO 0); + -- Source MAC/IP/UDP are not used, c_sdp_cep_hdr_field_sel selects MM programmable instead eth_src_mac : IN STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0); ip_src_addr : IN STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0); udp_src_port : IN STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0); @@ -98,7 +99,8 @@ ARCHITECTURE str OF sdp_beamformer_output IS SIGNAL common_fifo_rd_req : STD_LOGIC; SIGNAL payload_err : STD_LOGIC_VECTOR(0 DOWNTO 0); - SIGNAL dp_offload_tx_hdr_fields : STD_LOGIC_VECTOR(1023 DOWNTO 0); + -- Default set all data path driven header fields to 0 + SIGNAL dp_offload_tx_hdr_fields : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS=>'0'); BEGIN @@ -204,6 +206,62 @@ BEGIN ------------------------------------------------------------------------------- -- Assemble offload info ------------------------------------------------------------------------------- + -- Whether the dp_offload_tx_hdr_fields value is actually used in the Tx header depends on c_sdp_cep_hdr_field_sel + -- . c_sdp_cep_hdr_field_sel = "111"&"111111111011"&"1110"&"1100"&"00000010"&"100110"&"0"; + -- eth ip udp app + -- where 0 = data path, 1 = MM controlled. The '0' fields are assigned here via dp_offload_tx_hdr_fields. + -- in order: + -- access field + -- MM eth_dst_mac + -- MM eth_src_mac + -- MM eth_type + -- + -- MM ip_version + -- MM ip_header_length + -- MM ip_services + -- MM ip_total_length + -- MM ip_identification + -- MM ip_flags + -- MM ip_fragment_offset + -- MM ip_time_to_live + -- MM ip_protocol + -- DP ip_header_checksum --> added by u_tr_10GbE_ip_checksum + -- MM ip_src_addr + -- MM ip_dst_addr + -- + -- MM udp_src_port + -- MM udp_dst_port + -- MM udp_total_length + -- DP udp_checksum --> default fixed 0, so not used, not calculated here or in tr_10GbE + -- because would require store and forward + -- + -- MM sdp_marker + -- MM sdp_version_id + -- DP sdp_observation_id + -- DP sdp_station_id + -- + -- DP sdp_source_info_antenna_band_id + -- DP sdp_source_info_nyquist_zone_id + -- DP sdp_source_info_f_adc + -- DP sdp_source_info_fsub_type + -- DP sdp_source_info_payload_error + -- DP sdp_source_info_repositioning_flag + -- MM sdp_source_info_beamlet_width + -- DP sdp_source_info_gn_id + -- + -- MM sdp_reserved + -- DP sdp_beamlet_scale + -- DP sdp_beamlet_index + -- MM sdp_nof_blocks_per_packet + -- MM sdp_nof_beamlets_per_block + -- DP sdp_block_period + -- + -- DP dp_bsn + + -- Use MM programmable source MAC/IP/UDP instead of source MAC/IP/UDP based on node ID. This is necessary because + -- beamlet packets from different stations must have different source MAC/IP/UDP. + -- Hence the eth_src_mac, udp_src_port and ip_src_addr are ignored, because c_sdp_cep_hdr_field_sel selects MM control, + -- but keep the code to be able to enable using them by just changing the selection bit. dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "eth_src_mac" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "eth_src_mac" )) <= eth_src_mac; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "udp_src_port") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "udp_src_port")) <= udp_src_port; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "ip_src_addr" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_src_addr" )) <= ip_src_addr; @@ -217,7 +275,7 @@ BEGIN dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_payload_error" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_payload_error" )) <= payload_err; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_repositioning_flag" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_repositioning_flag" )) <= SLV(sdp_info.beam_repositioning_flag); dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id" )) <= gn_id; - dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_reserved" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_reserved" )) <= (OTHERS => '0'); + dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale" )) <= beamlet_scale; dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_index" )) <= TO_UVEC(c_beamlet_index, c_halfword_w); dp_offload_tx_hdr_fields(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period" ) DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period" )) <= sdp_info.block_period; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index b08a4b80ef3714623c82db66b4cfacf35dad5d08..f881389b6449c6b103f16031f52e9acee07e4394 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -209,9 +209,9 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_stat_app_header_len : NATURAL := 32; CONSTANT c_sdp_stat_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"001B217176B9"; -- 001B217176B9 = DOP36-enp2s0 - CONSTANT c_sdp_stat_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 00:22:86:08:pp:qq + CONSTANT c_sdp_stat_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 00:22:86:08:pp:qq = UNB_ETH_SRC_MAC_BASE in libraries/unb_osy/unbos_eth.h CONSTANT c_sdp_stat_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"0A6300FE"; -- 0A6300FE = '10.99.0.254' = DOP36-enp2s0 - CONSTANT c_sdp_stat_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63"; -- 10.99.xx.yy + CONSTANT c_sdp_stat_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63"; -- 10.99.xx.yy = g_base_ip in ctrl_unb2#_board.vhd used in libraries/unb_osy/unbos_eth.c CONSTANT c_sdp_stat_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5001, 16); -- 0x1389 = 5001 CONSTANT c_sdp_sst_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D0"; -- TBC, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0]) CONSTANT c_sdp_bst_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D1"; -- TBC @@ -219,20 +219,38 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_stat_version_id : NATURAL := 5; CONSTANT c_sdp_stat_nof_hdr_fields : NATURAL := 1+3+12+4+20+1; -- 608b; 19 32b words - CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- 0=data path, 1=MM controlled ---CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0101"&"0100"&"000000000"&"0000100"&"0"; -- 0=data path, 1=MM controlled TODO (26 nov 2021) ---CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "0"&"100"&"000000010001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- 0=data path, 1=MM controlled TODO + -- hdr_field_sel bit selects where the hdr_field value is set: + -- . 0 = data path controlled, value is set in sdp_statistics_offload.vhd, so field_default() is not used. + -- . 1 = MM controlled, value is set via MM or by the field_default(), so any data path setting in + -- sdp_statistics_offload.vhd is not used. + -- Remarks: + -- . For constant values it is convenient to use MM controlled, because then the field_default() + -- is used that can be set here in c_sdp_stat_hdr_field_arr. + -- . For reserved values it is convenient to use MM controlled, because then in future they + -- could still be changed via MM without having to recompile the FW. + -- . Typically only use data path controlled if the value has to be set dynamically, so dependent + -- on the state of the FW. + -- . If a data path controlled field is not set in the FW, then it defaults to 0 by declaring + -- hdr_fields_in_arr with all 0. Hence e.g. udp_checksum = 0 can be achieve via data path + -- and default hdr_fields_in_arr = 0 or via MM controlled and field_default(0). + -- eth ip udp app + CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- current +--CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0101"&"0100"&"000000000"&"0000100"&"0"; -- previous 26 nov 2021 +--CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "0"&"100"&"000000010001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- initial + + -- Default use destination MAC/IP/UDP = 0, so these have to be MM programmed before + -- statistics offload packets can be send. CONSTANT c_sdp_stat_hdr_field_arr : t_common_field_arr(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := ( ( field_name_pad("word_align" ), "RW", 16, field_default(0) ), -- Tx TSE IP will strip these 2 padding bytes - ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(c_sdp_stat_eth_dst_mac) ), + ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- c_sdp_stat_eth_dst_mac ( 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(0) ), + ( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ), -- differs for SST, BST, XST so set by data path ( 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) ), @@ -240,14 +258,14 @@ PACKAGE sdp_pkg is ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), - ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(c_sdp_stat_ip_dst_addr) ), + ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- c_sdp_stat_ip_dst_addr ( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ), - ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(c_sdp_stat_udp_dst_port) ), - ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), + ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_sdp_stat_udp_dst_port + ( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ), -- differs for SST, BST, XST so set by data path ( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), - ( field_name_pad("sdp_marker" ), "RW", 8, field_default(0) ), + ( field_name_pad("sdp_marker" ), "RW", 8, field_default(0) ), -- differs for SST, BST, XST so set by data path ( field_name_pad("sdp_version_id" ), "RW", 8, field_default(c_sdp_stat_version_id) ), ( field_name_pad("sdp_observation_id" ), "RW", 32, field_default(0) ), ( field_name_pad("sdp_station_id" ), "RW", 16, field_default(0) ), @@ -346,11 +364,20 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_cep_packet_nof_longwords : NATURAL := ceil_div(c_sdp_cep_header_len, c_longword_sz) + c_sdp_cep_payload_nof_longwords; -- without tail CRC, the CRC is applied by 10GbE MAC CONSTANT c_sdp_cep_nof_hdr_fields : NATURAL := 3+12+4+18+1; -- c_sdp_cep_header_len / c_longword_sz = 74 / 8 = 9.25 64b words = 592b - CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111001"&"0111"&"1100"&"00000010"&"000110"&"0"; -- 0=data path, 1=MM controlled TODO ---CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "100"&"000000010001"&"0100"&"0100"&"00000000"&"101000"&"0"; -- 0=data path, 1=MM controlled TODO - - CONSTANT c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( - ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ), + -- hdr_field_sel bit selects where the hdr_field value is set: + -- . 0 = data path controlled, value is set in sdp_beamformer_output.vhd, so field_default() is not used. + -- . 1 = MM controlled, value is set via MM or by the field_default(), so any data path setting in + -- sdp_beamformer_output.vhd is not used. + -- Remarks: see remarks at c_sdp_stat_nof_hdr_fields. + -- eth ip udp app + CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "111"&"111111111011"&"1110"&"1100"&"00000010"&"100110"&"0"; -- current +--CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111001"&"0111"&"1100"&"00000010"&"000110"&"0"; -- previous 27 sep 2022 +--CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "100"&"000000010001"&"0100"&"0100"&"00000000"&"101000"&"0"; -- initial + + -- Default use source MAC/IP/UDP = 0 and destination MAC/IP/UDP = 0, so these have to be MM programmed + -- before beamlet output packets can be send. + CONSTANT c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := ( + ( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(0) ), -- c_sdp_cep_eth_dst_mac ( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ), ( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ), @@ -365,10 +392,10 @@ PACKAGE sdp_pkg is ( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ), ( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ), ( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ), - ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(c_sdp_cep_ip_dst_addr) ), + ( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(0) ), -- c_sdp_cep_ip_dst_addr ( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ), - ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(c_sdp_cep_udp_dst_port) ), + ( field_name_pad("udp_dst_port" ), "RW", 16, field_default(0) ), -- c_sdp_cep_udp_dst_port ( field_name_pad("udp_total_length" ), "RW", 16, field_default(c_sdp_cep_udp_total_length) ), ( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ), @@ -725,9 +752,9 @@ PACKAGE BODY sdp_pkg IS FUNCTION func_sdp_get_stat_udp_src_port(g_statistics_type : STRING; gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS CONSTANT c_gn_index : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(gn_index, 8); BEGIN - RETURN sel_a_b(g_statistics_type="BST", c_sdp_bst_udp_src_port_15_8 & c_gn_index, -- BST = 0xD0 & gn_index - sel_a_b(g_statistics_type="XST", c_sdp_xst_udp_src_port_15_8 & c_gn_index, -- XST = 0xD1 & gn_index - c_sdp_sst_udp_src_port_15_8 & c_gn_index)); -- SST = 0xD2 & gn_index, SST_OS + RETURN sel_a_b(g_statistics_type="BST", c_sdp_bst_udp_src_port_15_8 & c_gn_index, -- BST = 0xD1 & gn_index + sel_a_b(g_statistics_type="XST", c_sdp_xst_udp_src_port_15_8 & c_gn_index, -- XST = 0xD2 & gn_index + c_sdp_sst_udp_src_port_15_8 & c_gn_index)); -- SST = 0xD0 & gn_index, SST_OS END func_sdp_get_stat_udp_src_port; FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL IS diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd index cfffdf2e7b32a003df111b5afd60da164af0a3d2..90e1a6ab1a9df2782be6b82791db11f27ca7638d 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_station.vhd @@ -536,7 +536,8 @@ ARCHITECTURE str OF sdp_station IS SIGNAL lane_rx_board_sosi_arr : t_dp_sosi_arr(c_nof_lane-1 DOWNTO 0); SIGNAL lane_tx_board_sosi_arr : t_dp_sosi_arr(c_nof_lane-1 DOWNTO 0); - SIGNAL dp_bsn_source_restart : STD_LOGIC; + SIGNAL dp_bsn_source_restart : STD_LOGIC; -- used to restart WPFB sync interval timing + SIGNAL dp_bsn_source_new_interval : STD_LOGIC; -- used to mask out first sync interval for SST and BST offload SIGNAL bf_udp_sosi_arr : t_dp_sosi_arr(c_sdp_N_beamsets-1 DOWNTO 0); SIGNAL bf_udp_siso_arr : t_dp_siso_arr(c_sdp_N_beamsets-1 DOWNTO 0); @@ -581,11 +582,16 @@ BEGIN ----------------------------------------------------------------------------- -- SDP Info register ----------------------------------------------------------------------------- - -- derive MAC, IP and UDP Port + -- . derive beamlet output MAC, IP and UDP Port as in https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L1%20Interface%20Control%20Documents/STAT%20to%20CEP%20ICD + -- . these FW default beamlet output source MAC, IP and UDP port for 10GbE are NOT used in sdp_beamformer_output, because + -- instead they are MM programmable as set by c_sdp_cep_hdr_field_sel cep_eth_src_mac <= c_sdp_cep_eth_src_mac_47_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & RESIZE_UVEC(this_chip_id, c_byte_w); -- Simply use chip_id since we only use 1 of the 6*4 = 24 10GbE port. cep_ip_src_addr <= c_sdp_cep_ip_src_addr_31_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & INCR_UVEC(RESIZE_UVEC(this_chip_id, c_byte_w), 1); -- +1 to avoid IP = *.*.*.0 cep_udp_src_port <= c_sdp_cep_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w); + -- . derive statistics offload source MAC/IP/UDP as in: https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD + -- . these FW default statistics offload source MAC, IP and UDP port for 1GbE are used, as set by c_sdp_stat_hdr_field_sel. + -- . the source MAC, IP are the same as for the M&C, because M&C and statistics offload share the same 1GbE stat_eth_src_mac <= c_sdp_stat_eth_src_mac_47_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & RESIZE_UVEC(this_chip_id, c_byte_w); -- Simply use chip_id since we only use 1 of the 6*4 = 24 10GbE port. stat_ip_src_addr <= c_sdp_stat_ip_src_addr_31_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & INCR_UVEC(RESIZE_UVEC(this_chip_id, c_byte_w), 1); -- +1 to avoid IP = *.*.*.0 sst_udp_src_port <= c_sdp_sst_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w); @@ -686,7 +692,8 @@ BEGIN -- Streaming data output out_sosi_arr => ait_sosi_arr, - dp_bsn_source_restart => dp_bsn_source_restart + dp_bsn_source_restart => dp_bsn_source_restart, + dp_bsn_source_new_interval => dp_bsn_source_new_interval ); ----------------------------------------------------------------------------- @@ -708,7 +715,8 @@ BEGIN in_sosi_arr => ait_sosi_arr, fsub_sosi_arr => fsub_sosi_arr, dp_bsn_source_restart => dp_bsn_source_restart, - + dp_bsn_source_new_interval => dp_bsn_source_new_interval, + sst_udp_sosi => udp_tx_sosi_arr(0), sst_udp_siso => udp_tx_siso_arr(0), @@ -765,6 +773,7 @@ BEGIN in_sosi_arr => ait_sosi_arr, fsub_sosi_arr => fsub_oversampled_sosi_arr, dp_bsn_source_restart => dp_bsn_source_restart, + dp_bsn_source_new_interval => dp_bsn_source_new_interval, sst_udp_sosi => udp_tx_sosi_arr(0), sst_udp_siso => udp_tx_siso_arr(0), @@ -889,8 +898,10 @@ BEGIN bf_udp_sosi => bf_udp_sosi_arr(beamset_id), bf_udp_siso => bf_udp_siso_arr(beamset_id), bst_udp_sosi => udp_tx_sosi_arr(2+ beamset_id), - bst_udp_siso => udp_tx_siso_arr(2+ beamset_id), - + bst_udp_siso => udp_tx_siso_arr(2+ beamset_id), + + dp_bsn_source_new_interval => dp_bsn_source_new_interval, + mm_rst => mm_rst, mm_clk => mm_clk, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd index eb9d5dec6ca46fccb48f5d7bf9a21c1ed4e4ed56..a2a5be3b5aca6f5976f66a54be199d132896d159 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -142,7 +142,7 @@ ENTITY sdp_statistics_offload IS -- Input timing regarding the integration interval of the statistics in_sosi : IN t_dp_sosi; - new_interval : IN STD_LOGIC := '0'; + new_interval : IN STD_LOGIC; -- Streaming output of offloaded statistics packets out_sosi : OUT t_dp_sosi; @@ -212,6 +212,8 @@ ARCHITECTURE str OF sdp_statistics_offload IS payload_err : STD_LOGIC; END RECORD; + CONSTANT c_input_rst : t_input := (0, 0, (OTHERS=>'0'), 0, c_sdp_crosslets_info_rst, 0, '0'); -- to avoid initial 'X' in sim + -- Offload control TYPE t_reg IS RECORD packet_count : NATURAL RANGE 0 TO c_nof_packets_max; @@ -230,13 +232,15 @@ ARCHITECTURE str OF sdp_statistics_offload IS SIGNAL p : t_parameters; - SIGNAL reg_input : t_input; - SIGNAL prev_input : t_input; - SIGNAL hdr_input : t_input; + SIGNAL reg_input : t_input := c_input_rst; + SIGNAL prev_input : t_input := c_input_rst; + SIGNAL hdr_input : t_input := c_input_rst; SIGNAL r : t_reg; SIGNAL nxt_r : t_reg; + SIGNAL reg_new_interval : STD_LOGIC; + SIGNAL data_id_rec : t_sdp_stat_data_id; SIGNAL data_id_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); @@ -273,33 +277,64 @@ ARCHITECTURE str OF sdp_statistics_offload IS BEGIN ------------------------------------------------------------------------------- - -- Assemble offload header info, for data path fields that are selected by: + -- Assemble offload header info + ------------------------------------------------------------------------------- + -- Whether the dp_offload_tx_hdr_fields value is actually used in the Tx header depends on c_sdp_stat_hdr_field_sel -- c_sdp_stat_hdr_field_sel = "1"&"101"&"111011111001"&"0100"&"0100"&"000000010"&"1000000"&"0" -- eth ip udp app -- where 0 = data path, 1 = MM controlled. The '0' fields are assigned here in dp_header_info -- in order: - -- . eth: eth_src_mac - -- . ip: ip_total_length, - -- ip_header_checksum (not here, will be filled in by 1GbE eth component), - -- ip_src_addr - -- . udp: udp_src_port, - -- udp_total_length - -- udp_checksum, (not here, also not calculated in 1GbE eth component because would - -- require store and forward, send default 0) - -- . app: - sdp_marker, sdp_observation_id, sdp_station_id, - -- - sdp_source_info_antenna_band_id, - -- sdp_source_info_nyquist_zone_id, - -- sdp_source_info_f_adc, - -- sdp_source_info_fsub_type, - -- sdp_source_info_payload_error, - -- sdp_source_info_beam_repositioning_flag, - -- sdp_source_info_weighted_subbands_flag, - -- sdp_source_info_gn_id, - -- - sdp_integration_interval, sdp_data_id, sdp_nof_signal_inputs, - -- sdp_nof_bytes_per_statistic, - -- sdp_nof_statistics_per_packet, sdp_block_period - -- - dp_bsn - ------------------------------------------------------------------------------- + -- access field + -- MM word_align + -- + -- MM eth_dst_mac + -- DP eth_src_mac + -- MM eth_type + -- + -- MM ip_version + -- MM ip_header_length + -- MM ip_services + -- DP ip_total_length + -- MM ip_identification + -- MM ip_flags + -- MM ip_fragment_offset + -- MM ip_time_to_live + -- MM ip_protocol + -- DP ip_header_checksum --> not here, will be filled in by 1GbE eth component + -- DP ip_src_addr + -- MM ip_dst_addr + -- + -- DP udp_src_port + -- MM udp_dst_port + -- DP udp_total_length + -- DP udp_checksum --> default fixed 0, so not used, not calculated here or in 1GbE + -- eth component because would require store and forward + -- + -- DP sdp_marker + -- MM sdp_version_id + -- DP sdp_observation_id + -- DP sdp_station_id + -- + -- DP sdp_source_info_antenna_band_id + -- DP sdp_source_info_nyquist_zone_id + -- DP sdp_source_info_f_adc + -- DP sdp_source_info_fsub_type + -- DP sdp_source_info_payload_error + -- DP sdp_source_info_beam_repositioning_flag + -- DP sdp_source_info_weighted_subbands_flag + -- MM sdp_source_info_reserved + -- DP sdp_source_info_gn_id + -- + -- MM sdp_reserved + -- DP sdp_integration_interval + -- DP sdp_data_id + -- DP sdp_nof_signal_inputs + -- DP sdp_nof_bytes_per_statistic + -- DP sdp_nof_statistics_per_packet + -- DP sdp_block_period + -- + -- DP dp_bsn + dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "eth_src_mac" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "eth_src_mac" )) <= eth_src_mac; dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "ip_total_length" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_total_length" )) <= TO_UVEC(c_ip_total_length, 16); dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "ip_src_addr" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_src_addr" )) <= ip_src_addr; @@ -530,13 +565,15 @@ BEGIN nxt_r <= v; END PROCESS; + -- Register new_interval to ease timing closure. The new_interval will already be active + -- somewhat before the first in_sosi.sync arrives at the sdp_statistics_offload, due to + -- latency in the data path. + reg_new_interval <= new_interval WHEN rising_edge(dp_clk); + -- The in_trigger can skip the first in_sosi.sync. This is necessary if the -- in_sosi input can be restarted, because then at every restart there is - -- no valid previous in_sosi.sync interval yet. This is used for XST offload, - -- because then the in_sync interval is MM programmable. For SST and BST the - -- new_interval = '0' is not used, because then the in_sosi typically - -- remains on after it was started. - in_trigger <= in_sosi.sync AND NOT new_interval; + -- no valid previous in_sosi.sync interval yet. + in_trigger <= in_sosi.sync AND NOT reg_new_interval; u_mms_common_variable_delay : ENTITY common_lib.mms_common_variable_delay PORT MAP ( diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd index 42b3fb1b104e32cf41561ad475db4b499209dec1..762d2e704f509e7df83aa29ce4d8c0a85382368e 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_pkg.vhd @@ -32,13 +32,17 @@ USE common_lib.common_network_layers_pkg.ALL; USE work.sdp_pkg.ALL; PACKAGE tb_sdp_pkg is + + ----------------------------------------------------------------------------- + -- Derive low part of MAC, IP from global node (GN) index + ----------------------------------------------------------------------------- + FUNCTION func_sdp_gn_index_to_mac_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR; + FUNCTION func_sdp_gn_index_to_ip_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR; + ----------------------------------------------------------------------------- -- Statistics offload ----------------------------------------------------------------------------- - FUNCTION func_sdp_compose_stat_header(eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); -- eth header - eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); - ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); -- ip header - ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + FUNCTION func_sdp_compose_stat_header(ip_header_checksum : NATURAL; sdp_info : t_sdp_info; -- app header g_statistics_type : STRING; weighted_subbands_flag : STD_LOGIC; @@ -56,10 +60,7 @@ PACKAGE tb_sdp_pkg is ----------------------------------------------------------------------------- -- Beamlet output via 10GbE to CEP (= central processor) ----------------------------------------------------------------------------- - FUNCTION func_sdp_compose_cep_header(eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); -- eth header - eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); - ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); -- ip header - ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + FUNCTION func_sdp_compose_cep_header(ip_src_addr : STD_LOGIC_VECTOR; ip_header_checksum : NATURAL; sdp_info : t_sdp_info; -- app header gn_index : NATURAL; @@ -67,6 +68,13 @@ PACKAGE tb_sdp_pkg is beamlet_index : NATURAL; dp_bsn : NATURAL) RETURN t_sdp_cep_header; + FUNCTION func_sdp_compose_cep_header(ip_header_checksum : NATURAL; + sdp_info : t_sdp_info; -- app header + gn_index : NATURAL; + beamlet_scale : NATURAL; + beamlet_index : NATURAL; + dp_bsn : NATURAL) RETURN t_sdp_cep_header; + FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN; @@ -74,10 +82,23 @@ END PACKAGE tb_sdp_pkg; PACKAGE BODY tb_sdp_pkg IS - FUNCTION func_sdp_compose_stat_header(eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); -- eth header - eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); - ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); -- ip header - ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + FUNCTION func_sdp_gn_index_to_mac_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS + CONSTANT c_unb_nr : NATURAL := gn_index / 4; -- 4 PN per Uniboard2 + CONSTANT c_node_nr : NATURAL := gn_index MOD 4; + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr, 8); + BEGIN + RETURN c_mac_15_0; + END func_sdp_gn_index_to_mac_15_0; + + FUNCTION func_sdp_gn_index_to_ip_15_0(gn_index : NATURAL) RETURN STD_LOGIC_VECTOR IS + CONSTANT c_unb_nr : NATURAL := gn_index / 4; -- 4 PN per Uniboard2 + CONSTANT c_node_nr : NATURAL := gn_index MOD 4; + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(c_unb_nr, 8) & TO_UVEC(c_node_nr+1, 8); -- +1 to avoid IP = *.*.*.0 + BEGIN + RETURN c_ip_15_0; + END func_sdp_gn_index_to_ip_15_0; + + FUNCTION func_sdp_compose_stat_header(ip_header_checksum : NATURAL; sdp_info : t_sdp_info; -- app header g_statistics_type : STRING; weighted_subbands_flag : STD_LOGIC; @@ -89,6 +110,10 @@ PACKAGE BODY tb_sdp_pkg IS xst_signal_input_A : NATURAL; xst_signal_input_B : NATURAL; dp_bsn : NATURAL) RETURN t_sdp_stat_header IS + -- Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on gn_index + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := func_sdp_gn_index_to_mac_15_0(gn_index); + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := func_sdp_gn_index_to_ip_15_0(gn_index); + CONSTANT c_nof_statistics_per_packet : NATURAL := func_sdp_get_stat_nof_statistics_per_packet(g_statistics_type); CONSTANT c_udp_total_length : NATURAL := func_sdp_get_stat_udp_total_length(g_statistics_type); CONSTANT c_ip_total_length : NATURAL := func_sdp_get_stat_ip_total_length(g_statistics_type); @@ -98,8 +123,8 @@ PACKAGE BODY tb_sdp_pkg IS VARIABLE v_hdr : t_sdp_stat_header; BEGIN -- eth header - v_hdr.eth.dst_mac := eth_dst_mac; - v_hdr.eth.src_mac := eth_src_mac; + v_hdr.eth.dst_mac := c_sdp_stat_eth_dst_mac; + v_hdr.eth.src_mac := c_sdp_stat_eth_src_mac_47_16 & c_mac_15_0; v_hdr.eth.eth_type := x"0800"; -- ip header @@ -112,18 +137,13 @@ PACKAGE BODY tb_sdp_pkg IS v_hdr.ip.fragment_offset := TO_UVEC( 0, c_network_ip_fragment_offset_w); v_hdr.ip.time_to_live := TO_UVEC( 127, c_network_ip_time_to_live_w); v_hdr.ip.protocol := TO_UVEC( 17, c_network_ip_protocol_w); - v_hdr.ip.header_checksum := TO_UVEC( 0, c_network_ip_header_checksum_w); - v_hdr.ip.src_ip_addr := ip_src_addr; -- c_network_ip_addr_w - v_hdr.ip.dst_ip_addr := ip_dst_addr; -- c_network_ip_addr_w + -- the IP header check sum is calculated in IO eth, so still 0 here + v_hdr.ip.header_checksum := TO_UVEC(ip_header_checksum, c_network_ip_header_checksum_w); + v_hdr.ip.src_ip_addr := c_sdp_stat_ip_src_addr_31_16 & c_ip_15_0; -- c_network_ip_addr_w + v_hdr.ip.dst_ip_addr := c_sdp_stat_ip_dst_addr; -- c_network_ip_addr_w -- udp header - IF g_statistics_type = "SST" OR g_statistics_type = "SST_OS" THEN - v_hdr.udp.src_port := c_sdp_sst_udp_src_port_15_8 & TO_UVEC(gn_index, 8); - ELSIF g_statistics_type = "BST" THEN - v_hdr.udp.src_port := c_sdp_bst_udp_src_port_15_8 & TO_UVEC(gn_index, 8); - ELSIF g_statistics_type = "XST" THEN - v_hdr.udp.src_port := c_sdp_xst_udp_src_port_15_8 & TO_UVEC(gn_index, 8); - END IF; + v_hdr.udp.src_port := func_sdp_get_stat_udp_src_port(g_statistics_type, gn_index); v_hdr.udp.dst_port := c_sdp_stat_udp_dst_port; v_hdr.udp.total_length := TO_UVEC(c_udp_total_length, c_network_udp_port_w); v_hdr.udp.checksum := TO_UVEC( 0, c_network_udp_checksum_w); @@ -236,22 +256,20 @@ PACKAGE BODY tb_sdp_pkg IS RETURN TRUE; END func_sdp_verify_stat_header; - - FUNCTION func_sdp_compose_cep_header(eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); -- eth header - eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0); - ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); -- ip header - ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0); + FUNCTION func_sdp_compose_cep_header(ip_src_addr : STD_LOGIC_VECTOR; ip_header_checksum : NATURAL; sdp_info : t_sdp_info; -- app header gn_index : NATURAL; beamlet_scale : NATURAL; beamlet_index : NATURAL; dp_bsn : NATURAL) RETURN t_sdp_cep_header IS + -- Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on gn_index + CONSTANT c_mac_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := func_sdp_gn_index_to_mac_15_0(gn_index); VARIABLE v_hdr : t_sdp_cep_header; BEGIN -- eth header - v_hdr.eth.dst_mac := eth_dst_mac; - v_hdr.eth.src_mac := eth_src_mac; + v_hdr.eth.dst_mac := c_sdp_cep_eth_dst_mac; + v_hdr.eth.src_mac := c_sdp_cep_eth_src_mac_47_16 & c_mac_15_0; v_hdr.eth.eth_type := x"0800"; -- ip header @@ -265,8 +283,8 @@ PACKAGE BODY tb_sdp_pkg IS v_hdr.ip.time_to_live := TO_UVEC( 127, c_network_ip_time_to_live_w); v_hdr.ip.protocol := TO_UVEC( 17, c_network_ip_protocol_w); v_hdr.ip.header_checksum := TO_UVEC( ip_header_checksum, c_network_ip_header_checksum_w); - v_hdr.ip.src_ip_addr := ip_src_addr; -- c_network_ip_addr_w - v_hdr.ip.dst_ip_addr := ip_dst_addr; -- c_network_ip_addr_w + v_hdr.ip.src_ip_addr := ip_src_addr; -- c_network_ip_addr_w + v_hdr.ip.dst_ip_addr := c_sdp_cep_ip_dst_addr; -- c_network_ip_addr_w -- udp header v_hdr.udp.src_port := c_sdp_cep_udp_src_port_15_8 & TO_UVEC(gn_index, 8); @@ -300,6 +318,25 @@ PACKAGE BODY tb_sdp_pkg IS RETURN v_hdr; END func_sdp_compose_cep_header; + FUNCTION func_sdp_compose_cep_header(ip_header_checksum : NATURAL; + sdp_info : t_sdp_info; -- app header + gn_index : NATURAL; + beamlet_scale : NATURAL; + beamlet_index : NATURAL; + dp_bsn : NATURAL) RETURN t_sdp_cep_header IS + -- Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on gn_index + CONSTANT c_ip_15_0 : STD_LOGIC_VECTOR(15 DOWNTO 0) := func_sdp_gn_index_to_ip_15_0(gn_index); + CONSTANT c_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_cep_ip_src_addr_31_16 & c_ip_15_0; + BEGIN + RETURN func_sdp_compose_cep_header(c_ip_src_addr, + ip_header_checksum, + sdp_info, + gn_index, + beamlet_scale, + beamlet_index, + dp_bsn); + END func_sdp_compose_cep_header; + FUNCTION func_sdp_verify_cep_header(in_hdr, exp_hdr : t_sdp_cep_header) RETURN BOOLEAN IS VARIABLE v_beamlet_index : NATURAL; BEGIN diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd index fa06e0c1e3a4df6b9e42e0e8ebec979e3bbd489a..016b6bb8ca3fb8953ca3ce66650e4e4cbf5c505d 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_statistics_offload.vhd @@ -82,10 +82,10 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_offload_time : NATURAL := g_offload_time * g_gn_index; - -- In this tb simply use fixed network src addresses - CONSTANT c_eth_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := x"123456789ABC"; - CONSTANT c_ip_src_addr : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0) := x"0A090807"; - CONSTANT c_udp_src_port : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0) := func_sdp_get_stat_udp_src_port(g_statistics_type, g_gn_index); + -- Use sim default dst and src MAC, IP, UDP port from sdp_pkg.vhd and based on g_gn_index + CONSTANT c_node_eth_src_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := c_sdp_stat_eth_src_mac_47_16 & func_sdp_gn_index_to_mac_15_0(g_gn_index); + CONSTANT c_node_ip_src_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := c_sdp_stat_ip_src_addr_31_16 & func_sdp_gn_index_to_ip_15_0(g_gn_index); + CONSTANT c_node_udp_src_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := func_sdp_get_stat_udp_src_port(g_statistics_type, g_gn_index); -- Used mm_adresses on mm bus "enable_mosi/miso". CONSTANT c_reg_enable_mm_addr_enable : NATURAL := 0; @@ -98,6 +98,8 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_nof_signal_inputs : NATURAL := func_sdp_get_stat_nof_signal_inputs(g_statistics_type); CONSTANT c_nof_packets_max : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, c_sdp_N_crosslets_max); + CONSTANT c_exp_ip_header_checksum : NATURAL := 0; -- 0 in this local tb, calculated by IO eth when used in design + CONSTANT c_exp_sdp_info : t_sdp_info := (TO_UVEC(601, 16), -- station_id '0', -- antenna_band_index x"FFFFFFFF", -- observation_id @@ -284,13 +286,23 @@ BEGIN BEGIN proc_common_wait_until_high(mm_clk, init_ram_done); proc_common_wait_some_cycles(dp_clk, 10); + -- Mark first in_sosi.sync interval, starting and ending somewhat before in_sosi.sync, to + -- ensure that one in_sosi.sync occurs during new_interval. Use c_nof_clk_per_block as + -- sufficient margin to allow for some latency between new_interval and in_sosi.sync. + new_interval <= '1'; + proc_common_wait_some_cycles(dp_clk, c_nof_clk_per_block); + -- Start active in_sosi in_sosi.bsn <= TO_DP_BSN(c_bsn_init); in_sosi.valid <= '1'; in_crosslets_info_rec <= c_crosslets_info_rec; - new_interval <= '1'; -- mark first in_sosi.sync interval WHILE TRUE LOOP - -- One in_sosi.sync interval + -- One in_sosi.sync interval per LOOP FOR i IN 0 TO c_nof_block_per_sync-1 LOOP + -- End new_interval somewhat before next in_sosi.sync + IF i = c_nof_block_per_sync-1 THEN + new_interval <= '0'; + END IF; + -- One in_sosi.sop/eop block per LOOP FOR j IN 0 TO c_nof_clk_per_block-1 LOOP in_sosi.sync <= '0'; in_sosi.sop <= '0'; @@ -312,7 +324,6 @@ BEGIN proc_common_wait_some_cycles(dp_clk, 1); END LOOP; END LOOP; - new_interval <= '0'; END LOOP; WAIT; END PROCESS; @@ -322,6 +333,13 @@ BEGIN BEGIN proc_common_wait_until_low(dp_clk, mm_rst); proc_common_wait_some_cycles(mm_clk, 10); + -- Write statistics offload destination MAC/IP/UDP + -- . obtain relative MM word addresses e.g. from lofar2_unb2c_sdp_station.mmap or from sdp.peripheral.yaml + proc_mem_mm_bus_wr(16#18#, TO_UINT(c_sdp_stat_udp_dst_port), mm_clk, hdr_dat_miso, hdr_dat_mosi); + proc_mem_mm_bus_wr(16#1A#, TO_SINT(c_sdp_stat_ip_dst_addr), mm_clk, hdr_dat_miso, hdr_dat_mosi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(16#29#, TO_SINT(c_sdp_stat_eth_dst_mac(31 DOWNTO 0)), mm_clk, hdr_dat_miso, hdr_dat_mosi); -- use signed to fit 32 b in INTEGER + proc_mem_mm_bus_wr(16#2A#, TO_UINT(c_sdp_stat_eth_dst_mac(47 DOWNTO 32)), mm_clk, hdr_dat_miso, hdr_dat_mosi); + -- Enable common variable delay. proc_mem_mm_bus_wr(c_reg_enable_mm_addr_enable, 1, mm_clk, enable_miso, enable_mosi); proc_common_wait_some_cycles(mm_clk, c_cross_clock_domain_latency); @@ -378,10 +396,7 @@ BEGIN -- . prepare expected XST signal_input_B index, assume crosslet transport in positive direction exp_xst_signal_input_B <= (source_gn MOD c_sdp_N_pn_max) * c_sdp_S_pn; - exp_sdp_stat_header <= func_sdp_compose_stat_header(c_sdp_stat_eth_dst_mac, - c_eth_src_mac, - c_ip_src_addr, - c_sdp_stat_ip_dst_addr, + exp_sdp_stat_header <= func_sdp_compose_stat_header(c_exp_ip_header_checksum, exp_sdp_info, g_statistics_type, weighted_subbands_flag, @@ -664,9 +679,9 @@ BEGIN out_siso => sdp_offload_siso, -- Inputs from other blocks - eth_src_mac => c_eth_src_mac, - udp_src_port => c_udp_src_port, - ip_src_addr => c_ip_src_addr, + eth_src_mac => c_node_eth_src_mac, + udp_src_port => c_node_udp_src_port, + ip_src_addr => c_node_ip_src_addr, gn_index => gn_index, ring_info => c_exp_ring_info, diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd index f5404195ffaaa8c82a68335ca2b30a5ea3af1f7d..fc6371e48c42cde1980a574cb24b7dea68c13d91 100644 --- a/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_validate_err.vhd @@ -49,6 +49,11 @@ -- . g_fifo_size can be set to g_max_block_size if there is no backpressure. -- If there is back pressure on the src_in, the fifo_fill_eop can be used to -- to account for this backpressure by using an g_fifo_size > g_max_block_size. +-- . Typically externally connect snk_in.sync to ref_sync or use another reference +-- pulse. If ref_sync is kept '1', then the MM counts show the current values. +-- Use a ref_sync pulse to let the MM counts show the values at that specific +-- instant, independent of when they are read. +-- ------------------------------------------------------------------------------- -- REGMAP ------------------------------------------------------------------------------- @@ -95,6 +100,9 @@ ENTITY dp_block_validate_err IS PORT ( dp_rst : IN STD_LOGIC; dp_clk : IN STD_LOGIC; + + ref_sync : IN STD_LOGIC := '1'; + -- ST sink snk_out : OUT t_dp_siso := c_dp_siso_rdy; snk_in : IN t_dp_sosi; @@ -126,6 +134,7 @@ ARCHITECTURE rtl OF dp_block_validate_err IS init_sl => '0'); -- Registers in st_clk domain + SIGNAL ref_sync_reg : STD_LOGIC := '0'; SIGNAL count_reg : STD_LOGIC_VECTOR(c_mm_reg.nof_dat*c_mm_reg.dat_w-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL nxt_cnt_en : STD_LOGIC; @@ -141,9 +150,9 @@ ARCHITECTURE rtl OF dp_block_validate_err IS SIGNAL cnt_err_arr : t_cnt_err_arr(g_nof_err_counts-1 DOWNTO 0); SIGNAL cnt_err_en_arr : STD_LOGIC_VECTOR(g_nof_err_counts-1 DOWNTO 0); - SIGNAL hold_cnt_blk : STD_LOGIC_VECTOR(g_blk_cnt_w-1 DOWNTO 0); - SIGNAL hold_cnt_discarded : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0); - SIGNAL hold_cnt_err_arr : t_cnt_err_arr(g_nof_err_counts-1 DOWNTO 0); + SIGNAL hold_cnt_blk : STD_LOGIC_VECTOR(g_blk_cnt_w-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL hold_cnt_discarded : STD_LOGIC_VECTOR(g_cnt_w-1 DOWNTO 0) := (OTHERS=>'0'); + SIGNAL hold_cnt_err_arr : t_cnt_err_arr(g_nof_err_counts-1 DOWNTO 0) := (OTHERS=>(OTHERS=>'0')); SIGNAL err_ok : STD_LOGIC; SIGNAL err_ok_reg : STD_LOGIC; @@ -169,10 +178,13 @@ BEGIN out_pulse => cnt_clr ); + -- . register snk_in.sync to ease timing closure for ref_sync fanout + ref_sync_reg <= ref_sync WHEN rising_edge(dp_clk); + -- . clear block counters immediately at cnt_clr -- . start block counters after sync, e.g. to align block counters in different nodes in -- case the snk_in was (already) active during the cnt_clr - nxt_cnt_en <= '0' WHEN cnt_clr = '1' ELSE '1' WHEN snk_in.sync = '1' ELSE cnt_en; + nxt_cnt_en <= '0' WHEN cnt_clr = '1' ELSE '1' WHEN ref_sync_reg = '1' ELSE cnt_en; cnt_en <= nxt_cnt_en WHEN rising_edge(dp_clk); cnt_this_eop <= cnt_en AND snk_in.eop; @@ -226,7 +238,7 @@ BEGIN ); END GENERATE; - -- Hold counter values at snk_in.sync to have stable values for MM read for comparision between nodes + -- Hold counter values at ref_sync_reg to have stable values for MM read for comparision between nodes p_hold_counters : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN @@ -234,7 +246,7 @@ BEGIN hold_cnt_blk <= (OTHERS=>'0'); hold_cnt_discarded <= (OTHERS=>'0'); hold_cnt_err_arr <= (OTHERS=>(OTHERS=>'0')); - ELSIF snk_in.sync = '1' THEN + ELSIF ref_sync_reg = '1' THEN hold_cnt_blk <= cnt_blk; hold_cnt_discarded <= cnt_discarded; hold_cnt_err_arr <= cnt_err_arr; @@ -246,11 +258,14 @@ BEGIN gen_reg : FOR I IN 0 TO g_nof_err_counts-1 GENERATE count_reg((I + 1) * c_word_w - 1 DOWNTO I * c_word_w) <= RESIZE_UVEC(hold_cnt_err_arr(I), c_word_w); END GENERATE; - count_reg((g_nof_err_counts+1) * c_word_w - 1 DOWNTO g_nof_err_counts * c_word_w ) <= RESIZE_UVEC(hold_cnt_discarded, c_word_w); + + count_reg((g_nof_err_counts+1) * c_word_w - 1 DOWNTO g_nof_err_counts * c_word_w ) <= RESIZE_UVEC(hold_cnt_discarded, c_word_w); + gen_blk_cnt_32b : IF g_blk_cnt_w < c_word_w GENERATE count_reg((g_nof_err_counts+2) * c_word_w - 1 DOWNTO (g_nof_err_counts+1) * c_word_w ) <= RESIZE_UVEC(hold_cnt_blk, c_word_w); -- low part count_reg((g_nof_err_counts+3) * c_word_w - 1 DOWNTO (g_nof_err_counts+2) * c_word_w ) <= (OTHERS=>'0'); -- high part (not used) END GENERATE; + gen_blk_cnt_64b : IF g_blk_cnt_w > c_word_w GENERATE count_reg((g_nof_err_counts+2) * c_word_w - 1 DOWNTO (g_nof_err_counts+1) * c_word_w ) <= hold_cnt_blk(c_word_w-1 DOWNTO 0); -- low part count_reg((g_nof_err_counts+3) * c_word_w - 1 DOWNTO (g_nof_err_counts+2) * c_word_w ) <= RESIZE_UVEC(hold_cnt_blk(g_blk_cnt_w-1 DOWNTO c_word_w), c_word_w); -- high part diff --git a/libraries/base/dp/src/vhdl/dp_bsn_monitor_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_monitor_v2.vhd index ead0038c65910aa3c063387457d08300ec968cde..8670721cbbc4c8d5a6894840853f3b35b68a7cc8 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_monitor_v2.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_monitor_v2.vhd @@ -116,6 +116,7 @@ ARCHITECTURE rtl OF dp_bsn_monitor_v2 IS SIGNAL nof_valid : STD_LOGIC_VECTOR(c_cnt_valid_w-1 DOWNTO 0); SIGNAL cnt_latency : STD_LOGIC_VECTOR(c_cnt_latency_w-1 DOWNTO 0); SIGNAL latency : STD_LOGIC_VECTOR(c_cnt_latency_w-1 DOWNTO 0); + SIGNAL ref_sync_reg : STD_LOGIC := '0'; SIGNAL i_mon_ready_stable : STD_LOGIC; SIGNAL i_mon_xon_stable : STD_LOGIC; @@ -167,7 +168,10 @@ BEGIN nof_err <= cnt_err; nof_valid <= cnt_valid; latency <= cnt_latency; - + + -- Register ref_sync to ease timing closure for ref_sync fanout to (many) dp_bsn_monitor_v2 instances + ref_sync_reg <= ref_sync WHEN rising_edge(clk); + u_sync_timeout_cnt : ENTITY common_lib.common_counter GENERIC MAP ( g_width => c_sync_timeout_w @@ -315,7 +319,7 @@ BEGIN load => TO_SVEC(1, c_cnt_valid_w), count => cnt_valid ); - + u_cnt_latency : ENTITY common_lib.common_counter GENERIC MAP ( g_width => c_cnt_latency_w @@ -323,7 +327,7 @@ BEGIN PORT MAP ( rst => rst, clk => clk, - cnt_clr => ref_sync, + cnt_clr => ref_sync_reg, cnt_en => '1', count => cnt_latency ); diff --git a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd index a2f1756cc82d92e2ca8ee5ba16e20e88321a42d0..cd9c04750d7b03c3c5439e4bb399d2bb04dff741 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd @@ -76,7 +76,8 @@ ENTITY dp_bsn_source_v2 IS dp_on_pps : IN STD_LOGIC; dp_on_status : OUT STD_LOGIC; -- = src_out.valid - bs_restart : OUT STD_LOGIC; -- = src_out.sop for first sop after dp_on went high + bs_restart : OUT STD_LOGIC; -- = src_out.sync for first sync after dp_on went high + bs_new_interval : OUT STD_LOGIC; -- = active during first src_out.sync interval nof_clk_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w); bsn_init : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); @@ -107,7 +108,10 @@ ARCHITECTURE rtl OF dp_bsn_source_v2 IS SIGNAL i_src_out : t_dp_sosi := c_dp_sosi_init; SIGNAL nxt_src_out : t_dp_sosi; - SIGNAL nxt_bs_restart : STD_LOGIC; + SIGNAL i_bs_restart : STD_LOGIC; + SIGNAL nxt_bs_restart : STD_LOGIC; + SIGNAL i_bs_new_interval : STD_LOGIC; + SIGNAL reg_bs_new_interval : STD_LOGIC; SIGNAL nxt_bsn_time_offset_cnt : STD_LOGIC_VECTOR(g_bsn_time_offset_w-1 DOWNTO 0); SIGNAL bsn_time_offset_cnt : STD_LOGIC_VECTOR(g_bsn_time_offset_w-1 DOWNTO 0); @@ -121,6 +125,8 @@ BEGIN src_out <= i_src_out; dp_on_status <= i_src_out.valid; + bs_restart <= i_bs_restart; + bs_new_interval <= i_bs_new_interval; p_state : PROCESS(sync, sync_size_cnt, nof_clk_per_sync, state, i_src_out, block_size_cnt, bsn_time_offset_cnt, @@ -232,6 +238,10 @@ BEGIN -- to have bs_restart at first src_out.sync and src_out.sop. nxt_bs_restart <= nxt_src_out.valid AND NOT i_src_out.valid; + i_bs_new_interval <= '1' WHEN i_bs_restart = '1' ELSE + '0' WHEN i_src_out.sync = '1' ELSE + reg_bs_new_interval; + p_clk : PROCESS(rst, clk) BEGIN IF rst='1' THEN @@ -241,7 +251,8 @@ BEGIN sync_size_cnt <= (OTHERS=>'0'); sync <= '0'; block_size_cnt <= (OTHERS=>'0'); - bs_restart <= '0'; + i_bs_restart <= '0'; + reg_bs_new_interval <= '0'; bsn_time_offset_cnt <= (OTHERS=>'0'); ELSIF rising_edge(clk) THEN prev_state <= state; @@ -250,7 +261,8 @@ BEGIN sync_size_cnt <= nxt_sync_size_cnt; sync <= nxt_sync; block_size_cnt <= nxt_block_size_cnt; - bs_restart <= nxt_bs_restart; + i_bs_restart <= nxt_bs_restart; + reg_bs_new_interval <= i_bs_new_interval; bsn_time_offset_cnt <= nxt_bsn_time_offset_cnt; END IF; END PROCESS; diff --git a/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd b/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd index c20fc561b114fd9b1a0e952636baa56d7c5cd62c..f4db0b10fd99d351882615f1b2c79db13f73b24c 100644 --- a/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd +++ b/libraries/base/dp/src/vhdl/mms_dp_bsn_source_v2.vhd @@ -52,7 +52,8 @@ ENTITY mms_dp_bsn_source_v2 IS -- Streaming clock domain bs_sosi : OUT t_dp_sosi; - bs_restart : OUT STD_LOGIC -- pulse to indicate if the bsn_source has restarted + bs_restart : OUT STD_LOGIC; -- pulse to indicate if the bsn_source has restarted + bs_new_interval : OUT STD_LOGIC -- level to indicate first sync interval if the bsn_source has restarted ); END mms_dp_bsn_source_v2; @@ -116,6 +117,7 @@ BEGIN dp_on_pps => dp_on_pps, dp_on_status => dp_on_status, bs_restart => bs_restart, + bs_new_interval => bs_new_interval, bsn_init => bsn_init, nof_clk_per_sync => nof_clk_per_sync, bsn_time_offset => bsn_time_offset, diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd index 156f92bed2e48b390a233ec03911c24d1c50448f..fe42dfd3e3b166855f7f7b010564e46a73c8dc6c 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_block_validate_err.vhd @@ -160,8 +160,8 @@ BEGIN dp_rst => rst, dp_clk => dp_clk, - mm_rst => rst, - mm_clk => mm_clk, + ref_sync => stimuli_sosi.sync, + -- ST sink snk_out => stimuli_siso, snk_in => stimuli_sosi, @@ -169,6 +169,9 @@ BEGIN src_in => verify_siso, src_out => verify_sosi, + mm_rst => rst, + mm_clk => mm_clk, + reg_mosi => reg_mosi, reg_miso => reg_miso ); diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd index c6ace124e0d2abd4500634a85ca50b75da766e2a..dcd79f1032ac4b97a94e631a760e0f4219490de6 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_source_v2.vhd @@ -124,6 +124,8 @@ ARCHITECTURE tb OF tb_dp_bsn_source_v2 IS SIGNAL dp_on_pps : STD_LOGIC := '0'; SIGNAL dp_on_status : STD_LOGIC; SIGNAL bs_restart : STD_LOGIC; + SIGNAL bs_new_interval : STD_LOGIC; + SIGNAL tb_new_interval : STD_LOGIC := '0'; SIGNAL bsn_init : STD_LOGIC_VECTOR(c_bsn_w-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL bsn_time_offset : STD_LOGIC_VECTOR(c_bsn_time_offset_w-1 DOWNTO 0) := (OTHERS=>'0'); SIGNAL bs_sosi : t_dp_sosi; @@ -304,6 +306,23 @@ BEGIN END IF; END PROCESS; + p_verify_bs_new_interval : PROCESS(clk) + BEGIN + IF rising_edge(clk) THEN + IF bs_restart = '1' THEN + ASSERT bs_new_interval = '1' REPORT "Wrong begin of bs_new_interval" SEVERITY ERROR; + tb_new_interval <= '1'; + ELSIF bs_sosi.sync = '1' THEN + ASSERT bs_new_interval = '0' REPORT "Wrong end of bs_new_interval" SEVERITY ERROR; + tb_new_interval <= '0'; + ELSIF tb_new_interval = '1' THEN + ASSERT bs_new_interval = '1' REPORT "Wrong level during bs_new_interval" SEVERITY ERROR; + ELSE + ASSERT bs_new_interval = '0' REPORT "Unexpected bs_new_interval" SEVERITY ERROR; + END IF; + END IF; + END PROCESS; + ----------------------------------------------------------------------------- -- DUT: dp_bsn_source_v2 ----------------------------------------------------------------------------- @@ -324,7 +343,8 @@ BEGIN dp_on_pps => dp_on_pps, dp_on_status => dp_on_status, -- = src_out.valid - bs_restart => bs_restart, -- = src_out.sop for first sop after dp_on went high + bs_restart => bs_restart, -- = src_out.sync for first sync after dp_on went high + bs_new_interval => bs_new_interval, -- active during first src_out.sync interval bsn_init => bsn_init, bsn_time_offset => bsn_time_offset, diff --git a/libraries/base/ring/src/vhdl/ring_rx.vhd b/libraries/base/ring/src/vhdl/ring_rx.vhd index 65dab32489ae24b6fa40c78c6966491002108c9c..80f7847d424c0d8af847dcecdff6d381c23b33ac 100644 --- a/libraries/base/ring/src/vhdl/ring_rx.vhd +++ b/libraries/base/ring/src/vhdl/ring_rx.vhd @@ -115,6 +115,10 @@ BEGIN ); -- Validate error field + -- . Use ref_sync as capture moment for the running MM total counts in dp_block_validate_err. + -- The rx_packet_sosi does not have rx_packet_sosi.sync, because it carries encoded packets + -- and because the rx_packet_sosi can carry packets from multiple sources (so multiple sync + -- intervals multiplexed on one lane). u_dp_block_validate_err : ENTITY dp_lib.dp_block_validate_err GENERIC MAP ( g_cnt_w => c_word_w, -- <= c_word_w = 32 @@ -123,12 +127,15 @@ BEGIN g_min_block_size => c_packet_size, g_nof_err_counts => g_nof_err_counts, g_fifo_size => c_packet_size, -- can be same as g_max_block_size as src_in.ready = '1' + g_use_sync => FALSE, -- no need to pass on ref_sync g_data_w => g_data_w ) PORT MAP ( dp_rst => dp_rst, dp_clk => dp_clk, + ref_sync => ref_sync, + snk_in => packet_sosi, src_out => validated_sosi,