diff --git a/applications/lofar2/designs/lofar2_unb2b_ring/hdllib.cfg b/applications/lofar2/designs/lofar2_unb2b_ring/hdllib.cfg index 577982457aef22446b2fb9de80ad066cbdc9db72..22a6542cf4b65b73ee2cd1e1c1916d463928b6a6 100644 --- a/applications/lofar2/designs/lofar2_unb2b_ring/hdllib.cfg +++ b/applications/lofar2/designs/lofar2_unb2b_ring/hdllib.cfg @@ -21,6 +21,7 @@ test_bench_files = tb/vhdl/tb_tb_lofar2_unb2b_ring.vhd regression_test_vhdl = + tb/vhdl/tb_tb_lofar2_unb2b_ring.vhd [modelsim_project_file] modelsim_copy_files = diff --git a/applications/lofar2/designs/lofar2_unb2b_ring/src/vhdl/lofar2_unb2b_ring.vhd b/applications/lofar2/designs/lofar2_unb2b_ring/src/vhdl/lofar2_unb2b_ring.vhd index e256e2c3fdbca49db4d4fd0855c24de81bb2a1e7..5891567b0adc6e12c3d8b24f0a934a632da0d264 100644 --- a/applications/lofar2/designs/lofar2_unb2b_ring/src/vhdl/lofar2_unb2b_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_ring/src/vhdl/lofar2_unb2b_ring.vhd @@ -132,8 +132,8 @@ ARCHITECTURE str OF lofar2_unb2b_ring IS CONSTANT c_lane_data_w : NATURAL := 64; CONSTANT c_lane_packet_length : NATURAL := c_sdp_V_ring_pkt_len_max - c_ring_dp_hdr_field_size; -- = 48 longwords per packet, so the maximum data rate with a packetrate of 195312.5 and all 16 nodes combined = 16 * 48 / 1024 * 64 * 200M = 9.6 Gb/s CONSTANT c_use_dp_layer : BOOLEAN := TRUE; - CONSTANT c_nof_rx_monitors : NATURAL := c_sdp_N_rn_max; - CONSTANT c_nof_tx_monitors : NATURAL := c_sdp_N_rn_max; + CONSTANT c_nof_rx_monitors : NATURAL := c_sdp_N_pn_max; + CONSTANT c_nof_tx_monitors : NATURAL := c_sdp_N_pn_max; CONSTANT c_err_bi : NATURAL := 0; CONSTANT c_nof_err_counts : NATURAL := 8; CONSTANT c_validate_err_fifo_size : NATURAL := 1536; @@ -142,8 +142,13 @@ ARCHITECTURE str OF lofar2_unb2b_ring IS CONSTANT c_validate_channel_mode : STRING := "="; CONSTANT c_fifo_tx_fill : NATURAL := c_lane_packet_length + sel_a_b(c_use_dp_layer, c_ring_dp_hdr_field_size, c_ring_eth_hdr_field_size); --total packet length CONSTANT c_fifo_tx_size : NATURAL := 2 * c_lane_packet_length; - CONSTANT c_lofar2_sync_timeout : NATURAL := c_lofar2_sample_clk_freq + c_lofar2_sample_clk_freq / 10; -- 1.1 seconds. + CONSTANT c_lofar2_sync_timeout : NATURAL := c_lofar2_sample_clk_freq + c_lofar2_sample_clk_freq / 10; -- 10% margin. CONSTANT c_sync_timeout : NATURAL := sel_a_b(g_sim, g_sim_sync_timeout, c_lofar2_sync_timeout ); + CONSTANT c_nof_if : NATURAL := 3; -- 3 different interfaces, QSFP, RING_0 and RING_1 + CONSTANT c_qsfp_if_offset : NATURAL := 0; -- QSFP signals are indexed at c_nof_if * I. + CONSTANT c_ring_0_if_offset : NATURAL := 1; -- RING_0 signals are indexed at c_nof_if * I + 1. + CONSTANT c_ring_1_if_offset : NATURAL := 2; -- RING_1 signals are indexed at c_nof_if * I + 2. + CONSTANT c_addr_w_reg_ring_lane_info : NATURAL := 1; CONSTANT c_addr_w_reg_bsn_monitor_v2_ring_rx : NATURAL := ceil_log2(c_nof_rx_monitors) + 3; CONSTANT c_addr_w_reg_bsn_monitor_v2_ring_tx : NATURAL := ceil_log2(c_nof_tx_monitors) + 3; @@ -647,7 +652,7 @@ BEGIN u_mmp_dp_xonoff_lane : ENTITY dp_lib.mms_dp_xonoff GENERIC MAP ( g_nof_streams => c_nof_lanes, - g_default_value => '1' --default enabled + g_default_value => '1' --default enabled, because standard behaviour is to only pass on packets from lane. ) PORT MAP ( mm_rst => mm_rst, @@ -676,7 +681,7 @@ BEGIN u_mmp_dp_xonoff_local : ENTITY dp_lib.mms_dp_xonoff GENERIC MAP ( g_nof_streams => c_nof_lanes, - g_default_value => '0' -- default disabled + g_default_value => '0' -- default disabled, because standard behaviour is to only pass on packets from lane. ) PORT MAP ( mm_rst => mm_rst, @@ -749,12 +754,7 @@ BEGIN ring_info => ring_info ); - gen_sim_this_rn: IF g_sim GENERATE - this_rn <= TO_UVEC(g_sim_node_nr, c_byte_w); - END GENERATE; - gen_no_sim_this_rn: IF NOT g_sim GENERATE - this_rn <= TO_UVEC(TO_UINT(ID) - TO_UINT(ring_info.O_rn), c_byte_w); - END GENERATE; + this_rn <= TO_UVEC(TO_UINT(ID) - TO_UINT(ring_info.O_rn), c_byte_w); ----------------------------------------------------------------------------- -- Ring lane even indices. @@ -803,8 +803,8 @@ BEGIN this_rn => this_rn, N_rn => ring_info.N_rn, - rx_select => ring_info.rx_select, - tx_select => ring_info.tx_select + rx_select => ring_info.use_cable_to_previous_rn, + tx_select => ring_info.use_cable_to_next_rn ); END GENERATE; @@ -853,10 +853,10 @@ BEGIN reg_dp_block_validate_bsn_at_sync_copi => reg_dp_block_validate_bsn_at_sync_copi_arr(2*I +1), reg_dp_block_validate_bsn_at_sync_cipo => reg_dp_block_validate_bsn_at_sync_cipo_arr(2*I +1), - this_rn => this_rn, - N_rn => ring_info.N_rn, - rx_select => ring_info.tx_select, -- reverse tx/rx select for odd indices - tx_select => ring_info.rx_select + this_rn => this_rn, + N_rn => ring_info.N_rn, + rx_select => ring_info.use_cable_to_next_rn, -- reverse tx/rx select for odd indices. + tx_select => ring_info.use_cable_to_previous_rn ); END GENERATE; @@ -865,21 +865,21 @@ BEGIN ----------------------------------------------------------------------------- gen_combine: FOR I IN 0 TO c_nof_even_lanes-1 GENERATE -- QSFP_RX - lane_rx_cable_even_sosi_arr(I) <= tr_10gbe_src_out_arr(3*I) WHEN ring_info.rx_select = '1' ELSE c_dp_sosi_rst; -- rx_select=1 -> even lanes receive from cable - lane_rx_cable_odd_sosi_arr(I) <= tr_10gbe_src_out_arr(3*I) WHEN ring_info.tx_select = '1' ELSE c_dp_sosi_rst; -- tx_select=1 -> odd lanes receive from cable + lane_rx_cable_even_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_qsfp_if_offset) WHEN ring_info.use_cable_to_previous_rn = '1' ELSE c_dp_sosi_rst; -- use_cable_to_previous_rn=1 -> even lanes receive from cable + lane_rx_cable_odd_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_qsfp_if_offset) WHEN ring_info.use_cable_to_next_rn = '1' ELSE c_dp_sosi_rst; -- use_cable_to_next_rn=1 -> odd lanes receive from cable -- QSFP_TX - tr_10gbe_snk_in_arr(3*I) <= lane_tx_cable_even_sosi_arr(I) WHEN ring_info.tx_select = '1' ELSE -- tx_select=1 -> even lanes transmit to cable - lane_tx_cable_odd_sosi_arr(I) WHEN ring_info.rx_select = '1' ELSE c_dp_sosi_rst; -- rx_select=1 -> odd lanes transmit to cable + tr_10gbe_snk_in_arr(c_nof_if * I + c_qsfp_if_offset) <= lane_tx_cable_even_sosi_arr(I) WHEN ring_info.use_cable_to_next_rn = '1' ELSE -- use_cable_to_next_rn=1 -> even lanes transmit to cable + lane_tx_cable_odd_sosi_arr(I) WHEN ring_info.use_cable_to_previous_rn = '1' ELSE c_dp_sosi_rst; -- use_cable_to_previous_rn=1 -> odd lanes transmit to cable -- RING_0_RX even lanes receive from RING_0 (from the left) - lane_rx_board_even_sosi_arr(I) <= tr_10gbe_src_out_arr(3*I +1); + lane_rx_board_even_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_ring_0_if_offset); -- RING_0_TX odd lanes transmit to RING_0 (to the left) - tr_10gbe_snk_in_arr(3*I +1) <= lane_tx_board_odd_sosi_arr(I); + tr_10gbe_snk_in_arr(c_nof_if * I + c_ring_0_if_offset) <= lane_tx_board_odd_sosi_arr(I); -- RING_1_RX odd lanes receive from RING_1 (from the right) - lane_rx_board_odd_sosi_arr(I) <= tr_10gbe_src_out_arr(3*I +2); + lane_rx_board_odd_sosi_arr(I) <= tr_10gbe_src_out_arr(c_nof_if * I + c_ring_1_if_offset); -- RING_1_TX even lanes transmit to RING_1 (to the right) - tr_10gbe_snk_in_arr(3*I +2) <= lane_tx_board_even_sosi_arr(I); + tr_10gbe_snk_in_arr(c_nof_if * I + c_ring_1_if_offset) <= lane_tx_board_even_sosi_arr(I); END GENERATE; ----------------------------------------------------------------------------- @@ -934,19 +934,19 @@ BEGIN -- QSFP port, RING_0 port and RING_1 port. gen_seperate: FOR I IN 0 TO c_nof_even_lanes-1 GENERATE -- QSFP_TX - unb2_board_front_io_serial_tx_arr(I) <= tr_10gbe_serial_tx_arr(3*I); + unb2_board_front_io_serial_tx_arr(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_qsfp_if_offset); -- QSFP_RX - tr_10gbe_serial_rx_arr(3*I) <= unb2_board_front_io_serial_rx_arr(I); + tr_10gbe_serial_rx_arr(c_nof_if * I + c_qsfp_if_offset) <= unb2_board_front_io_serial_rx_arr(I); -- RING_0_TX - i_RING_TX(0)(I) <= tr_10gbe_serial_tx_arr(3*I +1); + i_RING_TX(0)(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_ring_0_if_offset); -- RING_0_RX - tr_10gbe_serial_rx_arr(3*I +1) <= i_RING_RX(0)(I); + tr_10gbe_serial_rx_arr(c_nof_if * I + c_ring_0_if_offset) <= i_RING_RX(0)(I); -- RING_1_TX - i_RING_TX(1)(I) <= tr_10gbe_serial_tx_arr(3*I +2); + i_RING_TX(1)(I) <= tr_10gbe_serial_tx_arr(c_nof_if * I + c_ring_1_if_offset); -- RING_1_RX - tr_10gbe_serial_rx_arr(3*I +2) <= i_RING_RX(1)(I); + tr_10gbe_serial_rx_arr(c_nof_if * I + c_ring_1_if_offset) <= i_RING_RX(1)(I); END GENERATE; --------- diff --git a/applications/lofar2/designs/lofar2_unb2b_ring/tb/vhdl/tb_lofar2_unb2b_ring.vhd b/applications/lofar2/designs/lofar2_unb2b_ring/tb/vhdl/tb_lofar2_unb2b_ring.vhd index 1c6389ec66d21fe7ac43ffec9905b39735dc289f..66d78fa1775e61531aed243175b985f57b563b96 100644 --- a/applications/lofar2/designs/lofar2_unb2b_ring/tb/vhdl/tb_lofar2_unb2b_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_ring/tb/vhdl/tb_lofar2_unb2b_ring.vhd @@ -1,6 +1,6 @@ ------------------------------------------------------------------------------- -- --- Copyright 2020 +-- Copyright 2021 -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands -- @@ -21,26 +21,10 @@ ------------------------------------------------------------------------------- -- -- Author: R. van der Walle --- Purpose: Self-checking testbench for simulating lofar2_unb2b_ring using WG data. +-- Purpose: Self-checking testbench for simulating lofar2_unb2b_ring using BG data. -- -- Description: --- MM control actions: --- --- 1) Enable calc mode for WG via reg_diag_wg with: --- freq = 19.921875MHz --- ampl = 0.5 * 2**13 --- --- 2) Read current BSN from reg_bsn_scheduler_wg and write reg_bsn_scheduler_wg --- to trigger start of WG at BSN. --- --- 3) Read subband statistics (SST) --- --- 4) Read beamlet statistics (BST) via ram_st_bst and verify with --- c_exp_beamlet_power_sp_0 at c_sdp_N_sub-1 - c_subband_sp_0. --- View sp_beamlet_power_0 in Wave window --- 5) Compare SST with BST. --- 6) Verify 10GbE output. --- +-- See, https://support.astron.nl/confluence/x/jyu7Ag -- -- Usage: -- > as 7 # default @@ -79,7 +63,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_ring IS CONSTANT c_sim : BOOLEAN := TRUE; CONSTANT c_node_nr : NATURAL := 0; - CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := "00000000"; + CONSTANT c_id : STD_LOGIC_VECTOR(7 DOWNTO 0) := TO_UVEC(g_unb_nr, c_unb2b_board_nof_uniboard_w) & TO_UVEC(0, c_unb2b_board_nof_chip_w); CONSTANT c_version : STD_LOGIC_VECTOR(1 DOWNTO 0) := "00"; CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 0); @@ -197,7 +181,7 @@ BEGIN -- Others VERSION => c_version, - ID => c_id, + ID => ( TO_UVEC(g_unb_nr, c_unb2b_board_nof_uniboard_w) & TO_UVEC(I, c_unb2b_board_nof_chip_w) ), TESTIO => open, -- I2C Interface to Sensors @@ -261,12 +245,12 @@ BEGIN END LOOP; -- Start node specific settings - mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, 0) & "REG_RING_INFO", 0, 1, tb_clk); -- rx_select = 1 - mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, 0) & "REG_RING_INFO", 1, 0, tb_clk); -- tx_select = 0 + mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, 0) & "REG_RING_INFO", 0, 1, tb_clk); -- use_ring_to_previous_rn = 1 + mmf_mm_bus_wr(mmf_unb_file_prefix(g_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(g_unb_nr, g_nof_rn-1) & "REG_RING_INFO", 0, 0, tb_clk); -- rx_select = 0 - mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, g_nof_rn-1) & "REG_RING_INFO", 1, 1, tb_clk); -- tx_select = 1 + mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, g_nof_rn-1) & "REG_RING_INFO", 0, 0, tb_clk); -- use_ring_to_previous_rn = 0 + mmf_mm_bus_wr(mmf_unb_file_prefix(g_unb_nr, g_nof_rn-1) & "REG_RING_INFO", 1, 1, tb_clk); -- use_ring_to_next_rn = 1 ---------------------------------------------------------------------------- -- Access scheme 1. A source RN creates the packets and sends them along the ring. @@ -311,26 +295,26 @@ BEGIN IF g_access_scheme = 1 THEN -- Wait for bsn monitor to have received a sync period. mmf_mm_wait_until_value(c_mm_file_reg_bsn_monitor_v2_ring_rx, 4, -- read nof valid - "UNSIGNED", rd_data, ">", 0, -- this is the wait until condition + "SIGNED", rd_data, ">", 0, -- this is the wait until condition 1 us, tb_clk); -- read every 1 us FOR I IN 0 TO c_nof_lanes-1 LOOP - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_rn_max*8+1, rd_data, tb_clk); --bsn at sync + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_pn_max*8+1, rd_data, tb_clk); --bsn at sync ASSERT TO_UINT(rd_data) = c_exp_bsn_at_sync REPORT "Wrong bsn_at_sync value from bsn_monitor_v2_ring_tx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_rn_max*8+3, rd_data, tb_clk); --nof_sop + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_pn_max*8+3, rd_data, tb_clk); --nof_sop ASSERT TO_UINT(rd_data) = c_exp_nof_sop REPORT "Wrong nof_sop value from bsn_monitor_v2_ring_tx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_rn_max*8+4, rd_data, tb_clk); --nof_valid + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_pn_max*8+4, rd_data, tb_clk); --nof_valid ASSERT TO_UINT(rd_data) = c_exp_nof_valid REPORT "Wrong nof_valid value from bsn_monitor_v2_ring_tx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_rn_max*8+5, rd_data, tb_clk); --nof_err + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_tx, I*c_sdp_N_pn_max*8+5, rd_data, tb_clk); --nof_err ASSERT TO_UINT(rd_data) = 0 REPORT "Wrong nof_err value from bsn_monitor_v2_ring_tx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_rn_max*8+1, rd_data, tb_clk); --bsn at sync + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_pn_max*8+1, rd_data, tb_clk); --bsn at sync ASSERT TO_UINT(rd_data) = c_exp_bsn_at_sync REPORT "Wrong bsn_at_sync value from bsn_monitor_v2_ring_rx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_rn_max*8+3, rd_data, tb_clk); --nof_sop + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_pn_max*8+3, rd_data, tb_clk); --nof_sop ASSERT TO_UINT(rd_data) = c_exp_nof_sop REPORT "Wrong nof_sop value from bsn_monitor_v2_ring_rx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_rn_max*8+4, rd_data, tb_clk); --nof_valid + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_pn_max*8+4, rd_data, tb_clk); --nof_valid ASSERT TO_UINT(rd_data) = c_exp_nof_valid REPORT "Wrong nof_valid value from bsn_monitor_v2_ring_rx on source node in access scheme 1." SEVERITY ERROR; - mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_rn_max*8+5, rd_data, tb_clk); --nof_err + mmf_mm_bus_rd(c_mm_file_reg_bsn_monitor_v2_ring_rx, I*c_sdp_N_pn_max*8+5, rd_data, tb_clk); --nof_err ASSERT TO_UINT(rd_data) = 0 REPORT "Wrong nof_err value from bsn_monitor_v2_ring_rx on source node in access scheme 1." SEVERITY ERROR; END LOOP; @@ -340,7 +324,7 @@ BEGIN ELSE -- Wait for bsn monitor to have received a sync period. mmf_mm_wait_until_value(mmf_unb_file_prefix(g_unb_nr, g_nof_rn-1) & "REG_BSN_MONITOR_V2_RING_RX", 4, -- read nof valid - "UNSIGNED", rd_data, ">", 0, -- this is the wait until condition + "SIGNED", rd_data, ">", 0, -- this is the wait until condition 1 us, tb_clk); -- read every 1 us FOR RN IN 0 TO g_nof_rn-1 LOOP @@ -348,33 +332,33 @@ BEGIN FOR J IN 0 TO g_nof_rn-1 LOOP -- bsn_monitor index -- No packets transmitted from next RN (this_rn + 1 for even lanes, this_rn - 1 for odd lanes) as this RN should have removed it from the ring. IF (I MOD 2 = 0 AND (RN + 1) MOD g_nof_rn = J) OR (I MOD 2 = 1 AND (RN + g_nof_rn-1) MOD g_nof_rn = J) THEN - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+0, rd_data, tb_clk); --status bits + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+0, rd_data, tb_clk); --status bits ASSERT rd_data(2) = '1' REPORT "Wrong sync_timout, expected 1, got 0. From bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; ELSE - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+0, rd_data, tb_clk); --status bits + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+0, rd_data, tb_clk); --status bits ASSERT rd_data(2) = '0' REPORT "Wrong sync_timout, expected 0, got 1. From bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+1, rd_data, tb_clk); --bsn at sync + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+1, rd_data, tb_clk); --bsn at sync ASSERT TO_UINT(rd_data) = c_exp_bsn_at_sync REPORT "Wrong bsn_at_sync value from bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+3, rd_data, tb_clk); --nof_sop + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+3, rd_data, tb_clk); --nof_sop ASSERT TO_UINT(rd_data) = c_exp_nof_sop REPORT "Wrong nof_sop value from bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+4, rd_data, tb_clk); --nof_valid + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+4, rd_data, tb_clk); --nof_valid ASSERT TO_UINT(rd_data) = c_exp_nof_valid REPORT "Wrong nof_valid value from bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_rn_max + J) * 8+5, rd_data, tb_clk); --nof_err + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_TX", (I*c_sdp_N_pn_max + J) * 8+5, rd_data, tb_clk); --nof_err ASSERT TO_UINT(rd_data) = 0 REPORT "Wrong nof_err value from bsn_monitor_v2_ring_tx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; END IF; IF RN = J THEN -- No packets received from itself as the previous RN should have removed it from the ring. - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+0, rd_data, tb_clk); --status bits + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+0, rd_data, tb_clk); --status bits ASSERT rd_data(2) = '1' REPORT "Wrong sync_timout, expected 1, got 0. From bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; ELSE - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+0, rd_data, tb_clk); --status bits + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+0, rd_data, tb_clk); --status bits ASSERT rd_data(2) = '0' REPORT "Wrong sync_timout, expected 0, got 1. From bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+1, rd_data, tb_clk); --bsn at sync + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+1, rd_data, tb_clk); --bsn at sync ASSERT TO_UINT(rd_data) = c_exp_bsn_at_sync REPORT "Wrong bsn_at_sync value from bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+3, rd_data, tb_clk); --nof_sop + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+3, rd_data, tb_clk); --nof_sop ASSERT TO_UINT(rd_data) = c_exp_nof_sop REPORT "Wrong nof_sop value from bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+4, rd_data, tb_clk); --nof_valid + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+4, rd_data, tb_clk); --nof_valid ASSERT TO_UINT(rd_data) = c_exp_nof_valid REPORT "Wrong nof_valid value from bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; - mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_rn_max + J) * 8+5, rd_data, tb_clk); --nof_err + mmf_mm_bus_rd(mmf_unb_file_prefix(g_unb_nr, RN) & "REG_BSN_MONITOR_V2_RING_RX", (I*c_sdp_N_pn_max + J) * 8+5, rd_data, tb_clk); --nof_err ASSERT TO_UINT(rd_data) = 0 REPORT "Wrong nof_err value from bsn_monitor_v2_ring_rx on RN_" & INTEGER'IMAGE(RN) & " in access scheme 2/3." SEVERITY ERROR; END IF; END LOOP; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index 3790611d4d8da7db9b926d9eb491400ce22eae1a..32abb324a2812acfbe6e082727431fcc0e99f819 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -72,10 +72,10 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_N_crosslets_max : NATURAL := 7; CONSTANT c_sdp_N_fft : NATURAL := 1024; CONSTANT c_sdp_N_pn_lb : NATURAL := 16; + CONSTANT c_sdp_N_pn_max : NATURAL := 16; CONSTANT c_sdp_N_pol : NATURAL := 2; CONSTANT c_sdp_N_pol_bf : NATURAL := 2; CONSTANT c_sdp_N_ring_lanes_max : NATURAL := 8; - CONSTANT c_sdp_N_rn_max : NATURAL := 16; CONSTANT c_sdp_N_sub : NATURAL := 512; CONSTANT c_sdp_N_taps : NATURAL := 16; CONSTANT c_sdp_P_sq : NATURAL := 9; @@ -348,8 +348,8 @@ PACKAGE sdp_pkg is CONSTANT c_sdp_ram_st_xsq_addr_w : NATURAL := ceil_log2(c_sdp_P_sq) + ceil_log2(c_sdp_N_crosslets_max * c_sdp_X_sq * c_nof_complex * (c_longword_sz/c_word_sz) ); -- RING MM address widths - CONSTANT c_sdp_reg_bsn_monitor_v2_ring_rx_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + ceil_log2(c_sdp_N_rn_max) + ceil_Log2(7); - CONSTANT c_sdp_reg_bsn_monitor_v2_ring_tx_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + ceil_log2(c_sdp_N_rn_max) + ceil_Log2(7); + CONSTANT c_sdp_reg_bsn_monitor_v2_ring_rx_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + ceil_log2(c_sdp_N_pn_max) + ceil_Log2(7); + CONSTANT c_sdp_reg_bsn_monitor_v2_ring_tx_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + ceil_log2(c_sdp_N_pn_max) + ceil_Log2(7); CONSTANT c_sdp_reg_ring_lane_info_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + 1; CONSTANT c_sdp_reg_dp_xonoff_lane_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + 1; CONSTANT c_sdp_reg_dp_xonoff_local_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + 1; diff --git a/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd b/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd index a9736ef5dbc4b5d7ddc1f768ec85337d9d54694a..c21ef65e507057dd120d32a1d9a0f4629863e52a 100644 --- a/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_validate_bsn_at_sync.vhd @@ -49,6 +49,7 @@ -- dp_block_validate_bsn_at_sync.vhd on other PN. In this way it is -- suffiicent to have one instance of dp_block_validate_bsn_at_sync.vhd per -- PN. +-- . See, https://support.astron.nl/confluence/x/jyu7Ag ------------------------------------------------------------------------------- -- REGMAP ------------------------------------------------------------------------------- diff --git a/libraries/base/ring/src/vhdl/ring_info.vhd b/libraries/base/ring/src/vhdl/ring_info.vhd index 12d2f8422aa808aa110a2e87c66db32d56a84d80..47e8cdb9fdfbe4e9ea069b85f3067817bf23a863 100644 --- a/libraries/base/ring/src/vhdl/ring_info.vhd +++ b/libraries/base/ring/src/vhdl/ring_info.vhd @@ -81,10 +81,10 @@ BEGIN ); -- get "RW" fields from mm_fields - ring_info.O_rn <= mm_fields_out(field_hi(c_ring_info_field_arr, "O_rn") DOWNTO field_lo(c_ring_info_field_arr, "O_rn")); - ring_info.N_rn <= mm_fields_out(field_hi(c_ring_info_field_arr, "N_rn") DOWNTO field_lo(c_ring_info_field_arr, "N_rn")); - ring_info.rx_select <= sl(mm_fields_out(field_hi(c_ring_info_field_arr, "rx_select") DOWNTO field_lo(c_ring_info_field_arr, "rx_select"))); - ring_info.tx_select <= sl(mm_fields_out(field_hi(c_ring_info_field_arr, "tx_select") DOWNTO field_lo(c_ring_info_field_arr, "tx_select"))); + ring_info.O_rn <= mm_fields_out(field_hi(c_ring_info_field_arr, "O_rn") DOWNTO field_lo(c_ring_info_field_arr, "O_rn")); + ring_info.N_rn <= mm_fields_out(field_hi(c_ring_info_field_arr, "N_rn") DOWNTO field_lo(c_ring_info_field_arr, "N_rn")); + ring_info.use_cable_to_previous_rn <= sl(mm_fields_out(field_hi(c_ring_info_field_arr, "use_cable_to_previous_rn") DOWNTO field_lo(c_ring_info_field_arr, "use_cable_to_previous_rn"))); + ring_info.use_cable_to_next_rn <= sl(mm_fields_out(field_hi(c_ring_info_field_arr, "use_cable_to_next_rn") DOWNTO field_lo(c_ring_info_field_arr, "use_cable_to_next_rn"))); END str; diff --git a/libraries/base/ring/src/vhdl/ring_lane.vhd b/libraries/base/ring/src/vhdl/ring_lane.vhd index 6d85a207e44a3c1b9a1d8928991d0c9a98972ab7..bf2ba0fe87e0f08e2103f347f725ae8a8a18223b 100644 --- a/libraries/base/ring/src/vhdl/ring_lane.vhd +++ b/libraries/base/ring/src/vhdl/ring_lane.vhd @@ -54,7 +54,7 @@ ENTITY ring_lane IS g_bsn_at_sync_check_channel : NATURAL := 1; -- on which channel should the bsn be checked g_validate_channel : BOOLEAN := TRUE; g_validate_channel_mode : STRING := ">"; - g_sync_timeout : NATURAL := 200*10**6 + g_sync_timeout : NATURAL := 220*10**6 -- 10% margin ); PORT ( -- Clocks and reset diff --git a/libraries/base/ring/src/vhdl/ring_pkg.vhd b/libraries/base/ring/src/vhdl/ring_pkg.vhd index 25448eb84e5b08b1299ab0b477e3cd5e75de525a..8a41f1b36dc65cc56eee281556e053a713a9957c 100644 --- a/libraries/base/ring/src/vhdl/ring_pkg.vhd +++ b/libraries/base/ring/src/vhdl/ring_pkg.vhd @@ -35,24 +35,6 @@ USE common_lib.common_network_layers_pkg.ALL; PACKAGE ring_pkg is -- lane info, see https://support.astron.nl/confluence/x/jyu7Ag --- +====================+========+==============================================================================+===========================+ --- | Field | Access | Description | Remark | --- +====================+========+==============================================================================+===========================+ --- | transport_nof_hops | RW | Number of hops (N_transport_hops) to transport a packet. The RN will remove | Same setting for all RN | --- | | | packets that have traveled N_transport_hops hops. If | | --- | | | N_transport_hops >= N_rn, then the ring cannot remove the packet, because | | --- | | | then it cannot distinguish between a packet that just starts or that has | | --- | | | has already been transported along the entire ring, so then the application | | --- | | | has to take care of removing the packet from the ring (or let it cycle along | | --- | | | the ring 'forever'). | | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ --- | lane_direction | RO | 1 = transport in positive RN index direction on lanes with even lane index. 0| Same setting for all RN | --- | | | = transport in negative RN index direction on lanes with odd lane index. | | --- | | | Hence for N_lanes = 8, lanes 0, 2, 4, and 6 will transport in positive | | --- | | | direction, and lanes 1, 3, 5, 7 will transport in opposite (= negative) | | --- | | | direction. The lane direction is fixed per lane and therefore read only. | | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ - TYPE t_lane_info IS RECORD transport_nof_hops : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); lane_direction : STD_LOGIC; @@ -66,38 +48,21 @@ PACKAGE ring_pkg is (field_name_pad("lane_direction"), "RO", 1, field_default(0)) ); -- ring info, see https://support.astron.nl/confluence/x/jyu7Ag --- +====================+========+==============================================================================+===========================+ --- | Field | Access | Description | Remark | --- +====================+========+==============================================================================+===========================+ --- | O_rn | RW | Offset index of the first global node (GN) in the ring. | Same setting for all RN | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ --- | N_rn | RW | The number of ring nodes (RN) in the closed ring. | Same setting for all RN | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ --- | tx_select | RW | 0 = transmit via on board port, 1 = transmit via cable (QSFP) port. Default | Individual setting per RN | --- | | | in firmware assume cable between RN on different UniBoard2 and assume cable | | --- | | | to close the ring defined by ring_info. The programmable tx_select allows | | --- | | | using cables between other RN in the ring. | | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ --- | rx_select | RW | 0 = receive via on board port, 1 = receive via cable (QSFP) port. Default in | Individual setting per RN | --- | | | firmware assume cable between RN on different UniBoard2 and assume cable to | | --- | | | close the ring defined by ring_info. The programmable rx_select allows using | | --- | | | cables between other RN in the ring. | | --- +--------------------+--------+------------------------------------------------------------------------------+---------------------------+ TYPE t_ring_info IS RECORD - O_rn : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); - N_rn : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); - tx_select : STD_LOGIC; - rx_select : STD_LOGIC; + O_rn : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + N_rn : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0); + use_cable_to_next_rn : STD_LOGIC; + use_cable_to_previous_rn : STD_LOGIC; END RECORD; CONSTANT c_ring_info_rst : t_ring_info := ( (OTHERS => '0'), (OTHERS => '0'), '0', '0' ); CONSTANT c_ring_info_field_arr : t_common_field_arr(3 DOWNTO 0) := - ( (field_name_pad("O_rn"), "RW", 8, field_default( 0)), - (field_name_pad("N_rn"), "RW", 8, field_default(16)), - (field_name_pad("tx_select"), "RW", 1, field_default( 0)), - (field_name_pad("rx_select"), "RW", 1, field_default( 0)) ); + ( (field_name_pad("O_rn"), "RW", 8, field_default( 0)), + (field_name_pad("N_rn"), "RW", 8, field_default(16)), + (field_name_pad("use_cable_to_next_rn"), "RW", 1, field_default( 0)), + (field_name_pad("use_cable_to_previous_rn"), "RW", 1, field_default( 0)) ); CONSTANT c_ring_eth_dst_mac : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := x"FFFFFFFFFFFF"; CONSTANT c_ring_eth_src_mac : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0) := x"002286080000"; diff --git a/libraries/base/ring/src/vhdl/ring_rx.vhd b/libraries/base/ring/src/vhdl/ring_rx.vhd index 05e8e11c03d10fda318e58ab0ba6f7c1484ea867..7ac8a4a6e774bad9889adf4aef24d82c972b852d 100644 --- a/libraries/base/ring/src/vhdl/ring_rx.vhd +++ b/libraries/base/ring/src/vhdl/ring_rx.vhd @@ -51,7 +51,7 @@ ENTITY ring_rx IS g_nof_err_counts : NATURAL := 1; g_fifo_size : NATURAL := 1536; g_check_channel : NATURAL := 1; - g_sync_timeout : NATURAL := 200*10**6 + g_sync_timeout : NATURAL := 220*10**6 -- 10% margin ); PORT ( -- Clocks and reset diff --git a/libraries/base/ring/src/vhdl/ring_tx.vhd b/libraries/base/ring/src/vhdl/ring_tx.vhd index 5a6d0d4510ee42fd025da27b013eeda256106dc1..3c5b9df0b81f6cd4db1fe75d19bf1cf73bbf3eff 100644 --- a/libraries/base/ring/src/vhdl/ring_tx.vhd +++ b/libraries/base/ring/src/vhdl/ring_tx.vhd @@ -46,7 +46,7 @@ ENTITY ring_tx IS g_validate_channel : BOOLEAN := TRUE; g_mode : STRING := ">"; g_nof_tx_monitors : NATURAL := 1; - g_sync_timeout : NATURAL := 200*10**6 + g_sync_timeout : NATURAL := 220*10**6 -- 10% margin ); PORT ( -- Clocks and reset @@ -77,7 +77,7 @@ ARCHITECTURE str OF ring_tx IS CONSTANT c_nof_hdr_fields : NATURAL := sel_a_b(g_use_dp_layer, c_ring_dp_nof_hdr_fields, c_ring_eth_nof_hdr_fields); CONSTANT c_hdr_field_sel : STD_LOGIC_VECTOR(c_nof_hdr_fields-1 DOWNTO 0) := sel_a_b(g_use_dp_layer, c_ring_dp_hdr_field_sel, c_ring_eth_hdr_field_sel); CONSTANT c_hdr_field_arr : t_common_field_arr(c_nof_hdr_fields-1 DOWNTO 0) := sel_a_b(g_use_dp_layer, c_ring_dp_hdr_field_arr, c_ring_eth_hdr_field_arr); - CONSTANT c_fifo_size : NATURAL := 8; -- Large enough to fit ETH/DP header. + CONSTANT c_fifo_size : NATURAL := 8; -- Large enough to fit ETH/DP header (choose power of 2). SIGNAL validated_sosi : t_dp_sosi; SIGNAL tx_sosi : t_dp_sosi; @@ -201,8 +201,7 @@ BEGIN u_dp_demux : ENTITY dp_lib.dp_demux GENERIC MAP ( - g_nof_output => g_nof_tx_monitors, - g_sel_ctrl_invert => TRUE + g_nof_output => g_nof_tx_monitors ) PORT MAP ( rst => dp_rst,