diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index ed0c926e9f1b14cfa5d6365428f1d26eca3654d6..ea3e9fd77656f795abf4c3d42bca1121b0eee892 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -507,6 +507,7 @@ PACKAGE sdp_pkg is FUNCTION func_sdp_get_stat_nof_signal_inputs(g_statistics_type : STRING) RETURN NATURAL; -- nof_statistics_per_packet = mm_nof_data * mm_data_size / c_sdp_W_statistic_sz + FUNCTION func_sdp_get_stat_from_mm_user_size(g_statistics_type : STRING) RETURN NATURAL; FUNCTION func_sdp_get_stat_from_mm_data_size(g_statistics_type : STRING) RETURN NATURAL; FUNCTION func_sdp_get_stat_from_mm_step_size(g_statistics_type : STRING) RETURN NATURAL; FUNCTION func_sdp_get_stat_from_mm_nof_data(g_statistics_type : STRING) RETURN NATURAL; @@ -578,6 +579,14 @@ PACKAGE BODY sdp_pkg IS 1)); -- SST END func_sdp_get_stat_nof_signal_inputs; + FUNCTION func_sdp_get_stat_from_mm_user_size(g_statistics_type : STRING) RETURN NATURAL IS + -- see sdp_statistics_offload.vhd for description + BEGIN + RETURN sel_a_b(g_statistics_type="BST", c_sdp_W_statistic_sz, -- = 2 + sel_a_b(g_statistics_type="XST", c_nof_complex * c_sdp_W_statistic_sz, -- = 4 + c_sdp_W_statistic_sz)); -- = 2, SST + END func_sdp_get_stat_from_mm_user_size; + FUNCTION func_sdp_get_stat_from_mm_data_size(g_statistics_type : STRING) RETURN NATURAL IS BEGIN RETURN sel_a_b(g_statistics_type="BST", c_sdp_N_pol_bf * c_sdp_W_statistic_sz, -- = 4 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 674b8baa1e4234ad4fb5d16bb92dd012d7a63276..c9269c6a02c302a9c92429b699d9585ad2c617eb 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -30,6 +30,61 @@ -- https://plm.astron.nl/polarion/#/project/LOFAR2System/wiki/L2%20Interface%20Control%20Documents/SC%20to%20SDP%20ICD -- . See 2.9.4 Station Control (L3-SC) - SDP Firmware (L4-SDPFW) -- +-- . endianess +-- Within a 32bit MM word the values are stored with LSByte at lowest byte +-- address (so relative byte address 0) and MSByte at highest byte address +-- (so relative byte address 3). Internally in the RAM the MM words are thus +-- stored with LSByte first, which is called little endian. However, +-- externally the MM words are send with MSByte first, so in the statistics +-- offload header and offload payload the 32bit words are send with MSByte +-- first, which is called big endian. +-- The dp_offload_tx_v3 sends all multi byte header fields in big endian +-- order, hence also the 16bit, 24bit and 64bit values are send MSByte +-- first. The internet packet headers also use big endian, which is +-- therefore also called network order. Hence the entire statistics offload +-- packet is in big endian order. +-- If values are shown with first byte received left and last byte received +-- right, then big endian hex values can directly be interpreted when read +-- by a human, because they are shown in the normal order. +-- +-- . g_reverse_word_order +-- The statistics consist of c_sdp_W_statistic_sz = 2 MM words that are +-- with LSWord at low (even) word address and MSWord at high (odd) word +-- address. Default the statistics offload reads the low address first, but +-- the statistics have to be send with MSWord first. Therefore the read +-- order needs to be reversed per statistic value, so g_reverse_word_order +-- = TRUE. The combination of sending the MSWord first and the MSByte first +-- results that the entire 64b statistics words are send in big endian +-- order. +-- +-- Stored order: +-- word address: 0, 1, 2, 3 +-- SST Ul, Uh +-- BST Xl, Xh, Yl, Yh +-- XST Rl, Rh, Il, Ih +-- +-- The g_reverse_word_order = TRUE is needed to achieve have MSWord first +-- and 64bit big endian. +-- The g_user_size defines the number of words that get reversed: +-- . For the SST there is only one uint64 part, so g_user_size = 2. +-- . For the BST the X and Y polarization parts are treated as and array of +-- [N_pol_bf], so index 0 = X is send first and therefore g_user_size = 2 +-- to preserve the polarization order. +-- . For the XST the Re and Im complex parts are treated as a cint64, so +-- the imaginary part is send first and therefore g_user_size = 4 to also +-- reverse the Re an Im parts. This is similar as with cint16 values that +-- are packed as Im << 16 + Re in a 32bit word. However it differs from +-- two diminensional arrays of [N_complex], because for arrays index 0 +-- is send first and index 0 corresponds to Re. +-- +-- The () show the parts that are contained in g_user_size and that got +-- reversed by g_reverse_word_order = TRUE compared to the stored order: +-- +-- Transport order: (g_user_size) +-- SST (Uh, Ul), 2 +-- BST (Xh, Xl), (Yh, Yl), 2 keep parts order +-- XST (Ih, Il, Rh, Rl), 4 also reverse parts order +-- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, mm_lib, dp_lib, ring_lib; @@ -106,7 +161,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS CONSTANT c_beamlet_id : NATURAL := g_beamset_id * c_sdp_S_sub_bf; -- MM access settings per packet for u_dp_block_from_mm_dc - CONSTANT c_mm_user_size : NATURAL := c_sdp_W_statistic_sz; + CONSTANT c_mm_user_size : NATURAL := func_sdp_get_stat_from_mm_user_size(g_statistics_type); CONSTANT c_mm_data_size : NATURAL := func_sdp_get_stat_from_mm_data_size(g_statistics_type); CONSTANT c_mm_step_size : NATURAL := func_sdp_get_stat_from_mm_step_size(g_statistics_type); CONSTANT c_mm_nof_data : NATURAL := func_sdp_get_stat_from_mm_nof_data(g_statistics_type); 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 433f50839f8cd26b48eb43b0d41ec6387d20027b..327fa6ce994c3b69172e97f24371010e1e5022fc 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 @@ -114,14 +114,14 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS -- RAM dimensions -- . nof_statistics_per_packet = c_mm_nof_data * c_mm_data_size / c_sdp_W_statistic_sz - CONSTANT c_mm_user_size : NATURAL := c_sdp_W_statistic_sz; - CONSTANT c_mm_data_size : NATURAL := func_sdp_get_stat_from_mm_data_size(g_statistics_type); - CONSTANT c_mm_step_size : NATURAL := func_sdp_get_stat_from_mm_step_size(g_statistics_type); - CONSTANT c_mm_nof_data : NATURAL := func_sdp_get_stat_from_mm_nof_data(g_statistics_type); - CONSTANT c_mm_ram_size : NATURAL := c_mm_nof_data * c_mm_data_size * c_nof_packets_max; -- = c_ram_size + CONSTANT c_mm_user_size : NATURAL := func_sdp_get_stat_from_mm_user_size(g_statistics_type); + CONSTANT c_mm_data_size : NATURAL := func_sdp_get_stat_from_mm_data_size(g_statistics_type); + CONSTANT c_mm_step_size : NATURAL := func_sdp_get_stat_from_mm_step_size(g_statistics_type); + CONSTANT c_mm_nof_data : NATURAL := func_sdp_get_stat_from_mm_nof_data(g_statistics_type); + CONSTANT c_mm_ram_size : NATURAL := c_mm_nof_data * c_mm_data_size * c_nof_packets_max; -- = c_ram_size - CONSTANT c_mm_nof_step : NATURAL := c_mm_step_size / c_mm_data_size; - CONSTANT c_mm_Xsq_span : NATURAL := 2**ceil_log2(c_sdp_N_crosslets_max * c_packet_size); -- XST: 2**ceil_log2(7 * 576) = 4096 + CONSTANT c_mm_nof_step : NATURAL := c_mm_step_size / c_mm_data_size; + CONSTANT c_mm_Xsq_span : NATURAL := 2**ceil_log2(c_sdp_N_crosslets_max * c_packet_size); -- XST: 2**ceil_log2(7 * 576) = 4096 -- Define block timing. CONSTANT c_bsn_init : NATURAL := 0; @@ -514,13 +514,13 @@ BEGIN D := S; -- range c_mm_nof_data = 512 Data values, because -- c_mm_data_size / c_sdp_W_statistic_sz = 1 U := S; -- range c_sdp_N_sub = 512 SST values - I := W MOD c_sdp_W_statistic_sz; -- range c_sdp_W_statistic_sz = 2 words + I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words P := rx_packet_cnt; -- range c_nof_packets_max = 12 = c_sdp_S_pn Packets J := P MOD c_mm_nof_step; -- range c_mm_nof_step = 2 = c_sdp_Q_fft v_exp_data := S * 4; -- due to c_mm_step_size = 4 = c_sdp_W_statistic_sz * c_sdp_Q_fft; IF I = sel_a_b(g_reverse_word_order, 0, 1) THEN - v_exp_data := v_exp_data + 1; -- due to c_mm_user_size = c_sdp_W_statistic_sz = 2 + v_exp_data := v_exp_data + 1; -- due to c_mm_user_size = 2 END IF; IF J = 1 THEN v_exp_data := v_exp_data + 2; -- due to c_sdp_W_statistic_sz = 2 and c_mm_nof_step = 2 > 1 @@ -545,14 +545,14 @@ BEGIN D := S / c_sdp_N_pol_bf; -- range c_mm_nof_data = 488 Data values, because -- c_mm_data_size / c_sdp_W_statistic_sz = 2 = c_sdp_N_pol_bf B := D; -- range c_sdp_S_sub_bf = 488 dual polarization BST values - I := W MOD c_sdp_W_statistic_sz; -- range c_sdp_W_statistic_sz = 2 words + I := W MOD c_mm_user_size; -- range c_mm_user_size = c_sdp_W_statistic_sz = 2 words P := rx_packet_cnt; -- range c_nof_packets_max = 1 - v_exp_data := S * c_sdp_W_statistic_sz; + v_exp_data := S * c_mm_user_size; -- c_mm_user_size = 2 IF g_reverse_word_order = FALSE THEN v_exp_data := v_exp_data + I; ELSE - v_exp_data := v_exp_data - I + c_mm_user_size-1; -- c_mm_user_size = c_sdp_W_statistic_sz = 2 + v_exp_data := v_exp_data - I + c_mm_user_size-1; END IF; ASSERT v_exp_data = v_rx_data REPORT "Wrong BST payload data Rx" SEVERITY ERROR; @@ -586,16 +586,16 @@ BEGIN D := S / c_nof_complex; -- range c_mm_nof_data = 144 Data values, because -- c_mm_data_size / c_sdp_W_statistic_sz = 2 = c_nof_complex X := D; -- range c_sdp_X_sq = 144 complex XST values - I := W MOD c_sdp_W_statistic_sz; -- range c_sdp_W_statistic_sz = 2 words + I := W MOD c_mm_user_size; -- range c_mm_user_size = c_nof_complex * c_sdp_W_statistic_sz = 4 words P := rx_packet_cnt; -- range c_mm_nof_packets J := P MOD g_nof_crosslets; -- range g_nof_crosslets K := P / g_nof_crosslets; -- range g_P_sq - v_exp_data := S * c_sdp_W_statistic_sz; + v_exp_data := D * c_mm_user_size; IF g_reverse_word_order = FALSE THEN v_exp_data := v_exp_data + I; ELSE - v_exp_data := v_exp_data - I + c_mm_user_size-1; -- c_mm_user_size = c_sdp_W_statistic_sz = 2 + v_exp_data := v_exp_data - I + c_mm_user_size-1; -- c_mm_user_size = 4 END IF; v_exp_data := v_exp_data + J * c_packet_size; -- c_packet_size = 576 v_exp_data := v_exp_data + K * c_mm_Xsq_span; -- c_mm_Xsq_span = 4096