Skip to content
Snippets Groups Projects
Commit b3911848 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Use t_parameters and t_input to register the statistics info. Make sure that...

Use t_parameters and t_input to register the statistics info. Make sure that hdr_input contains the info for the previous sync interval in which the statistics were measured.
parent 394fbf85
No related branches found
No related tags found
1 merge request!273Use t_parameters and t_input to register the statistics info. Make sure that...
......@@ -84,13 +84,13 @@
-- BST (Xh, Xl), (Yh, Yl), 2 keep X, Y parts order
-- XST (Rh, Rl), (Ih, Il), 2 keep Re, Im parts order
--
-- . g_P_sq and nof_used_P_sq
-- . g_P_sq and p.nof_used_P_sq
-- The g_P_sq defines the number of correlator cells that is available in
-- the SDPFW. Use generic to support P_sq = 1 for one node and P_sq =
-- c_sdp_P_sq for multiple nodes (with ring).
-- The nof_used_P_sq is the number of correlator cells that is actually
-- The p.nof_used_P_sq is the number of correlator cells that is actually
-- used and that will output XST packets. Unused correlator cells yield
-- zero data that should not be output. The nof_used_P_sq is the smallest
-- zero data that should not be output. The p.nof_used_P_sq is the smallest
-- of g_P_sq and ring_info.N_rn/2 + 1. In this way the XST offload can work
-- with g_P_sq = 1 when N_rn > 1 and also in a ring with N_rn < N_pn when
-- g_P_sq = 9.
......@@ -158,8 +158,8 @@ ENTITY sdp_statistics_offload IS
sdp_info : IN t_sdp_info;
weighted_subbands_flag : IN STD_LOGIC := '0';
nof_crosslets : IN STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0');
crosslets_info_rec : IN t_sdp_crosslets_info := c_sdp_crosslets_info_rst
nof_crosslets : IN STD_LOGIC_VECTOR(c_sdp_nof_crosslets_reg_w-1 DOWNTO 0) := (OTHERS => '0'); -- from MM
prev_crosslets_info_rec : IN t_sdp_crosslets_info := c_sdp_crosslets_info_rst
);
END sdp_statistics_offload;
......@@ -185,43 +185,57 @@ ARCHITECTURE str OF sdp_statistics_offload IS
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;
-- offload control
-- Parameters that are fixed per node
TYPE t_parameters IS RECORD
gn_index : NATURAL; -- index of this global node
pn_index : NATURAL; -- index of this node in antenna band
rn_index : NATURAL; -- index of this ring node
local_si_offset : NATURAL; -- index of first signal input on this node
remote_rn : NATURAL; -- index of remote ring node
remote_gn : NATURAL; -- index of remote global node
remote_pn : NATURAL; -- index of remote node in antenna band
remote_si_offset : NATURAL; -- index of first signal input on remote node
nof_cycles_dly : NATURAL; -- trigger_offload delay for this node
offset_rn : NATURAL; -- = ring_info.O_rn, GN index of first ring node
nof_rn : NATURAL; -- = ring_info.N_rn, number of GN in the ring
nof_used_P_sq : NATURAL; -- number of used correlator cells <= g_P_sq (is number of available correlator cells)
END RECORD;
-- Input capture per sync interval
TYPE t_input IS RECORD
nof_crosslets : NATURAL RANGE 0 TO c_sdp_N_crosslets_max; -- nof_crosslets from MM
nof_packets : NATURAL; -- nof XST offload packets per integration interval dependend on nof_crosslets
bsn_at_sync : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0);
integration_interval : NATURAL;
crosslets_info_rec : t_sdp_crosslets_info;
sop_cnt : NATURAL;
payload_err : STD_LOGIC;
END RECORD;
-- Offload control
TYPE t_reg IS RECORD
packet_count : NATURAL RANGE 0 TO c_nof_packets_max;
start_address : NATURAL RANGE 0 TO c_mm_ram_size;
start_pulse : STD_LOGIC;
start_sync : STD_LOGIC;
dp_header_info : STD_LOGIC_VECTOR(1023 DOWNTO 0);
payload_err : STD_LOGIC;
in_sop_cnt : NATURAL;
integration_interval : NATURAL;
interleave_count : NATURAL RANGE 0 TO c_sdp_Q_fft;
interleave_address : NATURAL RANGE 0 TO c_mm_ram_size;
crosslet_count : NATURAL RANGE 0 TO c_sdp_N_crosslets_max;
instance_count : NATURAL RANGE 0 TO c_sdp_P_sq;
instance_address : NATURAL RANGE 0 TO c_mm_ram_size;
nof_crosslets : NATURAL RANGE 0 TO c_sdp_N_crosslets_max;
crosslets_info_rec : t_sdp_crosslets_info;
END RECORD;
CONSTANT c_reg_rst : t_reg := (0, 0, '0', '0', (OTHERS => '0'), '0', 0, 0, 0, 0, 0, 0, 0, 0, c_sdp_crosslets_info_rst);
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL gn_index_reg : NATURAL; -- index of this global node
SIGNAL pn_index : NATURAL; -- index of this node in antenna band
SIGNAL rn_index : NATURAL; -- index of this ring node
SIGNAL local_si_offset : NATURAL; -- index of first signal input on this node
SIGNAL remote_rn : NATURAL; -- index of remote ring node
SIGNAL remote_gn : NATURAL; -- index of remote global node
SIGNAL remote_pn : NATURAL; -- index of remote node in antenna band
SIGNAL remote_si_offset : NATURAL; -- index of first signal input on remote node
SIGNAL nof_cycles_dly : NATURAL; -- trigger_offload delay for this node
SIGNAL offset_rn : NATURAL; -- = ring_info.O_rn, GN index of first ring node
SIGNAL nof_rn : NATURAL; -- = ring_info.N_rn, number of GN in the ring
SIGNAL nof_used_P_sq : NATURAL; -- number of used correlator cells <= g_P_sq (is number of available correlator cells)
SIGNAL nof_packets : NATURAL; -- nof XST offload packets per integration interval
CONSTANT c_reg_rst : t_reg := (0, 0, '0', '0', (OTHERS => '0'), 0, 0, 0, 0, 0);
SIGNAL p : t_parameters;
SIGNAL reg_input : t_input;
SIGNAL prev_input : t_input;
SIGNAL hdr_input : t_input;
SIGNAL r : t_reg;
SIGNAL nxt_r : t_reg;
SIGNAL data_id_rec : t_sdp_stat_data_id;
SIGNAL data_id_slv : STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0');
......@@ -239,7 +253,6 @@ ARCHITECTURE str OF sdp_statistics_offload IS
SIGNAL udp_sosi : t_dp_sosi;
SIGNAL bsn_at_sync : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL dp_header_info : STD_LOGIC_VECTOR(1023 DOWNTO 0):= (OTHERS => '0');
SIGNAL r_dp_header_sop : STD_LOGIC;
SIGNAL r_dp_header_rec : t_sdp_stat_header;
......@@ -258,8 +271,6 @@ ARCHITECTURE str OF sdp_statistics_offload IS
BEGIN
bsn_at_sync <= RESIZE_UVEC(in_sosi.bsn, c_dp_stream_bsn_w) WHEN rising_edge(dp_clk) AND in_sosi.sync = '1';
-------------------------------------------------------------------------------
-- Assemble offload header info, for data path fields that are selected by:
-- c_sdp_stat_hdr_field_sel = "1"&"101"&"111011111001"&"0100"&"0100"&"000000010"&"1000000"&"0"
......@@ -300,17 +311,17 @@ BEGIN
dp_header_info(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" )) <= sdp_info.nyquist_zone_index;
dp_header_info(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" )) <= SLV(sdp_info.f_adc);
dp_header_info(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" )) <= SLV(sdp_info.fsub_type);
dp_header_info(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" )) <= SLV(r.payload_err);
dp_header_info(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" )) <= SLV(hdr_input.payload_err);
dp_header_info(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" )) <= SLV(sdp_info.beam_repositioning_flag);
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_source_info_weighted_subbands_flag" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_source_info_weighted_subbands_flag" )) <= SLV(weighted_subbands_flag);
dp_header_info(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" )) <= TO_UVEC(gn_index, 5);
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_integration_interval" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_integration_interval" )) <= TO_UVEC(r.integration_interval, 24);
dp_header_info(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" )) <= TO_UVEC(p.gn_index, 5);
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_integration_interval" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_integration_interval" )) <= TO_UVEC(hdr_input.integration_interval, 24);
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_data_id" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_data_id" )) <= data_id_slv;
dp_header_info(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" )) <= TO_UVEC(c_nof_signal_inputs, 8);
dp_header_info(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" )) <= TO_UVEC(c_sdp_nof_bytes_per_statistic, 8);
dp_header_info(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" )) <= TO_UVEC(c_nof_statistics_per_packet, 16);
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "sdp_block_period" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "sdp_block_period" )) <= sdp_info.block_period;
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn" )) <= bsn_at_sync;
dp_header_info(field_hi(c_sdp_stat_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_sdp_stat_hdr_field_arr, "dp_bsn" )) <= hdr_input.bsn_at_sync;
p_reg : PROCESS(dp_rst, dp_clk)
BEGIN
......@@ -321,81 +332,101 @@ BEGIN
END IF;
END PROCESS;
-- Derive and pipeline dynamic parameters
p_parameters : PROCESS(dp_clk)
-- Derive and pipeline dynamic parameters that depend on node id and MM, but are otherwise fixed
p_reg_parameters : PROCESS(dp_clk)
BEGIN
IF rising_edge(dp_clk) THEN
gn_index_reg <= gn_index;
pn_index <= func_sdp_gn_index_to_pn_index(gn_index_reg);
offset_rn <= TO_UINT(ring_info.O_rn);
rn_index <= gn_index_reg - offset_rn;
local_si_offset <= pn_index * c_sdp_S_pn;
nof_cycles_dly <= gn_index_reg * g_offload_time;
nof_rn <= TO_UINT(ring_info.N_rn);
nof_used_P_sq <= smallest(nof_rn / 2 + 1, g_P_sq);
nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, nof_used_P_sq, r.nof_crosslets);
remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, rn_index, nof_rn, g_crosslets_direction);
remote_gn <= offset_rn + remote_rn;
remote_pn <= func_sdp_gn_index_to_pn_index(remote_gn);
remote_si_offset <= remote_pn * c_sdp_S_pn;
p.gn_index <= gn_index;
p.pn_index <= func_sdp_gn_index_to_pn_index(p.gn_index);
p.offset_rn <= TO_UINT(ring_info.O_rn);
p.rn_index <= p.gn_index - p.offset_rn;
p.local_si_offset <= p.pn_index * c_sdp_S_pn;
p.nof_cycles_dly <= p.gn_index * g_offload_time;
p.nof_rn <= TO_UINT(ring_info.N_rn);
p.nof_used_P_sq <= smallest(p.nof_rn / 2 + 1, g_P_sq);
p.remote_rn <= func_ring_nof_hops_to_source_rn(r.instance_count, p.rn_index, p.nof_rn, g_crosslets_direction);
p.remote_gn <= p.offset_rn + p.remote_rn;
p.remote_pn <= func_sdp_gn_index_to_pn_index(p.remote_gn);
p.remote_si_offset <= p.remote_pn * c_sdp_S_pn;
END IF;
END PROCESS;
-- Determine info from previous sync interval in which the statistics were
-- measured.
-- . hold nof_crosslets from MM (and related nof_packets) per sync interval
-- . capture bsn_at_sync at start of a sync interval
-- . count number of sop that occur in a sync interval, to determine the
-- actual number of sop for the previous integration_interval
-- . track whether payload errors occur in a sync interval, to determine
-- the payload_err flag for the previous integration_interval
p_input_capture : PROCESS(dp_clk)
BEGIN
IF rising_edge(dp_clk) THEN
-- Capture input
IF in_sosi.sync = '1' THEN
reg_input.nof_crosslets <= TO_UINT(nof_crosslets);
reg_input.bsn_at_sync <= in_sosi.bsn;
reg_input.integration_interval <= reg_input.sop_cnt + 1; -- size = index + 1
reg_input.crosslets_info_rec <= prev_crosslets_info_rec;
reg_input.sop_cnt <= 0;
reg_input.payload_err <= '0';
ELSIF in_sosi.sop = '1' THEN
reg_input.sop_cnt <= reg_input.sop_cnt + 1;
ELSIF in_sosi.eop = '1' THEN
reg_input.payload_err <= reg_input.payload_err OR in_sosi.err(0);
END IF;
reg_input.nof_packets <= func_sdp_get_stat_nof_packets(g_statistics_type, c_sdp_S_pn, p.nof_used_P_sq, reg_input.nof_crosslets);
-- Determine previous sync interval info
-- . just register when the value suits any sync interval
prev_input.nof_crosslets <= reg_input.nof_crosslets;
prev_input.nof_packets <= reg_input.nof_packets;
-- . register at sync to get value for previous sync interval
IF in_sosi.sync = '1' THEN
prev_input.bsn_at_sync <= reg_input.bsn_at_sync;
END IF;
-- . just register when the value already is for the previous sync interval
prev_input.integration_interval <= reg_input.integration_interval;
prev_input.crosslets_info_rec <= reg_input.crosslets_info_rec;
prev_input.sop_cnt <= reg_input.sop_cnt;
prev_input.payload_err <= reg_input.payload_err;
-- Hold previous sync interval info at trigger_offload, so that
-- hdr_input can be used in p_control_packet_offload and
-- dp_header_info.
IF trigger_offload = '1' THEN
hdr_input <= prev_input;
END IF;
END IF;
END PROCESS;
-- Assign application header data_id for different statistic types, use
-- GENERATE to keep unused fields at 0 (all fields are NATURAL, so default to 0).
gen_data_id_sst : IF g_statistics_type = "SST" GENERATE
data_id_rec.sst_signal_input_index <= r.packet_count + local_si_offset;
data_id_rec.sst_signal_input_index <= r.packet_count + p.local_si_offset;
END GENERATE;
gen_data_id_bst : IF g_statistics_type = "BST" GENERATE
data_id_rec.bst_beamlet_index <= c_beamlet_id;
END GENERATE;
gen_data_id_xst : IF g_statistics_type = "XST" GENERATE
data_id_rec.xst_subband_index <= func_sdp_modulo_N_sub(r.crosslets_info_rec.offset_arr(r.crosslet_count));
data_id_rec.xst_signal_input_A_index <= local_si_offset;
data_id_rec.xst_signal_input_B_index <= remote_si_offset;
data_id_rec.xst_subband_index <= func_sdp_modulo_N_sub(hdr_input.crosslets_info_rec.offset_arr(r.crosslet_count));
data_id_rec.xst_signal_input_A_index <= p.local_si_offset;
data_id_rec.xst_signal_input_B_index <= p.remote_si_offset;
END GENERATE;
data_id_slv <= func_sdp_map_stat_data_id(g_statistics_type, data_id_rec);
p_control_packet_offload : PROCESS(r, in_sosi, nof_crosslets, crosslets_info_rec, trigger_offload, dp_sop, dp_header_info, nof_packets) -- in order of appearance
-- sensitivity list in order of appearance
p_control_packet_offload : PROCESS(r, trigger_offload, dp_sop, dp_header_info, reg_input)
VARIABLE v : t_reg;
VARIABLE v_index : NATURAL;
BEGIN
v := r;
v.start_pulse := '0';
v.start_sync := '0';
-- Count number of sop in a sync interval and get payload errors and keep them till next sync.
IF in_sosi.sync = '1' THEN
v.integration_interval := r.in_sop_cnt + 1; -- count = index + 1
v.in_sop_cnt := 0;
v.payload_err := '0';
ELSE
IF in_sosi.eop = '1' THEN
v.payload_err := r.payload_err OR in_sosi.err(0);
END IF;
IF in_sosi.sop = '1' THEN
v.in_sop_cnt := r.in_sop_cnt + 1;
END IF;
END IF;
-- For XST offload capture nof_crosslets and crosslets_info_rec at in_sosi.sync,
-- to make sure they do not change during packets offload.
-- . The sdp_crosslets_subband_select.vhd in [2] takes care that
-- nof_crosslets and crosslets_info_rec are valid at the xsel_sosi.sync. The
-- mmp_dp_bsn_align_v2 in [2] then aligns the local xsel_sosi with the
-- remote data and passes on the sync. After some latency the sync
-- arrives at the sdp_statistics_offload. This latency is very short
-- compared to the sync period, so the nof_crosslets and crosslets_info_rec
-- are still valid at the in_sosi.sync.
IF in_sosi.sync = '1' THEN
v.nof_crosslets := TO_UINT(nof_crosslets);
v.crosslets_info_rec := crosslets_info_rec;
END IF;
-- The trigger_offload occurs nof_cycles_dly after the in_sosi.sync and the
-- offload will have finished before the next in_sosi.sync, because
-- The trigger_offload occurs p.nof_cycles_dly after the in_sosi.sync and
-- the offload will have finished before the next in_sosi.sync, because
-- c_sdp_offload_time is such that all offload will finish within 100 ms
-- and the integration interval (= sync interval) is 1 s for SST and BST
-- and minimal 0.1s (= c_sdp_xst_nof_clk_per_sync_min) for XST.
......@@ -428,7 +459,7 @@ BEGIN
v.dp_header_info := dp_header_info;
-- Start next packets offload.
IF r.packet_count < nof_packets - 1 THEN
IF r.packet_count < reg_input.nof_packets - 1 THEN
IF g_statistics_type = "SST" THEN
-- step step step step step step
-- start_address : 0, 2, 2048, 2050, 4096, 4098, 6144, 6146, 8192, 8194, 10240, 10242
......@@ -448,7 +479,8 @@ BEGIN
ELSIF g_statistics_type = "XST" THEN
-- start_address:
-- nof_crosslets: 1, 2, 3, 4, 5, 6, 7
-- reg_input.nof_crosslets:
-- 1, 2, 3, 4, 5, 6, 7
-- X_sq instance:
-- 0 0, 576, 1152, 1728, 2304, 2880, 3456
-- 1 4096, 4672, 5248, 5824, 6400, 6976, 7552
......@@ -461,7 +493,7 @@ BEGIN
-- 8 32768, 33344, 33920, 34496, 35072, 35648, 36224
v.start_address := r.start_address + c_sdp_X_sq * c_nof_complex * c_sdp_W_statistic_sz; -- continue with next packet in this instance
v.crosslet_count := r.crosslet_count + 1;
IF r.crosslet_count = TO_UINT(nof_crosslets) - 1 THEN
IF r.crosslet_count = reg_input.nof_crosslets - 1 THEN
v.start_address := r.instance_address + 2**c_sdp_ram_st_xsq_addr_w; -- jump to first packet in next instance
v.crosslet_count := 0;
v.instance_count := r.instance_count + 1;
......@@ -498,7 +530,7 @@ BEGIN
reg_enable_mosi => reg_enable_mosi,
reg_enable_miso => reg_enable_miso,
delay => nof_cycles_dly,
delay => p.nof_cycles_dly,
trigger => in_trigger,
trigger_en => trigger_en,
trigger_dly => trigger_offload
......@@ -522,7 +554,7 @@ BEGIN
mm_clk => mm_clk,
start_pulse => r.start_pulse,
sync_in => r.start_sync,
bsn_at_sync => bsn_at_sync,
bsn_at_sync => hdr_input.bsn_at_sync,
start_address => r.start_address,
mm_mosi => master_mosi,
mm_miso => master_miso,
......@@ -551,7 +583,7 @@ BEGIN
src_out => dp_offload_snk_in
);
-- The bsn_at_sync is passed on via r.dp_header_info so that
-- The hdr_input.bsn_at_sync is passed on via r.dp_header_info so that
-- u_dp_offload_tx_v3 can put it in the udp_sosi header.
-- The dp_offload_snk_in.bsn that is passed on by u_dp_block_from_mm_dc is
-- in fact not used, but useful to see in udp_sosi.bsn in the Wave Window.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment