diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd index e4f2644dfa8e1773a9335b7266322436bccfd6e0..a37a81f51e236d9bbbbfece8d3cfd585c7b91b89 100644 --- a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd @@ -23,8 +23,14 @@ LIBRARY IEEE, common_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; +USE common_lib.common_str_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; PACKAGE apertif_unb1_correlator_pkg IS + + ----------------------------------------------------------------------------- + -- Revision control + ----------------------------------------------------------------------------- -- Revision configuration record for apertif_unb1_correlator. TYPE t_apertif_unb1_correlator_config IS RECORD @@ -89,6 +95,61 @@ PACKAGE apertif_unb1_correlator_pkg IS -- Function to select the revision configuration. FUNCTION func_sel_revision_rec(g_design_name : STRING) RETURN t_apertif_unb1_correlator_config; + + ----------------------------------------------------------------------------- + -- Derive visibility packet size + ----------------------------------------------------------------------------- + + TYPE t_apertif_unb1_correlator_packet_info IS RECORD + vis_header_size : NATURAL; + vis_payload_size : NATURAL; + vis_payload_nof_bits : NATURAL; + vis_packet_size : NATURAL; + eth_tail_size : NATURAL; + eth_gap_size : NATURAL; + eth_packet_size : NATURAL; + eth_packet_nof_bits : NATURAL; + eth_packet_nof_dp_clk : NATURAL; + eth_packet_overhead : REAL; + END RECORD; + + FUNCTION func_apertif_unb1_correlator_packet_info(nof_visibilities : NATURAL; + f_link : REAL; + f_dp_clk : REAL) RETURN t_apertif_unb1_correlator_packet_info; + + FUNCTION func_apertif_unb1_correlator_log_packet_info(pinfo : t_apertif_unb1_correlator_packet_info) RETURN BOOLEAN; + + ----------------------------------------------------------------------------- + -- Check inter channel delay + ----------------------------------------------------------------------------- + + FUNCTION func_apertif_unb1_correlator_inter_channel_delay_max(block_period : NATURAL; + nof_blocks_per_sync : NATURAL; + nof_beamlets : NATURAL; + nof_channels : NATURAL; + nof_visibilities : NATURAL) RETURN INTEGER; + + FUNCTION func_apertif_unb1_correlator_inter_channel_delay_min(pinfo : t_apertif_unb1_correlator_packet_info; + nof_visibilities : NATURAL) RETURN INTEGER; + + FUNCTION func_apertif_unb1_correlator_verify_inter_channel_delay(inter_channel_delay : NATURAL; + inter_channel_delay_max : INTEGER; + inter_channel_delay_min : INTEGER) RETURN BOOLEAN; + + FUNCTION func_apertif_unb1_correlator_log_inter_channel_delay(inter_channel_delay : NATURAL; + inter_channel_delay_max : INTEGER; + inter_channel_delay_min : INTEGER) RETURN BOOLEAN; + + -- Combine derive visibility packet size and check inter channel delay + FUNCTION func_apertif_unb1_correlator_verify_and_log_output_rate(inter_channel_delay : NATURAL; + block_period : NATURAL; + nof_blocks_per_sync : NATURAL; + nof_beamlets : NATURAL; + nof_channels : NATURAL; + nof_visibilities : NATURAL; + f_link : REAL; + f_dp_clk : REAL) RETURN BOOLEAN; + END apertif_unb1_correlator_pkg; PACKAGE BODY apertif_unb1_correlator_pkg IS @@ -116,34 +177,156 @@ PACKAGE BODY apertif_unb1_correlator_pkg IS END IF; END; + -- visibility packet size + FUNCTION func_apertif_unb1_correlator_packet_info(nof_visibilities : NATURAL; + f_link : REAL; + f_dp_clk : REAL) RETURN t_apertif_unb1_correlator_packet_info IS + VARIABLE v : t_apertif_unb1_correlator_packet_info; + BEGIN + -- size in number of 32b words + v.vis_header_size := 21; -- (pad(2) + eth(14) + ip(20) + udp(8) + app_id(16) + app_flags(24)) / 4 = 84 bytes / 4 = 21 words + v.vis_payload_size := nof_visibilities * c_nof_complex; + v.vis_payload_nof_bits := v.vis_payload_size * c_32; + v.vis_packet_size := v.vis_header_size + v.vis_payload_size; + -- account for ethernet overhead + v.eth_tail_size := 1; -- for the eth CRC word + v.eth_gap_size := c_network_eth_gap_len * c_8 / c_32; -- = 3 words for some idle time between packets + v.eth_packet_size := v.vis_packet_size + v.eth_tail_size + v.eth_gap_size; + -- express ethernet packet time in effective number of bits on the link and in equivalent number of dp_clk cycles + v.eth_packet_nof_bits := v.eth_packet_size * c_32; + v.eth_packet_nof_dp_clk := NATURAL(REAL(v.eth_packet_nof_bits) * f_dp_clk / f_link); + -- Calculate ethernet packet overhead compared to visibility payload due to header, tail and interpacket gap + v.eth_packet_overhead := REAL(v.eth_packet_nof_bits) / REAL(v.vis_payload_nof_bits); + RETURN v; + END; + + + FUNCTION func_apertif_unb1_correlator_log_packet_info(pinfo : t_apertif_unb1_correlator_packet_info) RETURN BOOLEAN IS + BEGIN + -- Log packet size + print_str("###############################################################################"); + print_str("# func_apertif_unb1_correlator_log_packet_info:"); + print_str(". vis_header_size = " & int_to_str(pinfo.vis_header_size)); + print_str(". vis_payload_size = " & int_to_str(pinfo.vis_payload_size)); + print_str(". vis_payload_nof_bits = " & int_to_str(pinfo.vis_payload_nof_bits)); + print_str(". vis_packet_size = " & int_to_str(pinfo.vis_packet_size)); + print_str(". eth_tail_size = " & int_to_str(pinfo.eth_tail_size)); + print_str(". eth_gap_size = " & int_to_str(pinfo.eth_gap_size)); + print_str(". eth_packet_size = " & int_to_str(pinfo.eth_packet_size)); + print_str(". eth_packet_nof_bits = " & int_to_str(pinfo.eth_packet_nof_bits)); + print_str(". eth_packet_nof_dp_clk = " & int_to_str(pinfo.eth_packet_nof_dp_clk)); + print_str(". eth_packet_overhead = " & real_to_str(pinfo.eth_packet_overhead, 7, 5)); + print_str(""); + RETURN TRUE; + END; + -- inter_channel_delay: -- . determines gaps between correlator output packets. -- . This produces an even (non-bursting) output rate on the 1GbE interface. -- 300 visibilities interleaved onto 150 streams @ 200MHz * 64b = 1920 Gbps without integration - -- . With 800000 samples per 64 channels integration (=12500 samples/channel): 1920 Gbps/ 12500 = 0.1536 Gbps (256 beamlets) or 0.1056 Gbps (176 beamlets) - -- ============================================================== - -- Inter channel delay Bus rate during visibility buffer output - -- 0 12.8 Gbps - -- 300 6.4 - -- 3*300 3.2 - -- 7*300 1.6 - -- 15*300 0.8 - -- 31*300 0.4 - -- 63*300 0.2 <-- OK - - -- 36 visibilities interleaved onto 18 streams @ 200MHz * 64b = 230.4 Gbps without integration - -- . With 20480 samples per 64 channels integration (320= samples/channel): 230.4 Gbps/ 320 = 0.72 Gbps (256 beamlets) or 0.495 Gbps (176 beamlets) + -- . The minimim capacity needed with 800000 samples per 64 channels integration (=12500 samples/channel) is + -- 1920 Gbps/ 12500 = 0.1536 Gbps (256 beamlets) or 0.1056 Gbps (176 beamlets in 8 bit beamlet mode) or + -- 0.144 Gbps (240 beamlets in 6 bit beamlet mode) + -- . The maximum capacity of the link is determined by the 2 * 10GbE to the data writer, so per PN that is + -- 20G/128 = 0.15625 Gbps + -- ============================================================== + -- The table below shows the inter channel delay in units of 300 visibilities, because a visibilities payload + -- contains 300 visibilities. The packet is represented by 1 * 300 and the inter channel delay by (n-1) * 300, + -- so then the output visibility data rate becomes 12.8G / n. + -- -- Inter channel delay Bus rate during visibility buffer output - -- 0 12.8 Gbps - -- 36 6.4 - -- 3*36 3.2 - -- 7*36 1.6 - -- 15*36 0.8 - -- 31*36 0.4 <-- Too slow as our average is 0.495 - -- 23*36 0.533 <-- OK + -- 0 12.8 Gbps = 64b * 200MHz + -- 300 6.4 = 12.8G/2 + -- 3*300 3.2 = 12.8G/4 + -- 7*300 1.6 = 12.8G/8 + -- 15*300 0.8 = 12.8G/16 + -- 31*300 0.4 = 12.8G/32 + -- 63*300 0.2 = 12.8G/64 > 0.156.25 Gbps, so too large for the available link capacity + -- 127*300 0.1 = 12.8G/128 < 0.144 Gbps, so too small for the required capacity + -- + -- From the available link capacity 0.15625 Gbps it follows that the minimal n = 12.8G / 0.15625 G = 81.92 + -- and c_inter_channel_delay_min = 24576. + -- Choose a required capacity of 0.144 Gbps to fit both 8 bit and 6 bit beamlet mode, however due to packet + -- overhead the required capacity needs to be about 4.2 % more than for the payload data alone. This packet + -- overhead can be accounted for by increasing the required link capacity by 1.042, so then + -- n = 12.8 / (0.144 * 1.042) = 85.3 and c_inter_channel_delay_max = 25591. + -- Use func_apertif_unb1_correlator_inter_channel_delay_max/min() to more accurately determine the min,max + -- range for c_inter_channel_delay. This yields 25300 < c_inter_channel_delay < 26366. + + FUNCTION func_apertif_unb1_correlator_inter_channel_delay_max(block_period : NATURAL; + nof_blocks_per_sync : NATURAL; + nof_beamlets : NATURAL; + nof_channels : NATURAL; + nof_visibilities : NATURAL) RETURN INTEGER IS + -- Derive maximum inter_channel_delay from required visibility data rate + CONSTANT c_nof_clk_per_sync : NATURAL := nof_blocks_per_sync * block_period; + CONSTANT c_vis_nof_packets_per_sync : NATURAL := nof_beamlets * nof_channels; + CONSTANT c_inter_channel_delay_max : INTEGER := c_nof_clk_per_sync / c_vis_nof_packets_per_sync - nof_visibilities; + BEGIN + RETURN c_inter_channel_delay_max; + END; + + FUNCTION func_apertif_unb1_correlator_inter_channel_delay_min(pinfo : t_apertif_unb1_correlator_packet_info; + nof_visibilities : NATURAL) RETURN INTEGER IS + -- Derive minimum inter_channel_delay from avaliable link data rate (independent of nof_beamlets, because the + -- burst rate is the same) + CONSTANT c_inter_channel_delay_min : INTEGER := pinfo.eth_packet_nof_dp_clk - nof_visibilities; + BEGIN + RETURN c_inter_channel_delay_min; + END; + + FUNCTION func_apertif_unb1_correlator_verify_inter_channel_delay(inter_channel_delay : NATURAL; + inter_channel_delay_max : INTEGER; + inter_channel_delay_min : INTEGER) RETURN BOOLEAN IS + BEGIN + -- Verify inter channel delay + ASSERT (inter_channel_delay >= inter_channel_delay_min) AND (inter_channel_delay <= inter_channel_delay_max) + REPORT "Inter channel delay " & int_to_str(inter_channel_delay) & + " must be >= " & int_to_str(inter_channel_delay_min) & + " and <= " & int_to_str(inter_channel_delay_max) + SEVERITY FAILURE; + RETURN TRUE; + END; + + FUNCTION func_apertif_unb1_correlator_log_inter_channel_delay(inter_channel_delay : NATURAL; + inter_channel_delay_max : INTEGER; + inter_channel_delay_min : INTEGER) RETURN BOOLEAN IS + BEGIN + -- Log inter channel delay + print_str("###############################################################################"); + print_str("# func_apertif_unb1_correlator_log_inter_channel_delay:"); + print_str(". Inter channel delay = " & int_to_str(inter_channel_delay)); + print_str(" Minimum = " & int_to_str(inter_channel_delay_min)); + print_str(" Maximum = " & int_to_str(inter_channel_delay_max)); + print_str(""); + RETURN TRUE; + END; + FUNCTION func_apertif_unb1_correlator_verify_and_log_output_rate(inter_channel_delay : NATURAL; + block_period : NATURAL; + nof_blocks_per_sync : NATURAL; + nof_beamlets : NATURAL; + nof_channels : NATURAL; + nof_visibilities : NATURAL; + f_link : REAL; + f_dp_clk : REAL) RETURN BOOLEAN IS + CONSTANT c_pinfo : t_apertif_unb1_correlator_packet_info := func_apertif_unb1_correlator_packet_info(nof_visibilities, f_link, f_dp_clk); + CONSTANT c_max : INTEGER := func_apertif_unb1_correlator_inter_channel_delay_max(block_period, + nof_blocks_per_sync, + nof_beamlets, + nof_channels, + nof_visibilities); + CONSTANT c_min : INTEGER := func_apertif_unb1_correlator_inter_channel_delay_min(c_pinfo, + nof_visibilities); + VARIABLE v_bool : BOOLEAN; + BEGIN + IF func_apertif_unb1_correlator_verify_inter_channel_delay(inter_channel_delay, c_max, c_min) THEN + v_bool := func_apertif_unb1_correlator_log_packet_info(c_pinfo); + v_bool := func_apertif_unb1_correlator_log_inter_channel_delay(inter_channel_delay, c_max, c_min); + END IF; + RETURN TRUE; + END; + END apertif_unb1_correlator_pkg; - -