diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/disturb2_unb2b_sdp_station_full_wg/tb_disturb2_unb2b_sdp_station_full_wg.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/disturb2_unb2b_sdp_station_full_wg/tb_disturb2_unb2b_sdp_station_full_wg.vhd index 4a1080e7605e740d0ba02b7b772795396a5a6d44..b84d16cc0e02f705d589aa3df1b6be450f3ff466 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/disturb2_unb2b_sdp_station_full_wg/tb_disturb2_unb2b_sdp_station_full_wg.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/disturb2_unb2b_sdp_station_full_wg/tb_disturb2_unb2b_sdp_station_full_wg.vhd @@ -111,7 +111,7 @@ architecture tb of tb_disturb2_unb2b_sdp_station_full_wg is constant c_wg_ampl_sp_2 : natural := c_wg_ampl_sp_0 / 3; -- use different ampl for sp_0 and sp_2 to distinghuis them -- . phase constant c_subband_phase : real := 0.0; -- wanted subband phase in degrees = WG phase at sop - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_subband_sp_0 : real := 102.0; -- use WG at sp-0 for subband at index 102 = 102/1024 * 200MHz = 19.921875 MHz constant c_subband_sp_2 : real := 99.5; -- use WG at sp-2 for subband at index 99.5 = 99.5/1024 * 200MHz = 19.43359375 MHz constant c_subband_freq_sp_0 : real := real(c_subband_sp_0) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate diff --git a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd index fc88e90a4a3bb1d561ce39a0571146b0799a99ec..3eb4663984c590f6d5ad8c05d233f30490d33afe 100644 --- a/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_sdp_station/revisions/lofar2_unb2b_sdp_station_bf/tb_lofar2_unb2b_sdp_station_bf.vhd @@ -164,7 +164,7 @@ architecture tb of tb_lofar2_unb2b_sdp_station_bf is -- . phase constant c_subband_phase : real := 0.0; -- wanted subband phase in degrees = WG phase at sop constant c_subband_freq : real := real(g_subband) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_wg_phase_offset : real := 360.0 * real(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles constant c_wg_phase : real := c_subband_phase + c_wg_phase_offset; -- WG phase in degrees 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 ae4d83d08ea97fa788ff42172351ba2766e67b31..01b7d1a62acb959ef016362c6999b5ba55c82bbf 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 @@ -119,7 +119,7 @@ architecture tb of tb_lofar2_unb2b_sdp_station_fsub is -- . phase constant c_subband_phase : real := 0.0; -- wanted subband phase in degrees = WG phase at sop constant c_subband_freq : real := real(g_subband) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz is dp_clk - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_wg_phase_offset : real := 360.0 * real(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles constant c_wg_phase : real := c_subband_phase + c_wg_phase_offset; -- WG phase in degrees diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd index e1121127b6c8ce995c9ee29cae088f497193767d..5961e34066a72b5aaacee15a2182a6667c3dc45a 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf/tb_lofar2_unb2c_sdp_station_bf.vhd @@ -277,7 +277,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf is constant c_exp_sp_ast : real := c_exp_sp_power * real(c_nof_clk_per_sync); -- . phase constant c_subband_freq : real := real(g_subband) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_wg_phase_offset : real := 360.0 * real(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles constant c_wg_phase : real := g_sp_phase + c_wg_phase_offset; -- WG phase in degrees constant c_wg_remnant_phase : real := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd index 18702afb27646b839fa7bcb523075e7799bd1366..3abd033083ff66f9773461d0c105567d78d07c0f 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_bf_ring/tb_lofar2_unb2c_sdp_station_bf_ring.vhd @@ -277,7 +277,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_bf_ring is constant c_exp_sp_ast : real := c_exp_sp_power * real(c_nof_clk_per_sync); -- . phase constant c_subband_freq : real := real(g_subband) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz = dp_clk rate - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_wg_phase_offset : real := 360.0 * real(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles constant c_wg_phase : real := g_sp_phase + c_wg_phase_offset; -- WG phase in degrees constant c_wg_remnant_phase : real := g_sp_remnant_phase + c_wg_phase_offset; -- WG phase in degrees diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd index 7d739b0f82e19e68cee96ffde59911ff0b4aa33e..cf06a7e71344fe6a522391112bb98930c494dae9 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_fsub/tb_lofar2_unb2c_sdp_station_fsub.vhd @@ -135,7 +135,7 @@ architecture tb of tb_lofar2_unb2c_sdp_station_fsub is constant c_subband_freq : real := real(g_subband) / real(c_sdp_N_fft); -- normalized by fs = f_adc = 200 MHz is dp_clk -- . phase constant c_subband_phase : real := 0.0; -- wanted subband phase in degrees = WG phase at sop - constant c_wg_latency : integer := c_diag_wg_latency - 0; -- -0 to account for BSN scheduler start trigger latency + constant c_wg_latency : integer := c_diag_wg_latency + c_sdp_shiftram_latency - 0; -- -0 to account for BSN scheduler start trigger latency constant c_wg_phase_offset : real := 360.0 * real(c_wg_latency) * c_subband_freq; -- c_diag_wg_latency is in dp_clk cycles constant c_wg_phase : real := c_subband_phase + c_wg_phase_offset; -- WG phase in degrees constant c_co_wg_phase : real := c_wg_phase; 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 ba5ace7994c52065b2c62316717a2e6230e93370..edb98df15980958c38a4fc3d011ce1bee1d98a67 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 @@ -286,7 +286,6 @@ begin gen_rx_ait : if g_no_jesd = false and g_use_tech_jesd204b_v2 = false generate u_rx_ait : entity work.sdp_adc_input_and_timing generic map ( - g_no_rx => g_no_jesd, -- when false use Rx and WG, else only use WG g_no_st_histogram => g_no_st_histogram, g_buf_nof_data => g_buf_nof_data, g_bsn_nof_clk_per_sync => g_bsn_nof_clk_per_sync, -- Default 200M, overide for short simulation @@ -401,11 +400,10 @@ begin ); end generate; -- gen_rx_ait - -- Wire dp_clk to AIT when jesd is not used or when jesd IP tech_jesd204b_v2 is used - gen_dp_ait : if g_no_jesd = true or (g_no_jesd = false and g_use_tech_jesd204b_v2 = true) generate + -- Wire dp_clk to AIT when jesd IP tech_jesd204b_v2 is used, or when only the WG is used (so no jesd) + gen_dp_ait : if (g_no_jesd = false and g_use_tech_jesd204b_v2 = true) or g_no_jesd = true generate u_dp_ait : entity work.sdp_adc_input_and_timing generic map ( - g_no_rx => g_no_jesd, -- when false use Rx and WG, else only use WG g_no_st_histogram => g_no_st_histogram, g_buf_nof_data => g_buf_nof_data, g_bsn_nof_clk_per_sync => g_bsn_nof_clk_per_sync, -- Default 200M, overide for short simulation diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_adc_input_and_timing.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_adc_input_and_timing.vhd index a821ed5603536208ae8e9b3bb253d0af90390e9b..8a53a0d6a035b87573d2570ea14250748e2af77a 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_adc_input_and_timing.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_adc_input_and_timing.vhd @@ -36,7 +36,6 @@ use work.sdp_pkg.all; entity sdp_adc_input_and_timing is generic ( - g_no_rx : boolean := false; -- when false use Rx and WG, else use only WG g_no_st_histogram : boolean := true; -- when false use input histogram, else not to save block RAM g_buf_nof_data : natural := c_sdp_V_si_db; g_bsn_nof_clk_per_sync : natural := c_sdp_N_clk_per_sync; -- Default 200M, overide for short simulation @@ -115,60 +114,17 @@ architecture str of sdp_adc_input_and_timing is constant c_bs_block_size : natural := c_sdp_N_fft; -- =1024; constant c_dp_fifo_dc_size : natural := 64; - -- Sosis and sosi arrays - signal dp_shiftram_snk_in_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); - signal ant_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); + -- Timestamp and streaming data arrays signal bs_sosi : t_dp_sosi := c_dp_sosi_rst; signal wg_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); + signal ant_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); signal mux_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); signal nxt_mux_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); + signal inp_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); signal st_sosi_arr : t_dp_sosi_arr(c_sdp_S_pn - 1 downto 0) := (others => c_dp_sosi_rst); begin out_sosi_arr <= st_sosi_arr; - gen_rx : if g_no_rx = false generate - ----------------------------------------------------------------------------- - -- Time delay: dp_shiftram - -- . copied from unb1_bn_capture_input (apertif) - -- Array range reversal is not done because everything is DOWNTO - -- . the input valid is always '1', even when there is no data - ----------------------------------------------------------------------------- - p_dp_shiftram_snk_in_arr : process(rx_sosi_arr) - begin - dp_shiftram_snk_in_arr <= rx_sosi_arr; - for I in 0 to c_sdp_S_pn - 1 loop - -- ADC data is stored in the upper 14 bits of the jesd rx_sosi. - dp_shiftram_snk_in_arr(I).data <= RESIZE_DP_SDATA(rx_sosi_arr(I).data(c_sdp_W_adc_jesd - 1 downto (c_sdp_W_adc_jesd - c_sdp_W_adc) )); - -- Force valid. - dp_shiftram_snk_in_arr(I).valid <= '1'; - end loop; - end process; - - u_dp_shiftram : entity dp_lib.dp_shiftram - generic map ( - g_nof_streams => c_sdp_S_pn, - g_nof_words => c_sdp_V_sample_delay, - g_data_w => c_sdp_W_adc, - g_use_sync_in => true - ) - port map ( - dp_rst => rx_rst, - dp_clk => rx_clk, - - mm_rst => mm_rst, - mm_clk => mm_clk, - - sync_in => bs_sosi.sync, - - reg_mosi => reg_dp_shiftram_mosi, - reg_miso => reg_dp_shiftram_miso, - - snk_in_arr => dp_shiftram_snk_in_arr, - - src_out_arr => ant_sosi_arr - ); - end generate; - ----------------------------------------------------------------------------- -- Timestamp ----------------------------------------------------------------------------- @@ -223,9 +179,8 @@ begin ); ----------------------------------------------------------------------------- - -- WG (Test Signal Generator) + -- WG (Waveworm Generator) ----------------------------------------------------------------------------- - u_wg_arr : entity diag_lib.mms_diag_wg_wideband_arr generic map ( g_nof_streams => c_sdp_S_pn, @@ -262,44 +217,86 @@ begin ); ----------------------------------------------------------------------------- - -- ADC/WG Mux (Input Select) + -- ADC data ----------------------------------------------------------------------------- + p_rx_rewire_data : process(rx_sosi_arr) + begin + ant_sosi_arr <= rx_sosi_arr; + for I in 0 to c_sdp_S_pn - 1 loop + -- ADC data is stored in the upper 14 bits of the jesd rx_sosi. + ant_sosi_arr(I).data <= RESIZE_DP_SDATA(rx_sosi_arr(I).data(c_sdp_W_adc_jesd - 1 downto (c_sdp_W_adc_jesd - c_sdp_W_adc) )); + ant_sosi_arr(I).valid <= rx_sosi_arr(I).valid; -- connect, but not used + end loop; + end process; + ----------------------------------------------------------------------------- + -- ADC/WG Mux (Input Select) + ----------------------------------------------------------------------------- gen_mux : for I in 0 to c_sdp_S_pn - 1 generate - p_sosi : process(ant_sosi_arr(I), wg_sosi_arr(I)) + p_mux : process(ant_sosi_arr(I), wg_sosi_arr(I)) begin -- Default use the ADC data - nxt_mux_sosi_arr(I).data <= ant_sosi_arr(I).data; + nxt_mux_sosi_arr(I).data <= ant_sosi_arr(I).data; if wg_sosi_arr(I).valid = '1' then -- Valid WG data overrules ADC data nxt_mux_sosi_arr(I).data <= wg_sosi_arr(I).data; end if; + -- Force valid = '1' to maintain synchronous processing, independent of + -- whether the ADC/WG data values are valid + nxt_mux_sosi_arr(I).valid <= '1'; end process; end generate; - mux_sosi_arr <= nxt_mux_sosi_arr when rising_edge(rx_clk); + mux_sosi_arr <= nxt_mux_sosi_arr when rising_edge(rx_clk); ----------------------------------------------------------------------------- - -- Concatenate muxed data streams with bsn framing + -- Time delay: dp_shiftram + -- . copied from unb1_bn_capture_input (apertif) + -- Array range reversal is not done because everything is DOWNTO + -- . the input valid is always '1', even when there is no data, to avoid + -- shift misalignment between different signal inputs on different nodes + -- . the sync_in ensures that a new shift setting takes effect at the + -- bs_sosi.sync ----------------------------------------------------------------------------- + u_dp_shiftram : entity dp_lib.dp_shiftram + generic map ( + g_nof_streams => c_sdp_S_pn, + g_nof_words => c_sdp_V_sample_delay, + g_data_w => c_sdp_W_adc, + g_use_sync_in => true + ) + port map ( + dp_rst => rx_rst, + dp_clk => rx_clk, + mm_rst => mm_rst, + mm_clk => mm_clk, + sync_in => bs_sosi.sync, + + reg_mosi => reg_dp_shiftram_mosi, + reg_miso => reg_dp_shiftram_miso, + + snk_in_arr => mux_sosi_arr, + src_out_arr => inp_sosi_arr + ); + + ----------------------------------------------------------------------------- + -- Concatenate input data streams with BSN framing + ----------------------------------------------------------------------------- gen_concat : for I in 0 to c_sdp_S_pn - 1 generate - p_sosi : process(mux_sosi_arr(I), bs_sosi) + p_concat : process(mux_sosi_arr(I), bs_sosi) begin - st_sosi_arr(I) <= bs_sosi; - st_sosi_arr(I).data <= mux_sosi_arr(I).data; + st_sosi_arr(I) <= bs_sosi; -- timestamp + st_sosi_arr(I).data <= inp_sosi_arr(I).data; end process; end generate; --------------------------------------------------------------------------------------- - -- Diagnostics on the bsn-framed data - -- . BSN Monitor (ToDo: can be removed as not part of the spec) - -- . Aduh monitor - -- . Data Buffer (variable depth from 1k-128k) + -- Diagnostics on the BSN-framed data --------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- - -- BSN monitor (Block Checker) + -- BSN monitor, for sync, BSN and nof samples per sync --------------------------------------------------------------------------------------- u_bsn_monitor : entity dp_lib.mms_dp_bsn_monitor generic map ( @@ -322,7 +319,7 @@ begin ); ----------------------------------------------------------------------------- - -- Monitor ADU/WG output + -- Monitor ADU/WG output, for mean sum and power sum ----------------------------------------------------------------------------- u_aduh_monitor : entity aduh_lib.mms_aduh_monitor_arr generic map ( @@ -337,7 +334,7 @@ begin mm_rst => mm_rst, mm_clk => mm_clk, - reg_mosi => reg_aduh_monitor_mosi, -- read only access to the signal path data mean sum and power sum registers + reg_mosi => reg_aduh_monitor_mosi, reg_miso => reg_aduh_monitor_miso, buf_mosi => c_mem_mosi_rst, -- Unused buf_miso => OPEN, @@ -350,9 +347,8 @@ begin ); ----------------------------------------------------------------------------- - -- Diagnostic Data Buffer + -- Diagnostic Data Buffer, for capturing raw time series data ----------------------------------------------------------------------------- - u_diag_data_buffer_bsn : entity diag_lib.mms_diag_data_buffer generic map ( g_nof_streams => c_sdp_S_pn, diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd index 0d029deee5d363a8e1c703dd7712f237de227266..aeef6fc98fcdcc4de0812b884fbc61a0ebb4e662 100644 --- a/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_pkg.vhd @@ -86,7 +86,7 @@ package sdp_pkg is constant c_sdp_S_sub_bf : natural := 488; constant c_sdp_R_os : natural := 2; -- Oversampling factor of 2 for PFB. 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_sample_delay : natural := 1024; -- 1024 uses 12 M20K, 2048 24 M20K and 4096 36 M20K 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; @@ -157,6 +157,12 @@ package sdp_pkg is -- c_sdp_nof_beamlets_per_longword * c_sdp_N_pol_bf * c_nof_complex = 2 * 2 * 2 = 8 octets subtype t_sdp_dual_pol_beamlet_in_longword is t_slv_8_arr(0 to 7); + ----------------------------------------------------------------------------- + -- Signal input delay buffer (dp_shiftram) + ----------------------------------------------------------------------------- + constant c_sdp_input_mux_latency : natural := 1; + constant c_sdp_shiftram_latency : natural := c_shiftram_latency + c_sdp_input_mux_latency; + ----------------------------------------------------------------------------- -- PFB ----------------------------------------------------------------------------- diff --git a/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_remote_ring.vhd b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_remote_ring.vhd new file mode 100644 index 0000000000000000000000000000000000000000..421f4496540b32e8393235abbc0d4a23388d1b55 --- /dev/null +++ b/applications/lofar2/libraries/sdp/tb/vhdl/tb_sdp_beamformer_remote_ring.vhd @@ -0,0 +1,165 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2023 +-- 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: E. Kooistra +-- Purpose: +-- . Test bench for multiple sdp_beamformer_output.vhd + ring_lane.vhd in a ring +-- Description: +-- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Beamformer +-- +-- This tb is inspired by tb_lofar2_unb2c_sdp_station_bf_ring.vhd, however +-- here the purpose is to simulate the memory usage of the circular buffer +-- in the bsn_aligner_v2 at each node. +-- +-- Usage: +-- > as 8 +-- > run -a +------------------------------------------------------------------------------- + +library IEEE, common_lib, dp_lib, reorder_lib; +use IEEE.std_logic_1164.all; +use common_lib.common_pkg.all; +use common_lib.common_mem_pkg.all; +use common_lib.tb_common_pkg.all; +use common_lib.tb_common_mem_pkg.all; +use dp_lib.dp_stream_pkg.all; +use work.sdp_pkg.all; +use work.tb_sdp_pkg.all; + +entity tb_sdp_beamformer_remote_ring is + generic ( + g_nof_rn : natural := 16 -- number of nodes in the ring + ); +end tb_sdp_beamformer_remote_ring; + +architecture tb of tb_sdp_beamformer_remote_ring is + constant c_dp_clk_period : time := 5 ns; -- 200 MHz + constant c_mm_clk_period : time := 1 ns; -- fast MM clk to speed up simulation + + constant c_last_rn : natural := g_nof_rn - 1; -- first ring node has index RN = 0 by definition. + + signal mm_init : std_logic := '1'; + signal tb_end : std_logic := '0'; + signal dp_clk : std_logic := '1'; + signal dp_rst : std_logic; + signal mm_clk : std_logic := '1'; + signal mm_rst : std_logic; + + signal rn_index : natural range 0 to c_sdp_N_pn_max - 1 := 0; + +begin + dp_rst <= '1', '0' after c_dp_clk_period * 7; + dp_clk <= (not dp_clk) or tb_end after c_dp_clk_period / 2; + + mm_rst <= '1', '0' after c_mm_clk_period * 7; + mm_clk <= (not mm_clk) or tb_end after c_mm_clk_period / 2; + + p_mm : process + variable v_offset : natural; + begin + proc_common_wait_until_low(dp_clk, mm_rst); + proc_common_wait_some_cycles(mm_clk, 10); + + proc_common_wait_cross_clock_domain_latency(c_mm_clk_period, c_dp_clk_period, c_common_cross_clock_domain_latency * 2); + mm_init <= '0'; + wait; + end process; + + + ------------------------------------------------------------------------------ + -- DUT + ------------------------------------------------------------------------------ + gen_dut : for RN in 0 to c_last_rn generate + -- Ring connections between nodes 0:c_last_rn,0 + u_ring_lane_bf : entity ring_lib.ring_lane + generic map ( + g_lane_direction => 1, -- transport in positive RN direction. + g_lane_data_w => c_longword_w, + g_lane_packet_length => c_lane_payload_nof_longwords_bf, + g_lane_total_nof_packets_w => c_lane_total_nof_packets_w, + g_use_dp_layer => true, + g_nof_rx_monitors => 1, + g_nof_tx_monitors => 1, + g_err_bi => c_err_bi, + g_nof_err_counts => c_nof_err_counts, + g_bsn_at_sync_check_channel => c_bsn_at_sync_check_channel, + g_validate_channel => c_validate_channel, + g_validate_channel_mode => c_validate_channel_mode, + g_sync_timeout => c_sync_timeout + ) + port map ( + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_clk => dp_clk, + dp_rst => dp_rst, + + from_lane_sosi => bf_from_ri_sosi_arr(beamset_id), + to_lane_sosi => bf_to_ri_sosi_arr(beamset_id), + lane_rx_cable_sosi => lane_rx_cable_sosi_arr(1 + beamset_id), + lane_rx_board_sosi => lane_rx_board_sosi_arr(1 + beamset_id), + lane_tx_cable_sosi => lane_tx_cable_sosi_arr(1 + beamset_id), + lane_tx_board_sosi => lane_tx_board_sosi_arr(1 + beamset_id), + bs_sosi => bf_bs_sosi, -- used for bsn and sync + + reg_ring_lane_info_copi => reg_ring_lane_info_bf_copi_arr(beamset_id), + reg_ring_lane_info_cipo => reg_ring_lane_info_bf_cipo_arr(beamset_id), + reg_bsn_monitor_v2_ring_rx_copi => reg_bsn_monitor_v2_ring_rx_bf_copi_arr(beamset_id), + reg_bsn_monitor_v2_ring_rx_cipo => reg_bsn_monitor_v2_ring_rx_bf_cipo_arr(beamset_id), + reg_bsn_monitor_v2_ring_tx_copi => reg_bsn_monitor_v2_ring_tx_bf_copi_arr(beamset_id), + reg_bsn_monitor_v2_ring_tx_cipo => reg_bsn_monitor_v2_ring_tx_bf_cipo_arr(beamset_id), + reg_dp_block_validate_err_copi => reg_dp_block_validate_err_bf_copi_arr(beamset_id), + reg_dp_block_validate_err_cipo => reg_dp_block_validate_err_bf_cipo_arr(beamset_id), + reg_dp_block_validate_bsn_at_sync_copi => reg_dp_block_validate_bsn_at_sync_bf_copi_arr(beamset_id), + reg_dp_block_validate_bsn_at_sync_cipo => reg_dp_block_validate_bsn_at_sync_bf_cipo_arr(beamset_id), + + this_rn => this_rn, + N_rn => ring_info.N_rn, + rx_select => ring_info.use_cable_to_previous_rn, + tx_select => ring_info.use_cable_to_next_rn + ); + + -- Intermediate BF alignment and summation at each node + u_sdp_beamformer_remote : entity work.sdp_beamformer_remote + port map ( + dp_clk => dp_clk, + dp_rst => dp_rst, + + rn_index => rn_index, + + local_bf_sosi : in t_dp_sosi; + from_ri_sosi : in t_dp_sosi; + to_ri_sosi : out t_dp_sosi; + bf_sum_sosi : out t_dp_sosi; + + mm_rst : in std_logic; + mm_clk : in std_logic; + + reg_bsn_align_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_align_cipo : out t_mem_cipo; + + reg_bsn_monitor_v2_bsn_align_input_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_monitor_v2_bsn_align_input_cipo : out t_mem_cipo; + + reg_bsn_monitor_v2_bsn_align_output_copi : in t_mem_copi := c_mem_copi_rst; + reg_bsn_monitor_v2_bsn_align_output_cipo : out t_mem_cipo + ); +end generate; -- gen_dut + +end tb; diff --git a/doc/erko_howto_tools.txt b/doc/erko_howto_tools.txt index b934aa032f9cdd312019fbcfb9cb881371db0d12..2ed1a047c7a79fb283c2d64f6099130986d150e8 100755 --- a/doc/erko_howto_tools.txt +++ b/doc/erko_howto_tools.txt @@ -287,6 +287,26 @@ Last SDPFW version used in 2022: ******************************************************************************* * Flash and reboot on L2TS using tunnel to SDPTR ******************************************************************************* +22 feb 2024 + +# Vanaf machine in ASTRON netwerk +cd git/sdptr +. ./init_sdptr.sh +# even kijken of de sdp translator te bereiken is: +sdp_rw.py --host cs001c.control.lofar --port 4840 -r firmware_version + +# als dat lukte: +sdp_firmware.py --host cs001c.control.lofar --port 4840 --write --image USER --file ~/images/*.rbf # juiste rbf opgeven + +# eventueel, om te controleren +sdp_firmware.py --host cs001c.control.lofar --port 4840 --read --verify --image USER --file ~/images/*.rbf # juiste rbf opgeven + +# om image aktief te maken +sdp_rw.py --host cs001c.control.lofar --port 4840 -w boot_image [1]*16 + +# checken of het gebeurt is: +sdp_rw.py --host cs001c.control.lofar --port 4840 -r firmware_version + 4 sept 2023 How to reach the SDP Translators on LCU2 in CS001? I got this from Reinier and Pieter to tunnel to the SDPTR, so that I can run the flash commands: diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd index 9fdebec8751b6b80700e888d8d71b31456b45b13..90462168dac8c42962557e50a1786a50b946b256 100644 --- a/libraries/base/common/src/vhdl/common_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_pkg.vhd @@ -95,6 +95,8 @@ package common_pkg is constant c_fifo_afull_margin : natural := 4; -- default or minimal FIFO almost full margin + constant c_shiftram_latency : natural := 3; -- minimal latency of common_shiftram when data_in_shift = 0 + -- DSP constant c_dsp_mult_w : natural := 18; -- Width of the embedded multipliers in Stratix IV (and Arria 10 for 2 multipliers per DSP block) constant c_dsp_mult_18_w : natural := 18; -- Width of the embedded multipliers in Stratix IV (and Arria 10 for 2 multipliers per DSP block) diff --git a/libraries/base/common/src/vhdl/common_shiftram.vhd b/libraries/base/common/src/vhdl/common_shiftram.vhd index 382a87a482c9a6c1d4976ea96cbbb0fa2357cdf5..7770e46a34b7345415fa6f016d77b1f4964f214a 100644 --- a/libraries/base/common/src/vhdl/common_shiftram.vhd +++ b/libraries/base/common/src/vhdl/common_shiftram.vhd @@ -30,6 +30,8 @@ -- interpreted as the maximum value. -- . data_out_shift will always indicate the shift as applied to the -- corresponding data_out. +-- . The common_shiftram has a latency of c_shiftram_latency = 3, so the +-- actual shift is c_shiftram_latency + data_in_shift. -- -- -- Cycle 0 Cycle 1 Cycle 2 Cycle 3 diff --git a/libraries/technology/ip_arria10_e1sg/jesd204b/ip_arria10_e1sg_jesd204b_v2.vhd b/libraries/technology/ip_arria10_e1sg/jesd204b/ip_arria10_e1sg_jesd204b_v2.vhd index 1c0d8ec310a410658266cf2f48a8c9ab18e41c86..06e7aa982415c438d910995dff7c8e2841fcba25 100644 --- a/libraries/technology/ip_arria10_e1sg/jesd204b/ip_arria10_e1sg_jesd204b_v2.vhd +++ b/libraries/technology/ip_arria10_e1sg/jesd204b/ip_arria10_e1sg_jesd204b_v2.vhd @@ -497,6 +497,10 @@ begin -- JESD204B IP is synchronized. wr_rst <= not wr_core_pll_locked; + -- The FIFO g_data_w = c_jesd204b_rx_data_w = 32b does not have to be optimized + -- for the fact that the actual ADC data width is 14b instead of 16b. It appears + -- that Quartus synthesis will automatically optimize away the unused bits from + -- the FIFO data width. u_dp_fifo_dc_arr : entity dp_lib.dp_fifo_dc_arr generic map ( g_nof_streams => g_nof_streams, @@ -533,13 +537,22 @@ begin -- dp_index. This is because reading ab, cd, ef, ... is equivalent to reading -- bc, de, fg, ... However the phase of dp_ready with respect to dp_index is -- important for reading the sync, because if dp_ready has the wrong phase, - -- then the sync is missed at the FIFO output. + -- then the sync is missed at the FIFO output. The reason that the sync can be + -- missed is that it is passed on via the sosi.sync, which means that it is + -- forced to '0' when sosi.valid = '0' due to dp_ready = '0'. If the sync would + -- be passed on as a sosi.data bit, then it would hold its '1' value also during + -- sosi.valid = '0'. -- . If dp_index = '0' or '1' initialy, then in both cases use dp_ready <= not -- dp_index, and then in both cases the latency dp_sosi.sync and data = 1000 is -- then 340 ns - -- . Do not use dp_ready <= dp_index, because then the dp_sosi.sync gets missed. + -- . Do not use dp_ready <= dp_index, because then they have opposite phase + -- and then dp_sosi.sync gets missed. -- Therefore choose to use dp_index = '0' initially, because then dp_ready = - -- dp_index always. + -- dp_index always. Then in the dp_clk cycle after dp_ready = '1' the high part + -- data is read (because dp_index = '0') and the sync is available (because + -- then valid = '1'). In the next dp_clk cycle the low part is read (because + -- dp_index = '1') and the dp_ready = '1', to prepare for the next data word + -- read from the FIFO. p_fsm_dp_index : process(dp_rst, dp_clk) begin if dp_rst = '1' then diff --git a/libraries/technology/ip_arria10_e2sg/jesd204b/ip_arria10_e2sg_jesd204b_v2.vhd b/libraries/technology/ip_arria10_e2sg/jesd204b/ip_arria10_e2sg_jesd204b_v2.vhd index 79501ebef68c71773c63068d39457489e14adaf6..a21f86e148b37736da66616bc94b730692369e22 100644 --- a/libraries/technology/ip_arria10_e2sg/jesd204b/ip_arria10_e2sg_jesd204b_v2.vhd +++ b/libraries/technology/ip_arria10_e2sg/jesd204b/ip_arria10_e2sg_jesd204b_v2.vhd @@ -497,6 +497,10 @@ begin -- JESD204B IP is synchronized. wr_rst <= not wr_core_pll_locked; + -- The FIFO g_data_w = c_jesd204b_rx_data_w = 32b does not have to be optimized + -- for the fact that the actual ADC data width is 14b instead of 16b. It appears + -- that Quartus synthesis will automatically optimize away the unused bits from + -- the FIFO data width. u_dp_fifo_dc_arr : entity dp_lib.dp_fifo_dc_arr generic map ( g_nof_streams => g_nof_streams, @@ -533,13 +537,22 @@ begin -- dp_index. This is because reading ab, cd, ef, ... is equivalent to reading -- bc, de, fg, ... However the phase of dp_ready with respect to dp_index is -- important for reading the sync, because if dp_ready has the wrong phase, - -- then the sync is missed at the FIFO output. + -- then the sync is missed at the FIFO output. The reason that the sync can be + -- missed is that it is passed on via the sosi.sync, which means that it is + -- forced to '0' when sosi.valid = '0' due to dp_ready = '0'. If the sync would + -- be passed on as a sosi.data bit, then it would hold its '1' value also during + -- sosi.valid = '0'. -- . If dp_index = '0' or '1' initialy, then in both cases use dp_ready <= not -- dp_index, and then in both cases the latency dp_sosi.sync and data = 1000 is -- then 340 ns - -- . Do not use dp_ready <= dp_index, because then the dp_sosi.sync gets missed. + -- . Do not use dp_ready <= dp_index, because then they have opposite phase + -- and then dp_sosi.sync gets missed. -- Therefore choose to use dp_index = '0' initially, because then dp_ready = - -- dp_index always. + -- dp_index always. Then in the dp_clk cycle after dp_ready = '1' the high part + -- data is read (because dp_index = '0') and the sync is available (because + -- then valid = '1'). In the next dp_clk cycle the low part is read (because + -- dp_index = '1') and the dp_ready = '1', to prepare for the next data word + -- read from the FIFO. p_fsm_dp_index : process(dp_rst, dp_clk) begin if dp_rst = '1' then