-
Eric Kooistra authoredEric Kooistra authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
sdp_pkg.vhd 58.21 KiB
-------------------------------------------------------------------------------
--
-- Copyright 2020
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Author: R. van der Walle, E. Kooistra
-- Purpose:
-- . This package contains sdp specific constants.
-- Description:
-- Remark:
-- . See Document: L3 SDP Decision: SDP Parameter definitions.
-- https://support.astron.nl/confluence/display/L2M/L3+SDP+Decision%3A+SDP+Parameter+definitions
-------------------------------------------------------------------------------
LIBRARY ieee, common_lib, rTwoSDF_lib, fft_lib, filter_lib, wpfb_lib;
USE IEEE.std_logic_1164.ALL;
USE common_lib.common_pkg.ALL;
USE common_lib.common_mem_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE common_lib.common_network_layers_pkg.ALL;
USE rTwoSDF_lib.rTwoSDFPkg.ALL;
USE fft_lib.fft_pkg.ALL;
USE filter_lib.fil_pkg.ALL;
USE wpfb_lib.wpfb_pkg.ALL;
PACKAGE sdp_pkg is
-------------------------------------------------
-- SDP info record as defined in:
-- LOFAR2-9258-SDP info per antenna band
-------------------------------------------------
TYPE t_sdp_info IS RECORD
station_id : STD_LOGIC_VECTOR(15 DOWNTO 0);
antenna_band_index : STD_LOGIC;
observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
nyquist_zone_index : STD_LOGIC_VECTOR(1 DOWNTO 0);
f_adc : STD_LOGIC;
fsub_type : STD_LOGIC;
beam_repositioning_flag : STD_LOGIC;
O_si : STD_LOGIC_VECTOR(7 DOWNTO 0);
N_si : STD_LOGIC_VECTOR(7 DOWNTO 0);
O_rn : STD_LOGIC_VECTOR(7 DOWNTO 0);
N_rn : STD_LOGIC_VECTOR(7 DOWNTO 0);
block_period : STD_LOGIC_VECTOR(15 DOWNTO 0);
END RECORD;
CONSTANT c_sdp_info_rst : t_sdp_info :=
( (OTHERS => '0'), '0', (OTHERS => '0'), (OTHERS => '0'),
'0', '0', '0',
(OTHERS => '0'), (OTHERS => '0'), (OTHERS => '0'), (OTHERS => '0'),
(OTHERS => '0') );
-------------------------------------------------
-- SDP specific parameters as defined in:
-- L3 SDP Decision: SDP Parameter definitions
CONSTANT c_sdp_f_adc_MHz : NATURAL := 200;
CONSTANT c_sdp_N_beamsets : NATURAL := 2;
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; -- gn 0:31 --> pn 0:15, pn 0:15 per antenna band
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_sub : NATURAL := 512;
CONSTANT c_sdp_N_sync_rcu : NATURAL := 1;
CONSTANT c_sdp_N_taps : NATURAL := 16;
CONSTANT c_sdp_P_sq : NATURAL := 9;
CONSTANT c_sdp_Q_fft : NATURAL := 2;
CONSTANT c_sdp_S_pn : NATURAL := 12;
CONSTANT c_sdp_S_rcu : NATURAL := 3;
CONSTANT c_sdp_S_sub_bf : NATURAL := 488;
CONSTANT c_sdp_V_ring_pkt_len_max : NATURAL := 48; -- for 16 nodes
CONSTANT c_sdp_V_sample_delay : NATURAL := 4096;
CONSTANT c_sdp_V_si_db : NATURAL := 1024;
CONSTANT c_sdp_V_si_db_large : NATURAL := 131072;
CONSTANT c_sdp_V_si_histogram : NATURAL := 512;
CONSTANT c_sdp_W_adc : NATURAL := 14;
CONSTANT c_sdp_W_adc_jesd : NATURAL := 16;
CONSTANT c_sdp_W_fir_coef : NATURAL := 16;
CONSTANT c_sdp_W_subband : NATURAL := 18;
CONSTANT c_sdp_W_crosslet : NATURAL := 16;
CONSTANT c_sdp_W_beamlet_sum : NATURAL := 18;
CONSTANT c_sdp_W_beamlet : NATURAL := 8;
CONSTANT c_sdp_W_gn_id : NATURAL := 5;
CONSTANT c_sdp_W_statistic : NATURAL := 64;
CONSTANT c_sdp_W_statistic_sz : NATURAL := 2; -- = c_sdp_W_statistic / c_word_w
CONSTANT c_sdp_W_sub_weight : NATURAL := 16; -- = w in s(w, p), s = signed
CONSTANT c_sdp_W_sub_weight_fraction : NATURAL := 13; -- = p in s(w, p)
CONSTANT c_sdp_W_sub_weight_magnitude : NATURAL := c_sdp_W_sub_weight - c_sdp_W_sub_weight_fraction - 1; -- = 2
CONSTANT c_sdp_W_beamlet_scale : NATURAL := 16; -- = w in u(w, p), u = unsigned
CONSTANT c_sdp_W_beamlet_scale_fraction : NATURAL := 15; -- = p in u(w, p)
CONSTANT c_sdp_W_beamlet_scale_magnitude : NATURAL := c_sdp_W_beamlet_scale - c_sdp_W_beamlet_scale_fraction; -- = 1
CONSTANT c_sdp_W_bf_weight : NATURAL := 16; -- = w in s(w, p), s = signed
CONSTANT c_sdp_W_bf_weight_fraction : NATURAL := 14; -- = p in s(w, p)
CONSTANT c_sdp_W_bf_weight_magnitude : NATURAL := c_sdp_W_bf_weight - c_sdp_W_bf_weight_fraction - 1; -- = 1
-- Derived constants
CONSTANT c_sdp_FS_adc : NATURAL := 2**(c_sdp_W_adc - 1); -- full scale FS corresponds to amplitude 1.0
CONSTANT c_sdp_N_clk_per_sync : NATURAL := c_sdp_f_adc_MHz*10**6; -- Default 200M clock cycles per second
CONSTANT c_sdp_N_sync_jesd : NATURAL := c_sdp_S_pn * c_sdp_N_sync_rcu / c_sdp_S_rcu; -- = 4, nof JESD IP sync outputs per PN
CONSTANT c_sdp_P_pfb : NATURAL := c_sdp_S_pn / c_sdp_Q_fft;
CONSTANT c_sdp_T_adc : TIME := (10**6 / c_sdp_f_adc_MHz) * 1 ps;
CONSTANT c_sdp_T_sub : TIME := c_sdp_N_fft * c_sdp_T_adc;
CONSTANT c_sdp_W_bf_product : NATURAL := c_sdp_W_subband + c_sdp_W_bf_weight -1;
CONSTANT c_sdp_X_sq : NATURAL := c_sdp_S_pn * c_sdp_S_pn;
CONSTANT c_sdp_block_period : NATURAL := c_sdp_N_fft * 1000 / c_sdp_f_adc_MHz; -- = 5120 [ns]
-- Default / tb values
CONSTANT c_sdp_beamlet_scale_default : NATURAL := 2**15;
-----------------------------------------------------------------------------
-- PFB
-----------------------------------------------------------------------------
-- In SDP c_nof_channels = 2**nof_chan = 1 and wb_factor = 1,
-- therefore these parameters are not explicitly used in calculation of derived constants
-- LTS 2020_11_23:
--CONSTANT c_sdp_wpfb_subbands : t_wpfb :=
-- (1, c_sdp_N_fft, 0, c_sdp_P_pfb,
-- c_sdp_N_taps, 1, c_sdp_W_adc, 16, c_sdp_W_fir_coef,
-- true, false, true, 16, c_sdp_W_subband, 1, 18, 2,
-- true, 54, 2, 195313, c_fft_pipeline, c_fft_pipeline,
-- c_fil_ppf_pipeline);
-- LTS 2021-02-03, changes based on results from u_wpfb_stage22 in tb_tb_verify_pfb_wg.vhd:
-- . fil_backoff_w = 0 (was 1)
-- . fil_out_dat_w = fft_in_dat_w = 17 (was 16)
-- . g_fft_out_gain_w = 0 (was 1)
-- . g_fft_stage_dat_w = 22 (was 18)
-- . g_fft_guard_w = 1 (was 2)
CONSTANT c_sdp_wpfb_subbands : t_wpfb :=
(1, c_sdp_N_fft, 0, c_sdp_P_pfb,
c_sdp_N_taps, 0, c_sdp_W_adc, 17, c_sdp_W_fir_coef,
true, false, true, 17, c_sdp_W_subband, 0, 22, 1,
true, 54, c_sdp_W_statistic_sz, 195313, c_fft_pipeline, c_fft_pipeline,
c_fil_ppf_pipeline);
-----------------------------------------------------------------------------
-- Statistics offload
-----------------------------------------------------------------------------
-- The statistics offload uses the same 1GbE port as the NiosII for M&C. The 1GbE addresses defined in SW and here in FW.
-- See NiosII code:
-- https://git.astron.nl/desp/hdl/-/blob/master/libraries/unb_osy/unbos_eth.h
-- https://git.astron.nl/desp/hdl/-/blob/master/libraries/unb_osy/unbos_eth.c
-- and g_base_ip = x"0A63" in:
-- https://git.astron.nl/desp/hdl/-/blob/master/boards/uniboard2b/libraries/unb2b_board/src/vhdl/ctrl_unb2b_board.vhd
-- Can use same offload time for all statistics, because 1GbE mux will combine them
--CONSTANT c_sdp_offload_time : NATURAL := 13000; -- from wave window 62855nS / 5nS = 12571 cycles.
CONSTANT c_sdp_offload_time : NATURAL := 600000; -- see L2SDP-452
-- packet lengths, see ICD SC-SDP
CONSTANT c_sdp_nof_bytes_per_statistic : NATURAL := 8; -- c_sdp_W_statistic_sz * c_word_sz = 2 * 4 = 8
CONSTANT c_sdp_stat_app_header_len : NATURAL := 32;
CONSTANT c_sdp_stat_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"001B217176B9"; -- 001B217176B9 = DOP36-enp2s0
CONSTANT c_sdp_stat_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 00:22:86:08:pp:qq
CONSTANT c_sdp_stat_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"0A6300FE"; -- 0A6300FE = '10.99.0.254' = DOP36-enp2s0
CONSTANT c_sdp_stat_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"0A63"; -- 10.99.xx.yy
CONSTANT c_sdp_stat_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5001, 16);
CONSTANT c_sdp_sst_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D0"; -- TBC, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0])
CONSTANT c_sdp_bst_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D1"; -- TBC
CONSTANT c_sdp_xst_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D2"; -- TBC
CONSTANT c_sdp_stat_version_id : NATURAL := 5;
CONSTANT c_sdp_stat_nof_hdr_fields : NATURAL := 1+3+12+4+20+1; -- 608b; 19 32b words
CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- 0=data path, 1=MM controlled
--CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "1"&"101"&"111011111001"&"0101"&"0100"&"000000000"&"0000100"&"0"; -- 0=data path, 1=MM controlled TODO (26 nov 2021)
--CONSTANT c_sdp_stat_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := "0"&"100"&"000000010001"&"0100"&"0100"&"000000010"&"1000000"&"0"; -- 0=data path, 1=MM controlled TODO
CONSTANT c_sdp_stat_hdr_field_arr : t_common_field_arr(c_sdp_stat_nof_hdr_fields-1 DOWNTO 0) := (
( field_name_pad("word_align" ), "RW", 16, field_default(0) ), -- Tx TSE IP will strip these 2 padding bytes
( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(c_sdp_stat_eth_dst_mac) ),
( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ),
( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ),
( field_name_pad("ip_version" ), "RW", 4, field_default(4) ),
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ),
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ),
( field_name_pad("ip_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ),
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ),
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ),
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ),
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ),
( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(c_sdp_stat_ip_dst_addr) ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(c_sdp_stat_udp_dst_port) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_marker" ), "RW", 8, field_default(0) ),
( field_name_pad("sdp_version_id" ), "RW", 8, field_default(c_sdp_stat_version_id) ),
( field_name_pad("sdp_observation_id" ), "RW", 32, field_default(0) ),
( field_name_pad("sdp_station_id" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_source_info_antenna_band_id" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_nyquist_zone_id" ), "RW", 2, field_default(0) ),
( field_name_pad("sdp_source_info_f_adc" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_fsub_type" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_payload_error" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_beam_repositioning_flag" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_subband_calibrated_flag" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_reserved" ), "RW", 3, field_default(0) ),
( field_name_pad("sdp_source_info_gn_id" ), "RW", 5, field_default(0) ),
( field_name_pad("sdp_reserved" ), "RW", 8, field_default(0) ),
( field_name_pad("sdp_integration_interval" ), "RW", 24, field_default(0) ),
( field_name_pad("sdp_data_id" ), "RW", 32, field_default(0) ),
( field_name_pad("sdp_nof_signal_inputs" ), "RW", 8, field_default(0) ),
( field_name_pad("sdp_nof_bytes_per_statistic" ), "RW", 8, field_default(c_sdp_nof_bytes_per_statistic) ),
( field_name_pad("sdp_nof_statistics_per_packet" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ),
( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) )
);
CONSTANT c_sdp_reg_stat_hdr_dat_addr_w : NATURAL := ceil_log2(field_nof_words(c_sdp_stat_hdr_field_arr, c_word_w));
TYPE t_sdp_network_stat_header IS RECORD
sdp_marker : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_version_id : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
sdp_station_id : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_source_info_antenna_band_id : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_nyquist_zone_id : STD_LOGIC_VECTOR( 1 DOWNTO 0);
sdp_source_info_f_adc : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_fsub_type : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_payload_error : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_beam_repositioning_flag : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_subband_calibrated_flag : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_reserved : STD_LOGIC_VECTOR( 2 DOWNTO 0);
sdp_source_info_gn_id : STD_LOGIC_VECTOR( 4 DOWNTO 0);
sdp_reserved : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_integration_interval : STD_LOGIC_VECTOR(23 DOWNTO 0);
sdp_data_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
sdp_data_id_sst_signal_input_index : STD_LOGIC_VECTOR( 7 DOWNTO 0); -- sdp_data_id sub field
sdp_data_id_bst_beamlet_index : STD_LOGIC_VECTOR(15 DOWNTO 0); -- sdp_data_id sub field
sdp_data_id_xst_subband_index : STD_LOGIC_VECTOR(24 DOWNTO 16); -- sdp_data_id sub field
sdp_data_id_xst_signal_input_A_index : STD_LOGIC_VECTOR(15 DOWNTO 8); -- sdp_data_id sub field
sdp_data_id_xst_signal_input_B_index : STD_LOGIC_VECTOR( 7 DOWNTO 0); -- sdp_data_id sub field
sdp_nof_signal_inputs : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_nof_bytes_per_statistic : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_nof_statistics_per_packet : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_block_period : STD_LOGIC_VECTOR(15 DOWNTO 0);
dp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0);
END RECORD;
TYPE t_sdp_stat_data_id IS RECORD
sst_signal_input_index : NATURAL RANGE 0 TO 2**8 - 1; -- < 192 = c_sdp_N_pn_max * c_sdp_S_pn
bst_beamlet_index : NATURAL RANGE 0 TO 2**16 - 1; -- < 976 = c_sdp_N_beamsets * c_sdp_S_sub_bf
xst_subband_index : NATURAL RANGE 0 TO 2**9 - 1; -- < 512 = c_sdp_N_sub
xst_signal_input_A_index : NATURAL RANGE 0 TO 2**8 - 1; -- < 192 = c_sdp_N_pn_max * c_sdp_S_pn
xst_signal_input_B_index : NATURAL RANGE 0 TO 2**8 - 1; -- < 192 = c_sdp_N_pn_max * c_sdp_S_pn
END RECORD;
TYPE t_sdp_stat_header IS RECORD
eth : t_network_eth_header;
ip : t_network_ip_header;
udp : t_network_udp_header;
app : t_sdp_network_stat_header;
END RECORD;
-----------------------------------------------------------------------------
-- Beamlet output via 10GbE to CEP (= central processor)
-----------------------------------------------------------------------------
CONSTANT c_sdp_marker_beamlets : NATURAL := 98; -- = x"62" = 'b'
CONSTANT c_sdp_cep_eth_dst_mac : STD_LOGIC_VECTOR(47 DOWNTO 0) := x"00074306C700"; -- 00074306C700 = DOP36-eth0
CONSTANT c_sdp_cep_eth_src_mac_47_16 : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00228608"; -- 47:16, 15:8 = backplane, 7:0 = node
CONSTANT c_sdp_cep_ip_dst_addr : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"C0A80001"; -- C0A80001 = '192.168.0.1' = DOP36-eth0
CONSTANT c_sdp_cep_ip_src_addr_31_16 : STD_LOGIC_VECTOR(15 DOWNTO 0) := x"C0A8"; -- 31:16, 15:8 = backplane, 7:0 = node + 1 = 192.168.xx.yy
CONSTANT c_sdp_cep_ip_total_length : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7868, 16); -- see ICD STAT-CEP
CONSTANT c_sdp_cep_udp_total_length : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(7848, 16); -- see ICD STAT-CEP
CONSTANT c_sdp_cep_udp_dst_port : STD_LOGIC_VECTOR(15 DOWNTO 0) := TO_UVEC(5000, 16);
CONSTANT c_sdp_cep_udp_src_port_15_8 : STD_LOGIC_VECTOR( 7 DOWNTO 0) := x"D0"; -- 15:8, 7:0 = gn_id (= ID[7:0] = backplane[5:0] & node[1:0])
CONSTANT c_sdp_cep_app_header_len : NATURAL := 32;
CONSTANT c_sdp_cep_version_id : NATURAL := 5;
CONSTANT c_sdp_cep_nof_blocks_per_packet : NATURAL := 4;
CONSTANT c_sdp_cep_nof_beamlets_per_block : NATURAL := c_sdp_S_sub_bf; -- number of dual pol beamlets (c_sdp_N_pol_bf = 2)
CONSTANT c_sdp_cep_nof_hdr_fields : NATURAL := 3+12+4+18+1; -- 592b; 9.25 64b words
CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "101"&"111111111001"&"0111"&"1100"&"00000010"&"000110"&"0"; -- 0=data path, 1=MM controlled TODO
--CONSTANT c_sdp_cep_hdr_field_sel : STD_LOGIC_VECTOR(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := "100"&"000000010001"&"0100"&"0100"&"00000000"&"101000"&"0"; -- 0=data path, 1=MM controlled TODO
CONSTANT c_sdp_cep_hdr_field_arr : t_common_field_arr(c_sdp_cep_nof_hdr_fields-1 DOWNTO 0) := (
( field_name_pad("eth_dst_mac" ), "RW", 48, field_default(c_sdp_cep_eth_dst_mac) ),
( field_name_pad("eth_src_mac" ), "RW", 48, field_default(0) ),
( field_name_pad("eth_type" ), "RW", 16, field_default(x"0800") ),
( field_name_pad("ip_version" ), "RW", 4, field_default(4) ),
( field_name_pad("ip_header_length" ), "RW", 4, field_default(5) ),
( field_name_pad("ip_services" ), "RW", 8, field_default(0) ),
( field_name_pad("ip_total_length" ), "RW", 16, field_default(c_sdp_cep_ip_total_length) ),
( field_name_pad("ip_identification" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_flags" ), "RW", 3, field_default(2) ),
( field_name_pad("ip_fragment_offset" ), "RW", 13, field_default(0) ),
( field_name_pad("ip_time_to_live" ), "RW", 8, field_default(127) ),
( field_name_pad("ip_protocol" ), "RW", 8, field_default(17) ),
( field_name_pad("ip_header_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("ip_src_addr" ), "RW", 32, field_default(0) ),
( field_name_pad("ip_dst_addr" ), "RW", 32, field_default(c_sdp_cep_ip_dst_addr) ),
( field_name_pad("udp_src_port" ), "RW", 16, field_default(0) ),
( field_name_pad("udp_dst_port" ), "RW", 16, field_default(c_sdp_cep_udp_dst_port) ),
( field_name_pad("udp_total_length" ), "RW", 16, field_default(c_sdp_cep_udp_total_length) ),
( field_name_pad("udp_checksum" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_marker" ), "RW", 8, field_default(c_sdp_marker_beamlets) ),
( field_name_pad("sdp_version_id" ), "RW", 8, field_default(c_sdp_cep_version_id) ),
( field_name_pad("sdp_observation_id" ), "RW", 32, field_default(0) ),
( field_name_pad("sdp_station_id" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_source_info_antenna_band_id" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_nyquist_zone_id" ), "RW", 2, field_default(0) ),
( field_name_pad("sdp_source_info_f_adc" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_fsub_type" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_payload_error" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_repositioning_flag" ), "RW", 1, field_default(0) ),
( field_name_pad("sdp_source_info_beamlet_width" ), "RW", 4, field_default(c_sdp_W_beamlet) ),
( field_name_pad("sdp_source_info_gn_id" ), "RW", 5, field_default(0) ),
( field_name_pad("sdp_reserved" ), "RW", 40, field_default(0) ),
( field_name_pad("sdp_beamlet_scale" ), "RW", 16, field_default(c_sdp_beamlet_scale_default) ),
( field_name_pad("sdp_beamlet_id" ), "RW", 16, field_default(0) ),
( field_name_pad("sdp_nof_blocks_per_packet" ), "RW", 8, field_default(c_sdp_cep_nof_blocks_per_packet) ),
( field_name_pad("sdp_nof_beamlets_per_block" ), "RW", 16, field_default(c_sdp_cep_nof_beamlets_per_block) ),
( field_name_pad("sdp_block_period" ), "RW", 16, field_default(c_sdp_block_period) ),
( field_name_pad("dp_bsn" ), "RW", 64, field_default(0) )
);
CONSTANT c_sdp_reg_cep_hdr_dat_addr_w : NATURAL := ceil_log2(field_nof_words(c_sdp_cep_hdr_field_arr, c_word_w));
TYPE t_sdp_network_cep_header IS RECORD
sdp_marker : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_version_id : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_observation_id : STD_LOGIC_VECTOR(31 DOWNTO 0);
sdp_station_id : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_source_info_antenna_band_id : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_nyquist_zone_id : STD_LOGIC_VECTOR( 1 DOWNTO 0);
sdp_source_info_f_adc : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_fsub_type : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_payload_error : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_repositioning_flag : STD_LOGIC_VECTOR( 0 DOWNTO 0);
sdp_source_info_beamlet_width : STD_LOGIC_VECTOR( 3 DOWNTO 0);
sdp_source_info_gn_id : STD_LOGIC_VECTOR( 4 DOWNTO 0);
sdp_reserved : STD_LOGIC_VECTOR(39 DOWNTO 0);
sdp_beamlet_scale : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_beamlet_id : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_nof_blocks_per_packet : STD_LOGIC_VECTOR( 7 DOWNTO 0);
sdp_nof_beamlets_per_block : STD_LOGIC_VECTOR(15 DOWNTO 0);
sdp_block_period : STD_LOGIC_VECTOR(15 DOWNTO 0);
dp_bsn : STD_LOGIC_VECTOR(63 DOWNTO 0);
END RECORD;
TYPE t_sdp_cep_header IS RECORD
eth : t_network_eth_header;
ip : t_network_ip_header;
udp : t_network_udp_header;
app : t_sdp_network_cep_header;
END RECORD;
-----------------------------------------------------------------------------
-- MM
-----------------------------------------------------------------------------
-- 10GbE MM address widths
CONSTANT c_sdp_reg_bf_hdr_dat_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + c_sdp_reg_cep_hdr_dat_addr_w;
CONSTANT c_sdp_reg_nw_10GbE_mac_addr_w : NATURAL := 13;
CONSTANT c_sdp_reg_nw_10GbE_eth10g_addr_w : NATURAL := 1;
-- JESD204
CONSTANT c_sdp_jesd204b_freq : STRING := "200MHz";
CONSTANT c_sdp_jesd204b_mm_jesd_ctrl_reg : t_c_mem := (latency => 1,
adr_w => 1,
dat_w => c_word_w,
nof_dat => 1,
init_sl => '0');
-- AIT MM address widths
CONSTANT c_sdp_jesd204b_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 8;
CONSTANT c_sdp_jesd_ctrl_addr_w : NATURAL := 1;
CONSTANT c_sdp_reg_bsn_monitor_input_addr_w : NATURAL := 8;
CONSTANT c_sdp_reg_wg_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 2;
CONSTANT c_sdp_ram_wg_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 10;
CONSTANT c_sdp_reg_dp_shiftram_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 1;
CONSTANT c_sdp_reg_bsn_source_v2_addr_w : NATURAL := 3;
CONSTANT c_sdp_reg_bsn_scheduler_addr_w : NATURAL := 1;
CONSTANT c_sdp_ram_diag_data_buf_bsn_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + ceil_log2(c_sdp_V_si_db_large); -- Dimension DB address range for largest DB, so that both the large and the default small DB fit.
CONSTANT c_sdp_reg_diag_data_buf_bsn_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 1;
CONSTANT c_sdp_ram_st_histogram_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + ceil_log2(c_sdp_V_si_histogram);
CONSTANT c_sdp_reg_aduh_monitor_addr_w : NATURAL := ceil_log2(c_sdp_S_pn) + 2;
-- FSUB MM address widths
CONSTANT c_sdp_ram_fil_coefs_addr_w : NATURAL := ceil_log2(c_sdp_N_fft * c_sdp_N_taps);
CONSTANT c_sdp_ram_st_sst_addr_w : NATURAL := ceil_log2(c_sdp_P_pfb * c_sdp_N_sub * c_sdp_Q_fft * c_sdp_W_statistic_sz);
CONSTANT c_sdp_reg_si_addr_w : NATURAL := 1; --enable/disable
CONSTANT c_sdp_ram_equalizer_gains_addr_w : NATURAL := ceil_log2(c_sdp_P_pfb*c_sdp_N_sub*c_sdp_Q_fft);
CONSTANT c_sdp_reg_dp_selector_addr_w : NATURAL := 1; --Select input 0 or 1.
-- STAT UDP offload MM address widths
CONSTANT c_sdp_reg_stat_enable_addr_w : NATURAL := 1;
-- BF MM address widths
CONSTANT c_sdp_reg_sdp_info_addr_w : NATURAL := 4;
CONSTANT c_sdp_ram_ss_ss_wide_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + ceil_log2(c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft);
CONSTANT c_sdp_ram_bf_weights_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + ceil_log2(c_sdp_N_pol_bf * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft);
CONSTANT c_sdp_reg_bf_scale_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + 1;
CONSTANT c_sdp_reg_dp_xonoff_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + 1;
CONSTANT c_sdp_ram_st_bst_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + ceil_log2(c_sdp_S_sub_bf * c_sdp_N_pol_bf * c_sdp_W_statistic_sz);
CONSTANT c_sdp_reg_stat_enable_bst_addr_w : NATURAL := ceil_log2(c_sdp_N_beamsets) + c_sdp_reg_stat_enable_addr_w;
CONSTANT c_sdp_reg_stat_hdr_dat_bst_addr_w: NATURAL := ceil_log2(c_sdp_N_beamsets) + c_sdp_reg_stat_hdr_dat_addr_w;
-- XSUB
CONSTANT c_sdp_crosslets_index_w : NATURAL := ceil_log2(c_sdp_N_sub);
CONSTANT c_sdp_mm_reg_crosslets_info : t_c_mem := (latency => 1,
adr_w => 4,
dat_w => c_sdp_crosslets_index_w,
nof_dat => 16, -- 15 offsets + 1 step
init_sl => '0');
CONSTANT c_sdp_crosslets_info_reg_w : NATURAL := c_sdp_mm_reg_crosslets_info.nof_dat*c_sdp_mm_reg_crosslets_info.dat_w;
CONSTANT c_sdp_crosslets_info_nof_offsets : NATURAL := c_sdp_mm_reg_crosslets_info.nof_dat - 1;
TYPE t_sdp_crosslets_info IS RECORD
offset_arr : t_natural_arr(0 TO c_sdp_crosslets_info_nof_offsets-1);
step : NATURAL;
END RECORD;
CONSTANT c_sdp_mm_reg_nof_crosslets : t_c_mem := (latency => 1,
adr_w => 1,
dat_w => ceil_log2(c_sdp_N_crosslets_max+1),
nof_dat => 1,
init_sl => '0'); -- Default = 1
CONSTANT c_sdp_nof_crosslets_reg_w : NATURAL := c_sdp_mm_reg_nof_crosslets.nof_dat*c_sdp_mm_reg_nof_crosslets.dat_w;
CONSTANT c_sdp_xst_nof_clk_per_sync_min : NATURAL := c_sdp_N_clk_per_sync / 10; -- 0.1 second
-- XSUB MM address widths
CONSTANT c_sdp_reg_crosslets_info_addr_w : NATURAL := c_sdp_mm_reg_crosslets_info.adr_w;
CONSTANT c_sdp_reg_nof_crosslets_addr_w : NATURAL := c_sdp_mm_reg_nof_crosslets.adr_w;
CONSTANT c_sdp_reg_bsn_sync_scheduler_xsub_addr_w : NATURAL := 4;
CONSTANT c_sdp_ram_st_xsq_addr_w : NATURAL := ceil_log2(c_sdp_N_crosslets_max * c_sdp_X_sq * c_nof_complex * c_sdp_W_statistic_sz);
CONSTANT c_sdp_ram_st_xsq_arr_addr_w : NATURAL := ceil_log2(c_sdp_P_sq) + c_sdp_ram_st_xsq_addr_w;
-- 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_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;
CONSTANT c_sdp_reg_dp_block_validate_err_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + 4;
CONSTANT c_sdp_reg_dp_block_validate_bsn_at_sync_addr_w : NATURAL := ceil_log2(c_sdp_N_ring_lanes_max) + 2;
CONSTANT c_sdp_reg_ring_info_addr_w : NATURAL := 2;
CONSTANT c_sdp_reg_tr_10GbE_mac_addr_w : NATURAL := 13;
CONSTANT c_sdp_reg_tr_10GbE_eth10g_addr_w : NATURAL := 1;
CONSTANT c_sdp_reg_diag_bg_addr_w : NATURAL := 3;
CONSTANT c_sdp_ram_diag_bg_addr_w : NATURAL := 7;
-------------------------------------------------
-- SDP simulation constants record, to use instead of HW default when g_sim = TRUE
-------------------------------------------------
TYPE t_sdp_sim IS RECORD
xst_nof_clk_per_sync_min : NATURAL;
offload_time : NATURAL; -- select > 0 and gn_index > 0 to see effect of offload_time on statistics offload
sync_timeout : NATURAL;
unb_nr : NATURAL;
node_nr : NATURAL;
END RECORD;
CONSTANT c_sdp_sim : t_sdp_sim := (1, 10, 3*1024, 0, 0);
-------------------------------------------------
-- SDP functions
-------------------------------------------------
FUNCTION func_sdp_gn_index_to_pn_index(gn_index : NATURAL) RETURN NATURAL;
FUNCTION func_sdp_modulo_N_sub(sub_index : NATURAL) RETURN NATURAL;
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_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;
FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL;
FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING) RETURN NATURAL; -- use c_sdp_S_pn, c_sdp_P_sq, c_sdp_N_crosslets_max
FUNCTION func_sdp_map_stat_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_sdp_stat_header;
FUNCTION func_sdp_map_cep_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_sdp_cep_header;
FUNCTION func_sdp_map_stat_data_id(g_statistics_type : STRING; data_id_slv : STD_LOGIC_VECTOR) RETURN t_sdp_stat_data_id;
FUNCTION func_sdp_map_stat_data_id(g_statistics_type : STRING; data_id_rec : t_sdp_stat_data_id) RETURN STD_LOGIC_VECTOR;
FUNCTION func_sdp_map_crosslets_info(info_slv : STD_LOGIC_VECTOR) RETURN t_sdp_crosslets_info; -- map all c_sdp_N_crosslets_max offsets
FUNCTION func_sdp_map_crosslets_info(info_rec : t_sdp_crosslets_info) RETURN STD_LOGIC_VECTOR; -- map all c_sdp_N_crosslets_max offsets
FUNCTION func_sdp_step_crosslets_info(info_rec : t_sdp_crosslets_info) RETURN t_sdp_crosslets_info; -- step all c_sdp_N_crosslets_max offsets
END PACKAGE sdp_pkg;
PACKAGE BODY sdp_pkg IS
FUNCTION func_sdp_gn_index_to_pn_index(gn_index : NATURAL) RETURN NATURAL IS
-- Determine PN index that starts at 0 per antenna band.
-- For LOFAR2 SDP there are two antenna bands: LB and HB. The LB starts at
-- GN index = 0 and has c_sdp_N_pn_lb = c_sdp_N_pn_max = 16 nodes. The HB
-- starts at c_sdp_N_pn_max. Assume every antenna_band starts at a GN:
--
-- pn_index = gn_index MOD c_sdp_N_pn_max
--
-- The fact that c_sdp_N_pn_max = 16 implies that instead of implementing
-- MOD it is possible to do:
--
-- pn_index = gn_index[3:0], because log2(16) = 4
CONSTANT c_w : NATURAL := ceil_log2(c_sdp_N_pn_max); -- = 4
VARIABLE v_index : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(gn_index, c_word_w);
BEGIN
RETURN TO_UINT(v_index(c_w-1 DOWNTO 0));
END func_sdp_gn_index_to_pn_index;
FUNCTION func_sdp_modulo_N_sub(sub_index : NATURAL) RETURN NATURAL IS
BEGIN
ASSERT sub_index < 2 * c_sdp_N_sub REPORT "func_sdp_modulo_N_sub: sub_index too large" SEVERITY FAILURE;
IF sub_index < c_sdp_N_sub-1 THEN
RETURN sub_index;
ELSE
RETURN sub_index - c_sdp_N_sub;
END IF;
END func_sdp_modulo_N_sub;
FUNCTION func_sdp_get_stat_marker(g_statistics_type : STRING) RETURN NATURAL IS
CONSTANT c_marker_sst : NATURAL := 83; -- = 0x53 = 'S'
CONSTANT c_marker_bst : NATURAL := 66; -- = 0x42 = 'B'
CONSTANT c_marker_xst : NATURAL := 88; -- = 0x58 = 'X'
BEGIN
RETURN sel_a_b(g_statistics_type="BST", c_marker_bst,
sel_a_b(g_statistics_type="XST", c_marker_xst,
c_marker_sst)); -- SST
END func_sdp_get_stat_marker;
FUNCTION func_sdp_get_stat_nof_signal_inputs(g_statistics_type : STRING) RETURN NATURAL IS
BEGIN
RETURN sel_a_b(g_statistics_type="BST", 0, -- not applicable for BST, so use 0,
sel_a_b(g_statistics_type="XST", c_sdp_S_pn,
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
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
CONSTANT c_data_size : NATURAL := func_sdp_get_stat_from_mm_data_size(g_statistics_type);
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_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
BEGIN
RETURN sel_a_b(g_statistics_type="BST", c_sdp_S_sub_bf, -- = 488
sel_a_b(g_statistics_type="XST", c_sdp_X_sq, -- = 144
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
sel_a_b(g_statistics_type="XST", c_sdp_X_sq * c_nof_complex, -- = 288
c_sdp_N_sub)); -- = 512, SST
END func_sdp_get_stat_nof_statistics_per_packet;
FUNCTION func_sdp_get_stat_app_total_length(g_statistics_type : STRING) RETURN NATURAL IS
CONSTANT c_nof_statistics_per_packet : NATURAL := func_sdp_get_stat_nof_statistics_per_packet(g_statistics_type);
BEGIN
-- RETURN:
-- . SST : 4128 (= 4096 + 32)
-- . BST : 7840 (= 7808 + 32)
-- . XST : 2336 (= 2304 + 32)
RETURN c_nof_statistics_per_packet * c_sdp_nof_bytes_per_statistic + c_sdp_stat_app_header_len;
END func_sdp_get_stat_app_total_length;
FUNCTION func_sdp_get_stat_udp_total_length(g_statistics_type : STRING) RETURN NATURAL IS
CONSTANT c_sdp_app_total_length : NATURAL := func_sdp_get_stat_app_total_length(g_statistics_type);
BEGIN
-- RETURN:
-- . SST : 4136 (= 4128 + 8)
-- . BST : 7848 (= 7840 + 8)
-- . XST : 2344 (= 2336 + 8)
RETURN c_sdp_app_total_length + c_network_udp_header_len;
END func_sdp_get_stat_udp_total_length;
FUNCTION func_sdp_get_stat_ip_total_length(g_statistics_type : STRING) RETURN NATURAL IS
CONSTANT c_sdp_udp_total_length : NATURAL := func_sdp_get_stat_udp_total_length(g_statistics_type);
BEGIN
-- RETURN:
-- . SST : 4156 (= 4136 + 20)
-- . BST : 7868 (= 7848 + 20)
-- . XST : 2364 (= 2344 + 20)
RETURN c_sdp_udp_total_length + c_network_ip_header_len;
END func_sdp_get_stat_ip_total_length;
FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING; S_pn, P_sq, N_crosslets : NATURAL) RETURN NATURAL IS
BEGIN
RETURN sel_a_b(g_statistics_type="BST", 1,
sel_a_b(g_statistics_type="XST", P_sq * N_crosslets,
S_pn)); -- SST
END func_sdp_get_stat_nof_packets;
FUNCTION func_sdp_get_stat_nof_packets(g_statistics_type : STRING) RETURN NATURAL IS
BEGIN
RETURN func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, c_sdp_P_sq, c_sdp_N_crosslets_max);
END func_sdp_get_stat_nof_packets;
FUNCTION func_sdp_map_stat_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_sdp_stat_header IS
VARIABLE v : t_sdp_stat_header;
BEGIN
-- eth header
v.eth.dst_mac := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "eth_dst_mac") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "eth_dst_mac"));
v.eth.src_mac := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "eth_src_mac") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "eth_src_mac"));
v.eth.eth_type := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "eth_type") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "eth_type"));
-- ip header
v.ip.version := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_version") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_version"));
v.ip.header_length := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_header_length") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_header_length"));
v.ip.services := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_services") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_services"));
v.ip.total_length := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_total_length") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_total_length"));
v.ip.identification := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_identification") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_identification"));
v.ip.flags := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_flags") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_flags"));
v.ip.fragment_offset := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_fragment_offset") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_fragment_offset"));
v.ip.time_to_live := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_time_to_live") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_time_to_live"));
v.ip.protocol := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_protocol") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_protocol"));
v.ip.header_checksum := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_header_checksum") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_header_checksum"));
v.ip.src_ip_addr := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_src_addr") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_src_addr"));
v.ip.dst_ip_addr := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "ip_dst_addr") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "ip_dst_addr"));
-- udp header
v.udp.src_port := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "udp_src_port") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "udp_src_port"));
v.udp.dst_port := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "udp_dst_port") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "udp_dst_port"));
v.udp.total_length := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "udp_total_length") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "udp_total_length"));
v.udp.checksum := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "udp_checksum") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "udp_checksum"));
-- app header
v.app.sdp_marker := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_marker") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_marker"));
v.app.sdp_version_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_version_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_version_id"));
v.app.sdp_observation_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_observation_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_observation_id"));
v.app.sdp_station_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_station_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_station_id"));
v.app.sdp_source_info_antenna_band_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_antenna_band_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_antenna_band_id"));
v.app.sdp_source_info_nyquist_zone_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_nyquist_zone_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_nyquist_zone_id"));
v.app.sdp_source_info_f_adc := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_f_adc") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_f_adc"));
v.app.sdp_source_info_fsub_type := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_fsub_type") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_fsub_type"));
v.app.sdp_source_info_payload_error := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_payload_error") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_payload_error"));
v.app.sdp_source_info_beam_repositioning_flag := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_beam_repositioning_flag") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_beam_repositioning_flag"));
v.app.sdp_source_info_subband_calibrated_flag := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_subband_calibrated_flag") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_subband_calibrated_flag"));
v.app.sdp_source_info_reserved := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_reserved") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_reserved"));
v.app.sdp_source_info_gn_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_gn_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_gn_id"));
v.app.sdp_reserved := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_reserved") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_reserved"));
v.app.sdp_integration_interval := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_integration_interval") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_integration_interval"));
v.app.sdp_data_id := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_data_id"));
v.app.sdp_data_id_sst_signal_input_index := v.app.sdp_data_id( 7 DOWNTO 0);
v.app.sdp_data_id_bst_beamlet_index := v.app.sdp_data_id(15 DOWNTO 0);
v.app.sdp_data_id_xst_subband_index := v.app.sdp_data_id(24 DOWNTO 16);
v.app.sdp_data_id_xst_signal_input_A_index := v.app.sdp_data_id(15 DOWNTO 8);
v.app.sdp_data_id_xst_signal_input_B_index := v.app.sdp_data_id( 7 DOWNTO 0);
v.app.sdp_nof_signal_inputs := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_signal_inputs") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_signal_inputs"));
v.app.sdp_nof_bytes_per_statistic := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_bytes_per_statistic") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_bytes_per_statistic"));
v.app.sdp_nof_statistics_per_packet := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_packet") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_nof_statistics_per_packet"));
v.app.sdp_block_period := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "sdp_block_period") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_block_period"));
v.app.dp_bsn := hdr_fields_raw(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn"));
RETURN v;
END func_sdp_map_stat_header;
FUNCTION func_sdp_map_cep_header(hdr_fields_raw : STD_LOGIC_VECTOR) RETURN t_sdp_cep_header IS
VARIABLE v : t_sdp_cep_header;
BEGIN
-- eth header
v.eth.dst_mac := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "eth_dst_mac") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "eth_dst_mac"));
v.eth.src_mac := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "eth_src_mac") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "eth_src_mac"));
v.eth.eth_type := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "eth_type") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "eth_type"));
-- ip header
v.ip.version := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_version") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_version"));
v.ip.header_length := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_header_length") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_header_length"));
v.ip.services := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_services") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_services"));
v.ip.total_length := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_total_length") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_total_length"));
v.ip.identification := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_identification") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_identification"));
v.ip.flags := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_flags") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_flags"));
v.ip.fragment_offset := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_fragment_offset") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_fragment_offset"));
v.ip.time_to_live := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_time_to_live") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_time_to_live"));
v.ip.protocol := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_protocol") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_protocol"));
v.ip.header_checksum := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_header_checksum") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_header_checksum"));
v.ip.src_ip_addr := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_src_addr") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_src_addr"));
v.ip.dst_ip_addr := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "ip_dst_addr") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "ip_dst_addr"));
-- udp header
v.udp.src_port := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "udp_src_port") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "udp_src_port"));
v.udp.dst_port := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "udp_dst_port") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "udp_dst_port"));
v.udp.total_length := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "udp_total_length") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "udp_total_length"));
v.udp.checksum := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "udp_checksum") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "udp_checksum"));
-- app header
v.app.sdp_marker := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_marker") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_marker"));
v.app.sdp_version_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_version_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_version_id"));
v.app.sdp_observation_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_observation_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_observation_id"));
v.app.sdp_station_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_station_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_station_id"));
v.app.sdp_source_info_antenna_band_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_antenna_band_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_antenna_band_id"));
v.app.sdp_source_info_nyquist_zone_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_nyquist_zone_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_nyquist_zone_id"));
v.app.sdp_source_info_f_adc := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_f_adc") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_f_adc"));
v.app.sdp_source_info_fsub_type := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_fsub_type") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_fsub_type"));
v.app.sdp_source_info_payload_error := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_payload_error") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_payload_error"));
v.app.sdp_source_info_repositioning_flag := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_repositioning_flag") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_repositioning_flag"));
v.app.sdp_source_info_beamlet_width := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_beamlet_width") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_beamlet_width"));
v.app.sdp_source_info_gn_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_source_info_gn_id"));
v.app.sdp_reserved := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_reserved") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_reserved"));
v.app.sdp_beamlet_scale := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_scale"));
v.app.sdp_beamlet_id := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_beamlet_id"));
v.app.sdp_nof_blocks_per_packet := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_blocks_per_packet"));
v.app.sdp_nof_beamlets_per_block := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_nof_beamlets_per_block"));
v.app.sdp_block_period := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "sdp_block_period") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "sdp_block_period"));
v.app.dp_bsn := hdr_fields_raw(field_hi(c_sdp_cep_hdr_field_arr, "dp_bsn") DOWNTO field_lo(c_sdp_cep_hdr_field_arr, "dp_bsn"));
RETURN v;
END func_sdp_map_cep_header;
FUNCTION func_sdp_map_stat_data_id(g_statistics_type : STRING; data_id_slv : STD_LOGIC_VECTOR) RETURN t_sdp_stat_data_id IS
VARIABLE v_rec : t_sdp_stat_data_id;
BEGIN
IF g_statistics_type = "SST" THEN
v_rec.sst_signal_input_index := TO_UINT(data_id_slv(7 DOWNTO 0));
ELSIF g_statistics_type = "BST" THEN
v_rec.bst_beamlet_index := TO_UINT(data_id_slv(15 DOWNTO 0));
ELSIF g_statistics_type = "XST" THEN
v_rec.xst_subband_index := TO_UINT(data_id_slv(24 DOWNTO 16));
v_rec.xst_signal_input_A_index := TO_UINT(data_id_slv(15 DOWNTO 8));
v_rec.xst_signal_input_B_index := TO_UINT(data_id_slv(7 DOWNTO 0));
END IF;
RETURN v_rec;
END func_sdp_map_stat_data_id;
FUNCTION func_sdp_map_stat_data_id(g_statistics_type : STRING; data_id_rec : t_sdp_stat_data_id) RETURN STD_LOGIC_VECTOR IS
VARIABLE v_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
BEGIN
IF g_statistics_type = "SST" THEN
v_slv(7 DOWNTO 0) := TO_UVEC(data_id_rec.sst_signal_input_index, 8);
ELSIF g_statistics_type = "BST" THEN
v_slv(15 DOWNTO 0) := TO_UVEC(data_id_rec.bst_beamlet_index, 16);
ELSIF g_statistics_type = "XST" THEN
v_slv(24 DOWNTO 16) := TO_UVEC(data_id_rec.xst_subband_index, 9);
v_slv(15 DOWNTO 8) := TO_UVEC(data_id_rec.xst_signal_input_A_index, 8);
v_slv(7 DOWNTO 0) := TO_UVEC(data_id_rec.xst_signal_input_B_index, 8);
END IF;
RETURN v_slv;
END func_sdp_map_stat_data_id;
FUNCTION func_sdp_map_crosslets_info(info_slv : STD_LOGIC_VECTOR) RETURN t_sdp_crosslets_info IS
VARIABLE v_info : t_sdp_crosslets_info;
BEGIN
FOR I IN 0 TO c_sdp_crosslets_info_nof_offsets-1 LOOP -- map al offsets
v_info.offset_arr(I) := TO_UINT(info_slv((I+1)*c_sdp_crosslets_index_w-1 DOWNTO I*c_sdp_crosslets_index_w));
END LOOP;
v_info.step := TO_UINT(info_slv(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w));
RETURN v_info;
END func_sdp_map_crosslets_info;
FUNCTION func_sdp_map_crosslets_info(info_rec : t_sdp_crosslets_info) RETURN STD_LOGIC_VECTOR IS
VARIABLE v_info : STD_LOGIC_VECTOR(c_sdp_crosslets_info_reg_w-1 DOWNTO 0);
BEGIN
FOR I IN 0 TO c_sdp_crosslets_info_nof_offsets-1 LOOP -- map all offsets
v_info((I+1)*c_sdp_crosslets_index_w-1 DOWNTO I*c_sdp_crosslets_index_w) := TO_UVEC(info_rec.offset_arr(I), c_sdp_crosslets_index_w);
END LOOP;
v_info(c_sdp_crosslets_info_reg_w-1 DOWNTO c_sdp_crosslets_info_reg_w - c_sdp_crosslets_index_w) := TO_UVEC(info_rec.step, c_sdp_crosslets_index_w);
RETURN v_info;
END func_sdp_map_crosslets_info;
FUNCTION func_sdp_step_crosslets_info(info_rec : t_sdp_crosslets_info) RETURN t_sdp_crosslets_info IS
VARIABLE v_info : t_sdp_crosslets_info := info_rec;
BEGIN
FOR I IN 0 TO c_sdp_crosslets_info_nof_offsets-1 LOOP -- step all offsets
v_info.offset_arr(I) := v_info.offset_arr(I) + v_info.step;
END LOOP;
RETURN v_info;
END func_sdp_step_crosslets_info;
END sdp_pkg;