diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd index 44f22b5dbe0e4c6e6190adda0914f29621adfb2d..ef1bd83f987c514f911651c6752052c0fb215fe6 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_fsub/tb_lofar2_unb2b_sdp_station_fsub.vhd @@ -78,7 +78,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2b_sdp_station_fsub IS CONSTANT c_tb_clk_period : TIME := 100 ps; -- use fast tb_clk to speed up M&C CONSTANT c_nof_block_per_sync : NATURAL := 16; - CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft; + CONSTANT c_nof_clk_per_sync : NATURAL := c_nof_block_per_sync*c_sdp_N_fft - (c_sdp_N_fft/2); --15.5 block per sync CONSTANT c_pps_period : NATURAL := c_nof_clk_per_sync; CONSTANT c_wpfb_sim : t_wpfb := func_wpfb_set_nof_block_per_sync(c_sdp_wpfb_subbands, c_nof_block_per_sync); diff --git a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd index c2b6942f2a7a57349ae260b8f17091191d80ac55..11e331a80e0267d8ef97720e36756d7f188a7426 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/node_sdp_adc_input_and_timing.vhd @@ -446,6 +446,7 @@ BEGIN u_dp_fifo_dc : ENTITY dp_lib.dp_fifo_dc GENERIC MAP ( g_data_w => c_sdp_W_adc_jesd, + g_bsn_w => c_bs_bsn_w, g_use_empty => FALSE, --TRUE, g_use_ctrl => TRUE, g_use_sync => TRUE, diff --git a/libraries/base/dp/hdllib.cfg b/libraries/base/dp/hdllib.cfg index 9bceeae7d50a99e04c724a62f37821888af5a23f..07fb20fc3763feb3845b327bf748ccf5e033f7d4 100644 --- a/libraries/base/dp/hdllib.cfg +++ b/libraries/base/dp/hdllib.cfg @@ -134,6 +134,7 @@ synth_files = src/vhdl/dp_offload_tx_len_calc.vhd src/vhdl/dp_sync_insert.vhd src/vhdl/dp_sync_insert_v2.vhd + src/vhdl/dp_sync_recover.vhd src/vhdl/dp_field_blk.vhd src/vhdl/dp_concat_field_blk.vhd diff --git a/libraries/base/dp/src/vhdl/dp_sync_recover.vhd b/libraries/base/dp/src/vhdl/dp_sync_recover.vhd new file mode 100644 index 0000000000000000000000000000000000000000..9b556fdb5bdedca21e00ed889a8cba701cd5eda5 --- /dev/null +++ b/libraries/base/dp/src/vhdl/dp_sync_recover.vhd @@ -0,0 +1,119 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2021 +-- 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 vd Walle +-- Purpose : * Insert extra sync pulses. +-- Description: +-- Every nof_blk_per_sync block a sync pulse is created at the output. The block +-- counter resets if a sync arrives at the input or when nof_blk_per_sync is reached. +-- nof_blk_per_sync is controllable using M&C. +-- +-- Remarks: +-- . There is no support for back pressure. +-- . It does not compensate for missing data or extra data. There is NO reset function. It assumes that the +-- incoming data is perfectly aligned. Use a dp_sync_checker to assure the incoming data is perfect. +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.NUMERIC_STD.ALL; +USE common_lib.common_pkg.ALL; +USE common_lib.common_mem_pkg.ALL; +USE work.dp_stream_pkg.ALL; + +ENTITY dp_sync_recover IS + GENERIC ( + g_initial_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0) := (OTHERS => '0'); + g_nof_data_per_block : POSITIVE := 1 + ); + PORT ( + + -- Clocks and reset + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + + in_sosi : IN t_dp_sosi := c_dp_sosi_rst; + val : IN STD_LOGIC; -- valid at the output + -- Streaming source + out_sosi : OUT t_dp_sosi + ); +END dp_sync_recover; + + +ARCHITECTURE rtl OF dp_sync_recover IS + + TYPE t_reg IS RECORD -- local registers + bsn_at_sync : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0); + data_cnt : NATURAL RANGE 0 TO g_nof_data_per_block; + out_bsn : STD_LOGIC_VECTOR(c_dp_stream_bsn_w -1 DOWNTO 0); + out_sosi : t_dp_sosi; + END RECORD; + + CONSTANT c_reg_rst : t_reg := ( (OTHERS => '0'), 0, g_initial_bsn, c_dp_sosi_rst); + + -- Define the local registers in t_reg record + SIGNAL r : t_reg; + SIGNAL nxt_r : t_reg; + +BEGIN + + out_sosi <= nxt_r.out_sosi; + + p_clk : PROCESS(dp_rst, dp_clk) + BEGIN + IF dp_rst='1' THEN + r <= c_reg_rst; + ELSIF rising_edge(dp_clk) THEN + r <= nxt_r; + END IF; + END PROCESS; + + p_comb : PROCESS(r, in_sosi, val) + VARIABLE v : t_reg; + BEGIN + v := r; + v.out_sosi := c_dp_sosi_rst; + v.out_sosi.valid := val; + v.out_sosi.bsn := r.out_sosi.bsn; + + IF in_sosi.sync = '1' THEN + v.bsn_at_sync := in_sosi.bsn; + END IF; + IF val = '1' THEN + v.data_cnt := r.data_cnt + 1; + IF r.data_cnt = 0 THEN + v.out_sosi.sop := '1'; + v.out_bsn := STD_LOGIC_VECTOR(UNSIGNED(r.out_bsn) + 1); + v.out_sosi.bsn := r.out_bsn; + IF r.out_bsn = r.bsn_at_sync THEN + v.out_sosi.sync := '1'; + END IF; + END IF; + IF r.data_cnt = g_nof_data_per_block-1 THEN + v.data_cnt := 0; + v.out_sosi.eop := '1'; + END IF; + END IF; + + nxt_r <= v; + END PROCESS; + +END rtl; diff --git a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd index 67d65dac3c7cb640832ca576997c8cf46634ec0f..071a6785a0266c3da24ea15d4c09cd7ffcf9f831 100644 --- a/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd +++ b/libraries/dsp/wpfb/src/vhdl/wpfb_unit_dev.vhd @@ -451,6 +451,7 @@ architecture str of wpfb_unit_dev is signal fft_out_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst); signal pfb_out_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0) := (others => c_dp_sosi_rst); + signal ctrl_pfb_out_sosi : t_dp_sosi := c_dp_sosi_rst; type reg_type is record in_sosi_arr : t_dp_sosi_arr(g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 downto 0); @@ -624,32 +625,29 @@ begin fft_out_sosi.bsn <= r.in_sosi_arr(0).bsn; fft_out_sosi.valid <= fft_out_val_arr(0); - wire_fft_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate - fft_out_sosi_arr(I).re <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I)); - fft_out_sosi_arr(I).im <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I)); - fft_out_sosi_arr(I).valid <= fft_out_val_arr(I); - end generate; - - u_dp_block_gen_valid_arr : ENTITY dp_lib.dp_block_gen_valid_arr - GENERIC MAP ( - g_nof_streams => g_wpfb.nof_wb_streams*g_wpfb.wb_factor, - g_nof_data_per_block => c_nof_valid_per_block, - g_nof_blk_per_sync => g_wpfb.nof_blk_per_sync, - g_check_input_sync => false, - g_nof_pages_bsn => 1, - g_restore_global_bsn => true + u_dp_sync_recover : ENTITY dp_lib.dp_sync_recover + GENERIC MAP( + g_nof_data_per_block => c_nof_valid_per_block ) PORT MAP ( - rst => dp_rst, - clk => dp_clk, - -- Streaming sink - snk_in => fft_out_sosi, - snk_in_arr => fft_out_sosi_arr, - -- Streaming source - src_out_arr => pfb_out_sosi_arr, - -- Control - enable => '1' + dp_rst => dp_rst, + dp_clk => dp_clk, + + in_sosi => fft_out_sosi, + val => fft_out_sosi.valid, + + out_sosi => ctrl_pfb_out_sosi ); + + wire_pfb_out_sosi_arr : for I in 0 to g_wpfb.nof_wb_streams*g_wpfb.wb_factor-1 generate + pfb_out_sosi_arr(I).re <= RESIZE_DP_DSP_DATA(fft_out_re_arr(I)); + pfb_out_sosi_arr(I).im <= RESIZE_DP_DSP_DATA(fft_out_im_arr(I)); + pfb_out_sosi_arr(I).valid <= ctrl_pfb_out_sosi.valid; + pfb_out_sosi_arr(I).sync <= ctrl_pfb_out_sosi.sync; + pfb_out_sosi_arr(I).bsn <= ctrl_pfb_out_sosi.bsn; + pfb_out_sosi_arr(I).sop <= ctrl_pfb_out_sosi.sop; + pfb_out_sosi_arr(I).eop <= ctrl_pfb_out_sosi.eop; + end generate; end generate; ----------------------------------------------------------------------------