diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index 296596eefcc58431cbbdee29cb196ebccc399782..ea3e9fd77656f795abf4c3d42bca1121b0eee892 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -505,10 +505,14 @@ PACKAGE sdp_pkg is FUNCTION func_sdp_get_stat_marker(g_statistics_type : STRING) RETURN NATURAL; 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; FUNCTION func_sdp_get_stat_nof_statistics_per_packet(g_statistics_type : STRING) RETURN NATURAL; + FUNCTION func_sdp_get_stat_app_total_length(g_statistics_type : STRING) RETURN NATURAL; FUNCTION func_sdp_get_stat_udp_total_length(g_statistics_type : STRING) RETURN NATURAL; FUNCTION func_sdp_get_stat_ip_total_length(g_statistics_type : STRING) RETURN NATURAL; @@ -575,11 +579,19 @@ PACKAGE BODY sdp_pkg IS 1)); -- SST END func_sdp_get_stat_nof_signal_inputs; - FUNCTION func_sdp_get_stat_from_mm_data_size(g_statistics_type : STRING) RETURN NATURAL IS + 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_N_pol_bf * c_sdp_W_statistic_sz, -- = 4 + 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 + 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 + 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_data_size; FUNCTION func_sdp_get_stat_from_mm_step_size(g_statistics_type : STRING) RETURN NATURAL IS @@ -587,7 +599,7 @@ PACKAGE BODY sdp_pkg IS BEGIN RETURN sel_a_b(g_statistics_type="BST", c_data_size, -- = 4 sel_a_b(g_statistics_type="XST", c_data_size, -- = 4 - c_sdp_Q_fft * c_data_size)); -- = 4, SST + c_data_size * c_sdp_Q_fft)); -- = 4, SST END func_sdp_get_stat_from_mm_step_size; FUNCTION func_sdp_get_stat_from_mm_nof_data(g_statistics_type : STRING) RETURN NATURAL IS @@ -597,6 +609,7 @@ PACKAGE BODY sdp_pkg IS c_sdp_N_sub)); -- = 512, SST END func_sdp_get_stat_from_mm_nof_data; + -- nof_statistics_per_packet = mm_nof_data * mm_data_size / c_sdp_W_statistic_sz FUNCTION func_sdp_get_stat_nof_statistics_per_packet(g_statistics_type : STRING) RETURN NATURAL IS BEGIN RETURN sel_a_b(g_statistics_type="BST", c_sdp_S_sub_bf * c_sdp_N_pol_bf, -- = 976 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 56f91879bf03794f81ad23870ae24cf2e45d1b9b..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; @@ -48,7 +103,8 @@ ENTITY sdp_statistics_offload IS g_offload_time : NATURAL := c_sdp_offload_time; g_beamset_id : NATURAL := 0; g_P_sq : NATURAL := c_sdp_P_sq; -- use generic to support P_sq = 1 for one node and P_sq = c_sdp_P_sq for multiple nodes (with ring) - g_crosslets_direction : NATURAL := 1 -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction + g_crosslets_direction : NATURAL := 1; -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction + g_reverse_word_order : BOOLEAN := TRUE -- default word order is MSB after LSB, we need to stream LSB after MSB. ); PORT ( -- Clocks and reset @@ -105,6 +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 := 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); @@ -385,10 +442,12 @@ BEGIN u_dp_block_from_mm_dc : ENTITY dp_lib.dp_block_from_mm_dc GENERIC MAP ( + g_user_size => c_mm_user_size, g_data_size => c_mm_data_size, g_step_size => c_mm_step_size, g_nof_data => c_mm_nof_data, - g_reverse_word_order => TRUE -- default word order is MSB after LSB, we need to stream LSB after MSB. + g_word_w => c_word_w, + g_reverse_word_order => g_reverse_word_order ) PORT MAP( dp_rst => dp_rst, 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 33b59b65c850bef7be1f1f6503e2b333b343bac1..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 @@ -32,7 +32,8 @@ -- Usage: -- > as 8 -- > run -a --- e.g. view test_offload_sosi and the rx_sdp_stat_header.app fields +-- . for header: view test_offload_sosi and the rx_sdp_stat_header.app fields +-- . for payload: view rx_val, rx_data and exp_data ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, dp_lib, ring_lib; @@ -55,14 +56,15 @@ ENTITY tb_sdp_statistics_offload IS -- All g_statistics_type : STRING := "SST"; g_offload_time : NATURAL := 50; + g_reverse_word_order : BOOLEAN := TRUE; -- when TRUE then stream LSB word after MSB word. g_gn_index : NATURAL := 5; -- global node (GN) index, must be in range(O_rn, O_rn + N_rn), use > 0 to see effect of g_offload_time -- BST g_beamset_id : NATURAL := 1; -- < c_sdp_N_beamsets -- XST g_O_rn : NATURAL := 4; -- GN index of first ring node (RN) g_N_rn : NATURAL := 8; -- <= c_sdp_N_rn_max = 16, number of nodes in ring - g_P_sq : NATURAL := 1; -- <= c_sdp_P_sq - g_nof_crosslets : NATURAL := 1; -- <= c_sdp_N_crosslets_max + g_P_sq : NATURAL := 4; -- <= c_sdp_P_sq + g_nof_crosslets : NATURAL := 3; -- <= c_sdp_N_crosslets_max g_crosslets_direction : NATURAL := 1 -- > 0 for crosslet transport in positive direction (incrementing RN), else 0 for negative direction ); END tb_sdp_statistics_offload; @@ -97,23 +99,37 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS CONSTANT c_crosslets_info_rec : t_sdp_crosslets_info := (offset_arr => (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15), step => 16); CONSTANT c_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := func_sdp_map_crosslets_info(c_crosslets_info_rec); + -- Crosslets settings + CONSTANT c_mm_nof_crosslets : STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := TO_UVEC(g_nof_crosslets, c_sdp_nof_crosslets_reg_w); + CONSTANT c_mm_nof_packets : NATURAL := func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, g_nof_crosslets); + -- payload data - CONSTANT c_data_size : NATURAL := c_sdp_W_statistic_sz; - CONSTANT c_nof_data : NATURAL := c_nof_statistics_per_packet; + CONSTANT c_packet_size : NATURAL := c_nof_statistics_per_packet * c_sdp_W_statistic_sz; - -- Define SST RAM size for c_nof_packets_max. - CONSTANT c_ram_size : NATURAL := c_nof_data * c_data_size * c_nof_packets_max; + -- Define statistics RAM size for c_nof_packets_max. + CONSTANT c_ram_size : NATURAL := c_packet_size * c_nof_packets_max; CONSTANT c_ram_w : NATURAL := ceil_log2(c_ram_size); --CONSTANT c_ram_buf : t_c_mem := (c_mem_ram_rd_latency, c_ram_w, 32, 2**c_ram_w, 'X'); CONSTANT c_ram_buf : t_c_mem := (1, c_ram_w, 32, 2**c_ram_w, 'X'); + -- 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 := 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 + -- Define block timing. CONSTANT c_bsn_init : NATURAL := 0; - CONSTANT c_nof_block_per_sync : NATURAL := 3 + ceil_div(c_offload_time, c_nof_data) + c_nof_packets_max; -- Sufficient to fit more than c_nof_packets_max offload packets per sync interval. - CONSTANT c_nof_clk_per_block : NATURAL := c_nof_data * c_data_size; - CONSTANT c_nof_valid_per_block : NATURAL := c_nof_data * c_data_size; - CONSTANT c_nof_sync : NATURAL := 3; + -- Sufficient c_nof_block_per_sync to fit more than c_nof_packets_max offload packets per sync interval. + CONSTANT c_nof_block_per_sync : NATURAL := 3 + ceil_div(c_offload_time, c_packet_size) + c_nof_packets_max; + CONSTANT c_nof_clk_per_block : NATURAL := c_packet_size; CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync * c_nof_clk_per_block; + CONSTANT c_nof_sync : NATURAL := 3; SIGNAL tb_end : STD_LOGIC := '0'; @@ -143,11 +159,11 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL offload_sosi : t_dp_sosi; SIGNAL offload_siso : t_dp_siso := c_dp_siso_rst; + SIGNAL test_offload_en : STD_LOGIC := '0'; SIGNAL test_offload_data : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); -- 32 bit SIGNAL test_offload_sosi : t_dp_sosi := c_dp_sosi_rst; - SIGNAL test_offload_en : STD_LOGIC := '0'; - SIGNAL test_offload_sop_cnt : NATURAL; - SIGNAL test_offload_eop_cnt : NATURAL; + SIGNAL test_offload_sop_cnt : NATURAL := 0; + SIGNAL test_offload_eop_cnt : NATURAL := 0; SIGNAL rx_hdr_fields_out : STD_LOGIC_VECTOR(1023 DOWNTO 0); SIGNAL rx_hdr_fields_raw : STD_LOGIC_VECTOR(1023 DOWNTO 0) := (OTHERS => '0'); @@ -163,7 +179,11 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL exp_xst_signal_input_A : NATURAL; SIGNAL exp_xst_signal_input_B : NATURAL; - -- Signals used to change settings of sdp_info. + SIGNAL rx_val : STD_LOGIC := '0'; + SIGNAL rx_data : NATURAL; + SIGNAL exp_data : NATURAL; + + -- Signals used to change settings of sdp_info. SIGNAL sdp_info : t_sdp_info := ( TO_UVEC(601, 16), -- station_id '0', -- antenna_band_index @@ -185,8 +205,6 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL source_gn : NATURAL; -- source node GN SIGNAL subband_calibrated_flag : STD_LOGIC := '0'; - SIGNAL nof_crosslets : STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0'); - SIGNAL nof_packets : NATURAL; -- Signals used for starting processes. SIGNAL ram_wr_data : STD_LOGIC_VECTOR(c_ram_buf.dat_w-1 DOWNTO 0); @@ -194,9 +212,8 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL ram_wr_en : STD_LOGIC; SIGNAL init_ram_done : STD_LOGIC := '0'; - SIGNAL in_sync_hold : STD_LOGIC := '0'; SIGNAL in_sync_cnt : NATURAL := 0; - SIGNAL test_sync_cnt : INTEGER; + SIGNAL test_sync_cnt : INTEGER := 0; SIGNAL rx_packet_cnt : NATURAL := 0; SIGNAL rx_valid_cnt : NATURAL := 0; @@ -209,14 +226,23 @@ ARCHITECTURE tb OF tb_sdp_statistics_offload IS SIGNAL dbg_c_nof_signal_inputs : NATURAL := c_nof_signal_inputs; SIGNAL dbg_c_nof_packets_max : NATURAL := c_nof_packets_max; SIGNAL dbg_c_beamlet_index : NATURAL := c_beamlet_index; - SIGNAL dbg_c_data_size : NATURAL := c_data_size; - SIGNAL dbg_c_nof_data : NATURAL := c_nof_data; + SIGNAL dbg_c_packet_size : NATURAL := c_packet_size; + SIGNAL dbg_c_mm_user_size : NATURAL := c_mm_user_size; + SIGNAL dbg_c_mm_data_size : NATURAL := c_mm_data_size; + SIGNAL dbg_c_mm_step_size : NATURAL := c_mm_step_size; + SIGNAL dbg_c_mm_nof_data : NATURAL := c_mm_nof_data; + SIGNAL dbg_c_mm_ram_size : NATURAL := c_mm_ram_size; + SIGNAL dbg_c_mm_nof_step : NATURAL := c_mm_nof_step; + SIGNAL dbg_c_mm_Xsq_span : NATURAL := c_mm_Xsq_span; SIGNAL dbg_c_ram_size : NATURAL := c_ram_size; SIGNAL dbg_c_crosslets_info_rec : t_sdp_crosslets_info := c_crosslets_info_rec; SIGNAL dbg_c_crosslets_info_slv : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0) := c_crosslets_info_slv; BEGIN + -- Check consistency of constant value dependencies + ASSERT c_ram_size = c_mm_ram_size REPORT "Wrong derivation of RAM size." SEVERITY FAILURE; + dp_rst <= '1', '0' AFTER c_dp_clk_period*7; dp_clk <= (NOT dp_clk) OR tb_end AFTER c_dp_clk_period/2; @@ -292,36 +318,23 @@ BEGIN WAIT; END PROCESS; - -- Crosslets settings - nof_crosslets <= TO_UVEC(g_nof_crosslets, c_sdp_nof_crosslets_reg_w); - nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, g_P_sq, g_nof_crosslets); - -- Counters to time expected exp_sdp_stat_header fields per offload packet - p_exp_counters : PROCESS(dp_clk) + p_test_counters : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - -- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync - IF test_offload_en = '0' THEN - in_sync_cnt <= 0; - test_offload_sop_cnt <= 0; - test_offload_eop_cnt <= 0; - ELSE - -- Count test_offload_sosi sync integration intervals - IF in_sosi.sync = '1' THEN - in_sync_cnt <= in_sync_cnt + 1; - END IF; - - -- Count test_offload_sosi packets - IF test_offload_sosi.sop = '1' THEN - test_offload_sop_cnt <= test_offload_sop_cnt + 1; -- early count - END IF; - IF test_offload_sosi.eop = '1' THEN - test_offload_eop_cnt <= test_offload_eop_cnt + 1; -- after count - END IF; + -- Count test_offload_sosi packets + IF test_offload_sosi.sop = '1' THEN + test_offload_sop_cnt <= test_offload_sop_cnt + 1; -- early count + END IF; + IF test_offload_sosi.eop = '1' THEN + test_offload_eop_cnt <= test_offload_eop_cnt + 1; -- after count END IF; END IF; END PROCESS; - test_sync_cnt <= in_sync_cnt + 0; -- optionally adjust to fit test_offload_sosi + + -- Count sync intervals using in_sosi.sync, because there is no test_offload_sosi.sync + in_sync_cnt <= in_sync_cnt + 1 WHEN rising_edge(dp_clk) AND in_sosi.sync = '1'; + test_sync_cnt <= in_sync_cnt - 1; -- optionally adjust to fit test_offload_sosi -- derive current X_sq correlator cell index cur_X_sq_cell <= (test_offload_eop_cnt / g_nof_crosslets) MOD g_P_sq; @@ -428,21 +441,16 @@ BEGIN END PROCESS; -- Count number of packets in a sync interval. - -- There is no active test_offload_sosi.sync to restart the count. Therefore capture the in_sosi.sync in in_sync_hold, and - -- use in_sync_hold with test_offload_sosi.sop to start counting packets from 0, at the start of every sync interval. + -- There is no active test_offload_sosi.sync to restart the count, therefore + -- use in_sosi.sync to reset the count for the next test_offload_sosi.sync + -- interval p_rx_packet_cnt : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF test_offload_sosi.sop = '1' THEN - IF in_sync_hold = '1' THEN - in_sync_hold <= '0'; - rx_packet_cnt <= 0; - ELSE - rx_packet_cnt <= rx_packet_cnt + 1; - END IF; - END IF; IF in_sosi.sync = '1' THEN - in_sync_hold <= '1'; + rx_packet_cnt <= 0; + ELSIF test_offload_sosi.eop = '1' THEN + rx_packet_cnt <= rx_packet_cnt + 1; END IF; END IF; END PROCESS; @@ -451,12 +459,8 @@ BEGIN p_verify_nof_packets : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF init_ram_done = '1' THEN - - IF in_sosi.sync = '1' AND rx_packet_cnt > 0 THEN - ASSERT rx_packet_cnt = nof_packets-1 REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; - END IF; - + IF in_sosi.sync = '1' AND in_sync_cnt > 1 THEN + ASSERT rx_packet_cnt = c_mm_nof_packets REPORT "Wrong number of packets per sync interval" SEVERITY ERROR; END IF; END IF; END PROCESS; @@ -464,12 +468,144 @@ BEGIN p_verify_nof_valid_per_packet : PROCESS(dp_clk) BEGIN IF rising_edge(dp_clk) THEN - IF test_offload_sosi.sop = '1' THEN - rx_valid_cnt <= 1; - ELSIF test_offload_sosi.eop = '1' THEN - ASSERT rx_valid_cnt+1 = c_nof_valid_per_block REPORT "Wrong number of valid per packet" SEVERITY ERROR; - ELSE - rx_valid_cnt <= rx_valid_cnt + 1; -- test_offload_sosi.valid has no gaps + IF test_offload_sosi.eop = '1' THEN + rx_valid_cnt <= 0; + ASSERT rx_valid_cnt = c_packet_size - 1 REPORT "Wrong number of valid per packet" SEVERITY ERROR; + ELSIF test_offload_sosi.valid = '1' THEN + rx_valid_cnt <= rx_valid_cnt + 1; + END IF; + END IF; + END PROCESS; + + p_verify_payload : PROCESS(dp_clk) + VARIABLE W : NATURAL; -- 32bit Words + VARIABLE D : NATURAL; -- Data values of c_mm_data_size + VARIABLE S : NATURAL; -- Statistic values of c_sdp_W_statistic_sz + VARIABLE P : NATURAL; -- Packet count + VARIABLE I, J, K, L : NATURAL; -- auxiliary index + VARIABLE U : NATURAL; -- real sUbband SST values + VARIABLE B : NATURAL; -- dual polarization Beamlet BST values + VARIABLE X : NATURAL; -- complex crosslet XST values + VARIABLE v_rx_data : NATURAL; -- received (rx) 32bit word + VARIABLE v_exp_data : NATURAL; -- expected (exp) 32bit word + BEGIN + IF rising_edge(dp_clk) THEN + rx_val <= '0'; + v_rx_data := TO_UINT(test_offload_sosi.data); + IF test_offload_sosi.valid = '1' THEN + IF g_statistics_type = "SST" THEN + -- Indices: + -- W: 0 1 2 3 4 5 ... 1022 1023 + -- U = D = S: 0 1 2 511 + -- I: 0 1 0 1 0 1 ... 0 1 + -- P: J: Words values: + -- 0 0 0 1 4 5 8 9 ... 2044 2045 + -- 1 1 2 3 6 7 10 11 ... 2046 2047 + -- 2 0 2048 2049 2052 2053 2056 2057 ... 4092 4093 + -- 3 1 2050 2051 2054 2055 2058 2059 ... 4094 4095 + -- ... ... + -- 11 1 10242 10243 10246 10247 10250 10251 ... 12286 12287 + -- + -- g_reverse_word_order = TRUE: swaps odd and even W columns, because + -- c_mm_user_size = c_sdp_W_statistic_sz = 2 + + W := rx_valid_cnt; -- range c_packet_size = 1024 32bit Words + S := W / c_sdp_W_statistic_sz; -- range c_nof_statistics_per_packet = 512 Statistic values + 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_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 = 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 + END IF; + v_exp_data := v_exp_data + (P/2) * 2048; -- due to c_packet_size = 1024 and c_mm_nof_step = 2 > 1 + ASSERT v_exp_data = v_rx_data REPORT "Wrong SST payload data Rx" SEVERITY ERROR; + + ELSIF g_statistics_type = "BST" THEN + -- Indices: + -- W: 0 1 2 3 4 5 ... 1948 1949 1950 1951 + -- S: 0 1 2 ... 974 975 + -- B = D: 0 1 ... 487 + -- I: 0 1 2 3 0 ... 0 1 2 3 + -- P: Words values: + -- 0 0 1 2 3 4 5 ... 1948 1949 1950 1951 + -- + -- g_reverse_word_order = TRUE: swaps odd and even W columns, because + -- c_mm_user_size = c_sdp_W_statistic_sz = 2 + + W := rx_valid_cnt; -- range c_packet_size = 1952 + S := W / c_sdp_W_statistic_sz; -- range c_nof_statistics_per_packet = 976 Statistic values + 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_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_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; + END IF; + ASSERT v_exp_data = v_rx_data REPORT "Wrong BST payload data Rx" SEVERITY ERROR; + + ELSIF g_statistics_type = "XST" THEN + -- . g_P_sq = 4 + -- . g_nof_crosslets = 3 + -- . c_sdp_N_crosslets_max = 7 --> c_mm_Xsq_span = 2**ceil_log2(7 * 576) = 4096 + -- + -- W: 0 1 2 3 4 5 ... 572 573 574 575 + -- S: 0 1 2 ... 286 287 + -- X = D: 0 1 ... 143 + -- I: 0 1 2 3 0 ... 0 1 2 3 + -- P: J: K: Word values: + -- 0 0 0 0 1 2 3 4 5 ... 572 573 574 575 + -- 1 1 576 ... + -- 2 2 1052 ... + -- + -- 3 0 1 4096 ... + -- 4 1 4672 ... + -- 5 2 5244 ... + -- ... + -- 9 0 3 12288 ... + -- 10 1 12864 ... + -- 11 2 13436 ... + -- + -- g_reverse_word_order = TRUE: swaps odd and even W columns, because + -- c_mm_user_size = c_sdp_W_statistic_sz = 2 + + W := rx_valid_cnt; -- range c_packet_size = 576 + S := W / c_sdp_W_statistic_sz; -- range c_nof_statistics_per_packet = 288 Statistic values + 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_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 := 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 = 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 + ASSERT v_exp_data = v_rx_data REPORT "Wrong XST payload data Rx" SEVERITY ERROR; + + END IF; + -- for debug in wave window + rx_val <= '1'; + rx_data <= v_rx_data; + exp_data <= v_exp_data; END IF; END IF; END PROCESS; @@ -535,6 +671,7 @@ BEGIN GENERIC MAP ( g_statistics_type => g_statistics_type, g_offload_time => g_offload_time, + g_reverse_word_order => g_reverse_word_order, g_beamset_id => g_beamset_id, g_P_sq => g_P_sq, g_crosslets_direction => g_crosslets_direction @@ -570,7 +707,7 @@ BEGIN sdp_info => sdp_info, subband_calibrated_flag => subband_calibrated_flag, - nof_crosslets => nof_crosslets, + nof_crosslets => c_mm_nof_crosslets, crosslets_info => in_crosslets_info_slv ); diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd index db3baf5a19b8352c9da6e203b68ddc8cdb0ad2e4..a688d26acd7d88aba8f60ca51f3409710bf0c36e 100644 --- a/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_tb_sdp_statistics_offload.vhd @@ -40,6 +40,7 @@ BEGIN -- -- All -- g_statistics_type : STRING := "SST"; -- g_offload_time : NATURAL := 500; +-- g_reverse_word_order : BOOLEAN := TRUE -- when TRUE then stream LSB word after MSB word. -- g_gn_index : NATURAL := 1; -- global node (GN) index, use > 0 to see effect of g_offload_time -- -- BST -- g_beamset_id : NATURAL := 0; @@ -50,14 +51,17 @@ BEGIN -- g_nof_crosslets : NATURAL := 1; -- g_crosslets_direction : INTEGER := 1; -- +1 or -1 - u_sst : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST", 50, 3, 0, 0); - u_bst_0 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, 1, 0, 0); - u_bst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, 1, 1, 0); - u_xst_P1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 0, 16, 1, 1, 1); - u_xst_P1_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 0, 16, 1, 3, 1); - u_xst_P9 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 0, 16, 9, 1, 1); - u_xst_P9_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 0, 16, 9, 3, 1); - u_xst_P9_N3_neg : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 0, 16, 9, 3, 0); - u_xst_P8_N7_RN1_15 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, 1, 0, 1, 15, 8, 7, 0); + u_sst : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST", 50, TRUE, 3, 0, 0); + u_sst_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("SST", 50, FALSE, 3, 0, 0); + u_bst_0 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, TRUE, 1, 0, 0); + u_bst_0_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, FALSE, 1, 0, 0); + u_bst_1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("BST", 50, TRUE, 1, 1, 0); + u_xst_P1 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 1, 1, 1); + u_xst_P1_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 1, 3, 1); + u_xst_P9 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 1, 1); + u_xst_P9_N3 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 3, 1); + u_xst_P9_N3_no_reverse : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, FALSE, 1, 0, 0, 16, 9, 3, 1); + u_xst_P9_N3_neg : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 0, 16, 9, 3, 0); + u_xst_P8_N7_RN1_15 : ENTITY work.tb_sdp_statistics_offload GENERIC MAP("XST", 50, TRUE, 1, 0, 1, 15, 8, 7, 0); END tb; diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd index 795c772f562a4c8e01bd747ff4e3c6bc49016fed..462d489dce2291ffc9e2e82d5603d9bba517bbb4 100644 --- a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd @@ -18,11 +18,42 @@ -- -------------------------------------------------------------------------- -- Author: --- . Pieter Donker, R van der Walle +-- . Pieter Donker, R van der Walle, E. Kooistra -- Purpose: -- . Read a block of data from memory mapped (MM) location and stream it as a block of data. -- Description: -- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank +-- +-- . g_*_size, g_word_w: +-- The g_*_size values are in number of g_word_w memory words, so e.g. +-- 32bit words. The 32bit words are read in data blocks of g_data_size +-- words. The data block contains U = g_data_size / g_user_size +-- number of user words. U is and integer. This occurs e.g. for U = 2 +-- when the data block contains: +-- - a complex value, so with real part and imag part +-- - dual polarization value, so with X polarization and Y polarization +-- The user words contain g_user_size number of g_word_w = 32bit words. +-- The output out_sosi.data width is also g_word_w bits. +-- +-- . g_step_size: +-- The g_step_size = K * g_data_size, where K >= 1 to allow read out of +-- data blocks that are interleaved by a factor K. +-- +-- . g_nof_data and start_pulse, start_address, mm_mosi, mm_miso, mm_done: +-- The g_nof_data is the number of data blocks that are read out via +-- mm_mosi/mm_miso per start_pulse, to form a new aggregate output block +-- with out_sosi.sop and out_sosi.eop. When the read out is done, then +-- mm_done pulses and a new start_pulse can be issued. By incrementing +-- the start_address for every start_pulse it is possible to read out K +-- interleaved sets of data blocks from the memory. +-- +-- . g_reverse_word_order per g_user_size: +-- The g_reverse_word_order has no effect when FALSE, but reverses the +-- read out order of the 32bit words per user word when TRUE. The +-- g_reverse_word_order has to apply per user word and not per data block, +-- to preserve the order of the user parts (e.g. real and imag, X and Y +-- polarization) in a data block. +-- -- -------------------------------------------------------------------------- LIBRARY IEEE,common_lib; @@ -34,10 +65,11 @@ USE work.dp_stream_pkg.ALL; ENTITY dp_block_from_mm IS GENERIC ( + g_user_size : NATURAL; g_data_size : NATURAL; g_step_size : NATURAL; g_nof_data : NATURAL; - g_data_w : NATURAL := c_word_w; + g_word_w : NATURAL := c_word_w; g_mm_rd_latency : NATURAL := 1; -- default 1 from rd_en to rd_val, use 2 to ease timing closure g_reverse_word_order : BOOLEAN := FALSE ); @@ -58,23 +90,25 @@ END dp_block_from_mm; ARCHITECTURE rtl OF dp_block_from_mm IS CONSTANT c_mem_size : NATURAL := g_step_size * g_nof_data; - CONSTANT c_word_index_rst : NATURAL := sel_a_b(g_reverse_word_order, g_data_size - 1, 0); TYPE t_reg IS RECORD - busy : STD_LOGIC; - sop : STD_LOGIC; - eop : STD_LOGIC; - word_index : NATURAL; - step_index : NATURAL; + busy : STD_LOGIC; + sop : STD_LOGIC; + eop : STD_LOGIC; + user_index : NATURAL RANGE 0 TO g_user_size; -- word index in g_user_size + data_index : NATURAL RANGE 0 TO g_data_size; -- default word order index in g_data_size + word_index : NATURAL RANGE 0 TO g_data_size; -- default or reversed word order index in g_data_size + step_address : NATURAL RANGE 0 TO c_mem_size; -- step address offset END RECORD; - CONSTANT c_reg_rst : t_reg := ('0', '0', '0', c_word_index_rst, 0); + CONSTANT c_reg_rst : t_reg := ('0', '0', '0', 0, 0, 0, 0); SIGNAL r : t_reg; SIGNAL nxt_r : t_reg; - SIGNAL mm_address : NATURAL := 0; SIGNAL last_mm_address : NATURAL := 0; + SIGNAL mm_address : NATURAL := 0; + SIGNAL mm_address_rev : NATURAL := 0; SIGNAL r_sop_p : STD_LOGIC; SIGNAL r_eop_p : STD_LOGIC; @@ -84,8 +118,9 @@ ARCHITECTURE rtl OF dp_block_from_mm IS BEGIN last_mm_address <= g_step_size * (g_nof_data - 1) + g_data_size + start_address - 1; - mm_address <= start_address + r.word_index + r.step_index; - + mm_address <= start_address + r.data_index + r.step_address; -- default word order per g_user_size + mm_address_rev <= start_address + r.word_index + r.step_address; -- reverse word order per g_user_size + -- Take care of g_mm_rd_latency for out_sosi.sop and out_sosi.eop r_sop_p <= r.sop WHEN rising_edge(clk); r_eop_p <= r.eop WHEN rising_edge(clk); @@ -95,7 +130,7 @@ BEGIN u_sosi : PROCESS(r, mm_miso, out_sop, out_eop) BEGIN out_sosi <= c_dp_sosi_rst; -- To avoid Modelsim warnings on conversion to integer from unused fields. - out_sosi.data <= RESIZE_DP_DATA(mm_miso.rddata(g_data_w-1 DOWNTO 0)); + out_sosi.data <= RESIZE_DP_DATA(mm_miso.rddata(g_word_w-1 DOWNTO 0)); out_sosi.valid <= mm_miso.rdval; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1) out_sosi.sop <= out_sop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.sop can be used for output sop out_sosi.eop <= out_eop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.eop can be used for output eop @@ -112,17 +147,20 @@ BEGIN END IF; END PROCESS; - p_comb : PROCESS(r, start_pulse, out_siso, mm_address, last_mm_address) - VARIABLE v : t_reg; + p_comb : PROCESS(r, start_pulse, out_siso, mm_address, mm_address_rev, last_mm_address) + VARIABLE v : t_reg; + VARIABLE v_base : NATURAL; + VARIABLE v_reverse : NATURAL; BEGIN v := r; v.sop := '0'; v.eop := '0'; - mm_mosi <= c_mem_mosi_rst; -- use default 0 to avoid Warning: (vsim-8684) No drivers exist on out port .wr, .wrdata - mm_mosi.address <= TO_MEM_ADDRESS(mm_address); -- only use mosi.rd and mosi.address + + -- Use default c_mem_mosi_rst to avoid Warning: (vsim-8684) No drivers exist on out port .wr, .wrdata + mm_mosi <= c_mem_mosi_rst; IF r.busy = '0' AND start_pulse = '1' THEN - -- initiate next block + -- initiate next output block v.busy := '1'; END IF; @@ -130,57 +168,54 @@ BEGIN -- support zero gaps between output blocks IF v.busy = '1' THEN IF out_siso.ready = '1' THEN - -- continue with block + -- Continue with output block mm_mosi.rd <= '1'; - IF g_reverse_word_order THEN - - IF r.word_index > 0 THEN - v.word_index := r.word_index - 1; - ELSE - v.word_index := g_data_size - 1; - v.step_index := r.step_index + g_step_size; - END IF; - - -- check start of block - IF r.word_index = g_data_size - 1 AND r.step_index = 0 THEN - v.sop := '1'; - END IF; - + -- Calculate data_index for default word order + IF r.data_index < g_data_size - 1 THEN + v.data_index := r.data_index + 1; ELSE + v.data_index := 0; + v.step_address := r.step_address + g_step_size; + END IF; - IF r.word_index < g_data_size - 1 THEN - v.word_index := r.word_index + 1; - ELSE - v.word_index := 0; - v.step_index := r.step_index + g_step_size; - END IF; - - -- check start of block - IF r.word_index = 0 AND r.step_index = 0 THEN - v.sop := '1'; - END IF; + -- maintain user_index within g_user_size + IF r.user_index < g_user_size - 1 THEN + v.user_index := r.user_index + 1; + ELSE + v.user_index := 0; + END IF; + -- check start of output block + IF r.data_index = 0 AND r.step_address = 0 THEN + v.sop := '1'; END IF; - - -- check end of block - IF g_reverse_word_order THEN - IF mm_address = last_mm_address - (g_data_size - 1) THEN -- with reversed word order the last word to read is actually the first word of the last step index - v.eop := '1'; - -- prepare for next block - v.busy := '0'; - v.step_index := 0; - v.word_index := g_data_size - 1; - END IF; - ELSIF mm_address >= last_mm_address THEN -- g_reverse_word_order = False + + -- check end of output block + IF mm_address >= last_mm_address THEN v.eop := '1'; - -- prepare for next block + -- prepare for next output block at next start_pulse v.busy := '0'; - v.step_index := 0; - v.word_index := 0; + v.step_address := 0; + v.data_index := 0; + v.user_index := 0; END IF; END IF; END IF; + + -- Default word order + v.word_index := v.data_index; + mm_mosi.address <= TO_MEM_ADDRESS(mm_address); + + -- Account for g_reverse_word_order + IF g_reverse_word_order THEN + v_base := v.data_index - v.user_index; -- data_index of first word in g_user_size + v_reverse := g_user_size - 1 - v.user_index; -- reverse word index in g_user_size + v.word_index := v_base + v_reverse; + + mm_mosi.address <= TO_MEM_ADDRESS(mm_address_rev); + END IF; + nxt_r <= v; END PROCESS; diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd index cdf640ced48b4b93bd1906b931864646998525b6..0ac01ec489d22cf6d3e2843e7df9e9e6243e2150 100644 --- a/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_from_mm_dc.vhd @@ -24,6 +24,7 @@ -- this is a dual-clock wrapper around dp_block_from_mm.vhd -- Description: -- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank +-- . see dp_block_from_mm.vhd -- -------------------------------------------------------------------------- LIBRARY IEEE,common_lib; @@ -35,9 +36,11 @@ USE work.dp_stream_pkg.ALL; ENTITY dp_block_from_mm_dc IS GENERIC ( + g_user_size : NATURAL; g_data_size : NATURAL; g_step_size : NATURAL; g_nof_data : NATURAL; + g_word_w : NATURAL := c_word_w; g_reverse_word_order : BOOLEAN := FALSE ); PORT ( @@ -135,9 +138,11 @@ BEGIN u_dp_block_from_mm : ENTITY work.dp_block_from_mm GENERIC MAP ( + g_user_size => g_user_size, g_data_size => g_data_size, g_step_size => g_step_size, g_nof_data => g_nof_data, + g_word_w => g_word_w, g_reverse_word_order => g_reverse_word_order ) PORT MAP ( diff --git a/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd index e94cd4efd070011f1e89c84d1ca3ffdd8a6c89ed..20ca5fa3b09f0bf0ae1faa8e2cd028927add33f5 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_align_v2.vhd @@ -418,10 +418,11 @@ BEGIN gen_mm_to_dp : FOR I IN 0 TO g_nof_streams-1 GENERATE u_mm_to_dp: ENTITY work.dp_block_from_mm GENERIC MAP ( + g_user_size => 1, g_data_size => 1, g_step_size => 1, g_nof_data => g_block_size, - g_data_w => g_data_w, + g_word_w => g_data_w, g_mm_rd_latency => g_rd_latency, g_reverse_word_order => FALSE ) diff --git a/libraries/base/dp/tb/vhdl/tb_dp_block_from_mm.vhd b/libraries/base/dp/tb/vhdl/tb_dp_block_from_mm.vhd index d139f3759ed1daaac47c051f7902127421137580..321286228995bdcf88e91619cccaaf1e3de9306e 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_block_from_mm.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_block_from_mm.vhd @@ -33,6 +33,9 @@ -- . p_verify_read, set ram address (using g_data_size and g_step_size) to check and -- read value from ram, also set expected ram value. -- . p_verify_check, check if ram_value is equal to expected value. +-- +-- Remark: +-- . g_user_size and g_reverse_word_order are verified in tb_sdp_statistics_offload.vhd -- -------------------------------------------------------------------------- -- > as 10 @@ -222,6 +225,7 @@ BEGIN -- DUT, dp_block_from_mm u_dp_block_from_mm: ENTITY work.dp_block_from_mm GENERIC MAP ( + g_user_size => g_data_size, g_data_size => g_data_size, g_step_size => g_step_size, g_nof_data => g_nof_data diff --git a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd index 1c464c468c67424c91dadffc99860e32c941e4c4..30f6a9475042ae14f1f04d2c064b0fa4d32fe4c5 100644 --- a/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd +++ b/libraries/base/dp/tb/vhdl/tb_dp_bsn_align_v2.vhd @@ -603,10 +603,11 @@ BEGIN gen_mm_to_dp : FOR I IN 0 TO g_nof_streams-1 GENERATE u_mm_to_dp: ENTITY work.dp_block_from_mm GENERIC MAP ( + g_user_size => 1, g_data_size => 1, g_step_size => 1, g_nof_data => g_block_size, - g_data_w => g_data_w, + g_word_w => g_data_w, g_mm_rd_latency => g_rd_latency, g_reverse_word_order => FALSE )