diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_remote.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_remote.vhd index 77402cf395652f55be1c12aa166ef142fe16ba0a..d5094cfe9d89615cf87a0042d0daddc8efe3908b 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_remote.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_beamformer_remote.vhd @@ -62,18 +62,22 @@ END sdp_beamformer_remote; ARCHITECTURE str OF sdp_beamformer_remote IS - CONSTANT c_data_w : NATURAL := c_nof_complex * c_sdp_W_beamlet_sum; - CONSTANT c_block_size : NATURAL := c_sdp_S_sub_bf * c_sdp_N_pol_bf; - CONSTANT c_fifo_size : NATURAL := 2** ceil_log2((c_block_size * 9) / 16); -- 9/16 = 36/64, 1 block of 64 bit words rounded to the next power of 2 = 1024. - - SIGNAL dispatch_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); -- 1 for local, 1 for remote. - SIGNAL dp_fifo_sosi : t_dp_sosi := c_dp_sosi_rst; - SIGNAL dp_fifo_siso : t_dp_siso := c_dp_siso_rdy; - SIGNAL beamlets_data_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); - SIGNAL beamlets_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); - SIGNAL i_bf_sum_sosi : t_dp_sosi := c_dp_sosi_rst; - SIGNAL bf_sum_data_sosi : t_dp_sosi := c_dp_sosi_rst; + CONSTANT c_data_w : NATURAL := c_nof_complex * c_sdp_W_beamlet_sum; + CONSTANT c_block_size : NATURAL := c_sdp_S_sub_bf * c_sdp_N_pol_bf; + CONSTANT c_fifo_size : NATURAL := 2** ceil_log2((c_block_size * 9) / 16); -- 9/16 = 36/64, 1 block of 64 bit words rounded to the next power of 2 = 1024. + CONSTANT c_complex_adder_latency : NATURAL := ceil_log2(c_dual); + + SIGNAL dispatch_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); -- 1 for local, 1 for remote. + SIGNAL dp_fifo_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL dp_fifo_siso : t_dp_siso := c_dp_siso_rdy; + SIGNAL beamlets_data_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); + SIGNAL beamlets_sosi_arr : t_dp_sosi_arr(c_dual-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst); + SIGNAL pipelined_beamlets_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL i_bf_sum_sosi : t_dp_sosi := c_dp_sosi_rst; + SIGNAL bf_sum_data_sosi : t_dp_sosi := c_dp_sosi_rst; BEGIN + + -- repacking beamlets re/im to data field. p_wire_local_bf_sosi : PROCESS(local_bf_sosi) BEGIN @@ -174,6 +178,20 @@ BEGIN beamlets_sosi_arr(1).im(c_sdp_W_beamlet_sum-1 DOWNTO 0) <= beamlets_data_sosi_arr(1).data( c_data_w -1 DOWNTO c_sdp_W_beamlet_sum); END PROCESS; + --------------------------------------------------------------- + -- DP PIPELINE IN_SOSI FIELDS + --------------------------------------------------------------- + u_pipeline : ENTITY dp_lib.dp_pipeline + GENERIC MAP ( + g_pipeline => c_complex_adder_latency + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + snk_in => beamlets_sosi_arr(0), + src_out => pipelined_beamlets_sosi + ); + --------------------------------------------------------------- -- ADD --------------------------------------------------------------- @@ -190,17 +208,18 @@ BEGIN src_out => i_bf_sum_sosi ); - bf_sum_sosi <= i_bf_sum_sosi; - --------------------------------------------------------------- -- Repack 36b to 64b --------------------------------------------------------------- - -- repacking bf_sum re/im to data field. - p_wire_bf_sum_sosi : PROCESS(i_bf_sum_sosi) + -- repacking bf_sum re/im to data field and combine with pipelined_beamlets_sosi. + p_wire_bf_sum_sosi : PROCESS(pipelined_beamlets_sosi, i_bf_sum_sosi) BEGIN - bf_sum_data_sosi <= i_bf_sum_sosi; + bf_sum_data_sosi <= pipelined_beamlets_sosi; -- To preserve sosi control signals as dp_complex_add removes them. + bf_sum_sosi <= pipelined_beamlets_sosi; -- To preserve sosi control signals as dp_complex_add removes them. bf_sum_data_sosi.data(c_sdp_W_beamlet_sum -1 DOWNTO 0) <= i_bf_sum_sosi.re(c_sdp_W_beamlet_sum-1 DOWNTO 0); bf_sum_data_sosi.data( c_data_w -1 DOWNTO c_sdp_W_beamlet_sum) <= i_bf_sum_sosi.im(c_sdp_W_beamlet_sum-1 DOWNTO 0); + bf_sum_sosi.re(c_sdp_W_beamlet_sum-1 DOWNTO 0) <= i_bf_sum_sosi.re(c_sdp_W_beamlet_sum-1 DOWNTO 0); + bf_sum_sosi.im(c_sdp_W_beamlet_sum-1 DOWNTO 0) <= i_bf_sum_sosi.im(c_sdp_W_beamlet_sum-1 DOWNTO 0); END PROCESS; u_dp_repack_data_local : ENTITY dp_lib.dp_repack_data 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 afe6fb047c260a99537a89133bf8f1ed2af4056e..1e66291922993df2cb3bb30081db9d6e20e7fb1c 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_statistics_offload.vhd @@ -185,6 +185,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS packet_count : NATURAL RANGE 0 TO c_nof_packets_max; start_address : NATURAL RANGE 0 TO c_mm_ram_size; start_pulse : STD_LOGIC; + sync : STD_LOGIC; dp_header_info : STD_LOGIC_VECTOR(1023 DOWNTO 0); payload_err : STD_LOGIC; in_sop_cnt : NATURAL; @@ -199,7 +200,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS END RECORD; CONSTANT c_crosslets_info_rst : t_sdp_crosslets_info := (offset_arr => (OTHERS => 0), step => 0); - CONSTANT c_reg_rst : t_reg := (0, 0, '0', (OTHERS => '0'), '0', 0, 0, 0, 0, 0, 0, 0, 0, c_crosslets_info_rst); + CONSTANT c_reg_rst : t_reg := (0, 0, '0', '0', (OTHERS => '0'), '0', 0, 0, 0, 0, 0, 0, 0, 0, c_crosslets_info_rst); SIGNAL r : t_reg; SIGNAL nxt_r : t_reg; @@ -232,7 +233,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS SIGNAL udp_sosi : t_dp_sosi; - SIGNAL bsn_at_sync : STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0'); + 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'); -- Debug signals for view in Wave window @@ -249,7 +250,7 @@ ARCHITECTURE str OF sdp_statistics_offload IS BEGIN - bsn_at_sync <= RESIZE_UVEC(in_sosi.bsn, 64) WHEN rising_edge(dp_clk) AND in_sosi.sync = '1'; + 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: @@ -354,6 +355,7 @@ BEGIN BEGIN v := r; v.start_pulse := '0'; + v.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 @@ -383,6 +385,7 @@ BEGIN IF trigger_offload = '1' THEN -- Use trigger_offload to start first packet offload, all g_statistics_type start from start address 0 v.start_pulse := '1'; + v.sync := '1'; v.start_address := 0; v.packet_count := 0; v.interleave_count := 0; -- only used for SST @@ -472,7 +475,8 @@ BEGIN g_step_size => c_mm_step_size, g_nof_data => c_mm_nof_data, g_word_w => c_word_w, - g_reverse_word_order => g_reverse_word_order + g_reverse_word_order => g_reverse_word_order, + g_bsn_w => c_dp_stream_bsn_w ) PORT MAP( dp_rst => dp_rst, @@ -480,6 +484,8 @@ BEGIN mm_rst => mm_rst, mm_clk => mm_clk, start_pulse => r.start_pulse, + sync_in => r.sync, + bsn_at_sync => bsn_at_sync, start_address => r.start_address, done => mm_done, mm_mosi => master_mosi, @@ -546,7 +552,7 @@ BEGIN -- Streaming clock domain dp_rst => dp_rst, dp_clk => dp_clk, - ref_sync => in_sosi.sync, -- using in_sosi sync instead of udp_sosi as it has no sync. + ref_sync => in_sosi.sync, in_sosi_arr(0) => udp_sosi ); 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 462d489dce2291ffc9e2e82d5603d9bba517bbb4..6689c397db138213fee9d5ea32032469ece33ca8 100644 --- a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd @@ -54,6 +54,12 @@ -- to preserve the order of the user parts (e.g. real and imag, X and Y -- polarization) in a data block. -- +-- . sync_in is an optional sync pulse to generate a sync signal at out_sosi. +-- sync_in is not equal to start_pulse as start pulse indicates the start +-- of a packet and not the start of a sync period. +-- . For generating a bsn at out_sosi, the bsn_at_sync should contain the +-- desired bsn at sync_in pulse. The bsn is increased in this component at +-- every start_pulse. -- -------------------------------------------------------------------------- LIBRARY IEEE,common_lib; @@ -71,12 +77,15 @@ ENTITY dp_block_from_mm IS g_nof_data : NATURAL; 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 + g_reverse_word_order : BOOLEAN := FALSE; + g_bsn_w : NATURAL := 1 ); PORT ( rst : IN STD_LOGIC; clk : IN STD_LOGIC; start_pulse : IN STD_LOGIC; + sync_in : IN STD_LOGIC := '0'; -- Must be syncronous with start_pulse. + bsn_at_sync : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); start_address : IN NATURAL; mm_done : OUT STD_LOGIC; mm_mosi : OUT t_mem_mosi; @@ -92,16 +101,19 @@ ARCHITECTURE rtl OF dp_block_from_mm IS CONSTANT c_mem_size : NATURAL := g_step_size * g_nof_data; TYPE t_reg IS RECORD - 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 + busy : STD_LOGIC; + sync : STD_LOGIC; + sop : STD_LOGIC; + eop : STD_LOGIC; + sync_in_detected : STD_LOGIC; + bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); + 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', 0, 0, 0, 0); + CONSTANT c_reg_rst : t_reg := ('0', '0', '0', '0', '0', (OTHERS => '0'), 0, 0, 0, 0); SIGNAL r : t_reg; SIGNAL nxt_r : t_reg; @@ -112,8 +124,12 @@ ARCHITECTURE rtl OF dp_block_from_mm IS SIGNAL r_sop_p : STD_LOGIC; SIGNAL r_eop_p : STD_LOGIC; + SIGNAL r_sync_p : STD_LOGIC; + SIGNAL r_bsn_p : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); SIGNAL out_sop : STD_LOGIC; SIGNAL out_eop : STD_LOGIC; + SIGNAL out_sync : STD_LOGIC; + SIGNAL out_bsn : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0); BEGIN @@ -122,10 +138,14 @@ BEGIN 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); - out_sop <= r.sop WHEN g_mm_rd_latency = 1 ELSE r_sop_p; - out_eop <= r.eop WHEN g_mm_rd_latency = 1 ELSE r_eop_p; + r_sop_p <= r.sop WHEN rising_edge(clk); + r_eop_p <= r.eop WHEN rising_edge(clk); + r_sync_p <= r.sync WHEN rising_edge(clk); + r_bsn_p <= r.bsn WHEN rising_edge(clk); + out_sop <= r.sop WHEN g_mm_rd_latency = 1 ELSE r_sop_p; + out_eop <= r.eop WHEN g_mm_rd_latency = 1 ELSE r_eop_p; + out_sync <= r.sync WHEN g_mm_rd_latency = 1 ELSE r_sync_p; + out_bsn <= r.bsn WHEN g_mm_rd_latency = 1 ELSE r_bsn_p; u_sosi : PROCESS(r, mm_miso, out_sop, out_eop) BEGIN @@ -134,6 +154,8 @@ BEGIN 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 + out_sosi.sync <= out_sync; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.sync can be used for output sync + out_sosi.bsn <= RESIZE_DP_BSN(out_bsn); -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.bsn can be used for output bsn END PROCESS; mm_done <= r.eop; @@ -147,14 +169,15 @@ BEGIN END IF; END PROCESS; - p_comb : PROCESS(r, start_pulse, out_siso, mm_address, mm_address_rev, last_mm_address) + p_comb : PROCESS(r, start_pulse, sync_in, bsn_at_sync, 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'; + v.sop := '0'; + v.eop := '0'; + v.sync := '0'; -- 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; @@ -162,6 +185,10 @@ BEGIN IF r.busy = '0' AND start_pulse = '1' THEN -- initiate next output block v.busy := '1'; + IF sync_in = '1' THEN + v.sync_in_detected := '1'; + v.bsn := bsn_at_sync; + END IF; END IF; -- use v.busy, instead of r.busy, to allow start_pulse at mm_done, to @@ -189,6 +216,12 @@ BEGIN -- check start of output block IF r.data_index = 0 AND r.step_address = 0 THEN v.sop := '1'; + IF v.sync_in_detected = '1' THEN + v.sync := '1'; + v.sync_in_detected := '0'; + ELSE + v.bsn := INCR_UVEC(r.bsn, 1); + END IF; END IF; -- check end of output block 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 0ac01ec489d22cf6d3e2843e7df9e9e6243e2150..71706eaeff9b0980e4c9e37e4de58433271695ef 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 @@ -41,7 +41,8 @@ ENTITY dp_block_from_mm_dc IS g_step_size : NATURAL; g_nof_data : NATURAL; g_word_w : NATURAL := c_word_w; - g_reverse_word_order : BOOLEAN := FALSE + g_reverse_word_order : BOOLEAN := FALSE; + g_bsn_w : NATURAL := 1 ); PORT ( -- mm_clk domain @@ -53,6 +54,8 @@ ENTITY dp_block_from_mm_dc IS dp_rst : IN STD_LOGIC; dp_clk : IN STD_LOGIC; start_pulse : IN STD_LOGIC; + sync_in : IN STD_LOGIC := '0'; -- Must be syncronous with start_pulse. + bsn_at_sync : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); start_address : IN NATURAL; done : OUT STD_LOGIC; out_sosi : OUT t_dp_sosi; @@ -70,17 +73,22 @@ ARCHITECTURE str OF dp_block_from_mm_dc IS SIGNAL mm_fifo_sosi : t_dp_sosi := c_dp_sosi_rst; SIGNAL mm_fifo_siso : t_dp_siso; SIGNAL start_pulse_dly : STD_LOGIC_VECTOR(0 TO c_delay_len) := (OTHERS => '0'); + SIGNAL sync_dly : STD_LOGIC_VECTOR(0 TO c_delay_len) := (OTHERS => '0'); SIGNAL mm_start_pulse : STD_LOGIC := '0'; + SIGNAL mm_sync : STD_LOGIC := '0'; SIGNAL mm_done : STD_LOGIC := '0'; + SIGNAL mm_bsn_at_sync : STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL start_address_slv : STD_LOGIC_VECTOR(c_start_addr_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL mm_start_address_slv : STD_LOGIC_VECTOR(c_start_addr_w-1 DOWNTO 0) := (OTHERS => '0'); SIGNAL mm_start_address : NATURAL := 0; BEGIN - -- Use start_pulse_dly to make sure mm_start_address_slv is stable before + -- Use sync/start_pulse_dly to make sure mm_start_address_slv is stable before -- mm_start_pulse, also when mm_clk is faster than dp_clk (e.g. in sim). start_pulse_dly(0) <= start_pulse; start_pulse_dly(1 TO c_delay_len) <= start_pulse_dly(0 TO c_delay_len-1) WHEN rising_edge(dp_clk); + sync_dly(0) <= sync_in; + sync_dly(1 TO c_delay_len) <= sync_dly(0 TO c_delay_len-1) WHEN rising_edge(dp_clk); u_common_spulse_start_pulse : ENTITY common_lib.common_spulse PORT MAP ( @@ -92,6 +100,16 @@ BEGIN out_pulse => mm_start_pulse ); + u_common_spulse_sync : ENTITY common_lib.common_spulse + PORT MAP ( + in_rst => dp_rst, + in_clk => dp_clk, + in_pulse => sync_dly(c_delay_len), + out_rst => mm_rst, + out_clk => mm_clk, + out_pulse => mm_sync + ); + u_common_spulse_mm_done : ENTITY common_lib.common_spulse PORT MAP ( in_rst => mm_rst, @@ -110,16 +128,30 @@ BEGIN g_delay_len => c_meta_delay_len ) PORT MAP ( - rst => dp_rst, - clk => dp_clk, + rst => mm_rst, + clk => mm_clk, din => start_address_slv, dout => mm_start_address_slv ); + u_common_async_slv_bsn : ENTITY common_lib.common_async_slv + GENERIC MAP ( + g_delay_len => c_meta_delay_len + ) + PORT MAP ( + rst => mm_rst, + clk => mm_clk, + din => bsn_at_sync, + dout => mm_bsn_at_sync + ); + u_dp_fifo_fill_eop : ENTITY work.dp_fifo_fill_eop GENERIC MAP ( g_use_dual_clock => TRUE, g_data_w => c_word_w, + g_bsn_w => g_bsn_w, + g_use_bsn => TRUE, + g_use_sync => TRUE, g_fifo_fill => c_packet_size, g_fifo_size => c_fifo_size ) @@ -143,13 +175,16 @@ BEGIN 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 + g_reverse_word_order => g_reverse_word_order, + g_bsn_w => g_bsn_w ) PORT MAP ( clk => mm_clk, rst => mm_rst, start_pulse => mm_start_pulse, + sync_in => mm_sync, + bsn_at_sync => mm_bsn_at_sync, start_address => mm_start_address, mm_done => mm_done, mm_mosi => mm_mosi,