diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd index 5cf5c737e6530ee05b3721fe0e4d4a83315656e1..817155f4a16145c8ad74f626da15f0a3ad245af6 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/revisions/lofar2_unb2c_sdp_station_adc/tb_lofar2_unb2c_sdp_station_adc_jesd.vhd @@ -49,6 +49,8 @@ -- > as 16 # for detailed debugging of JESD204B IP -- > run -a -- +-- View ait_sosi_arr, to see that only complete blocks are passed on. +-- ------------------------------------------------------------------------------- LIBRARY IEEE, common_lib, unb2c_board_lib, i2c_lib, mm_lib, dp_lib, diag_lib, lofar2_sdp_lib, wpfb_lib, lofar2_unb2c_sdp_station_lib, tech_jesd204b_lib; USE IEEE.std_logic_1164.ALL; @@ -114,6 +116,7 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS CONSTANT c_mm_file_reg_bsn_scheduler_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_BSN_SCHEDULER"; CONSTANT c_mm_file_reg_diag_wg : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_WG"; CONSTANT c_mm_file_reg_aduh_mon : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_ADUH_MONITOR"; + CONSTANT c_mm_file_reg_dp_shiftram : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "REG_DP_SHIFTRAM"; CONSTANT c_mm_file_jesd204b : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "JESD204B"; CONSTANT c_mm_file_pio_jesd_ctrl : STRING := mmf_unb_file_prefix(c_unb_nr, c_node_nr) & "PIO_JESD_CTRL"; @@ -126,6 +129,9 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS SIGNAL pps_rst : STD_LOGIC := '1'; SIGNAL gen_pps : STD_LOGIC := '0'; + -- Input delay + SIGNAL rd_input_delay : NATURAL; + -- WG SIGNAL dbg_c_exp_wg_power_sp_0 : REAL := c_exp_wg_power_sp_0; SIGNAL sp_samples : t_integer_arr(0 TO c_mon_buffer_nof_samples-1) := (OTHERS=>0); @@ -204,11 +210,12 @@ ARCHITECTURE tb OF tb_lofar2_unb2c_sdp_station_adc_jesd IS SIGNAL pio_jesd_ctrl_reset : STD_LOGIC; -- Debug signals to track progress of p_stimuli in Wave Window - SIGNAL dbg_restart : NATURAL := 0; - SIGNAL dbg_bsn_source_en : STD_LOGIC := '0'; - SIGNAL dbg_jesd_ctrl_reset : STD_LOGIC := '0'; - SIGNAL dbg_read_jesd204b : STD_LOGIC := '0'; - SIGNAL dbg_link_reinit : STD_LOGIC := '0'; + SIGNAL dbg_restart : NATURAL := 0; + SIGNAL dbg_bsn_source_en : STD_LOGIC := '0'; + SIGNAL dbg_jesd_ctrl_reset_ignore : STD_LOGIC := '0'; + SIGNAL dbg_jesd_ctrl_reset : STD_LOGIC := '0'; + SIGNAL dbg_read_jesd204b : STD_LOGIC := '0'; + SIGNAL dbg_link_reinit : STD_LOGIC := '0'; -- Read JESD204B IP status per signal input c_si PROCEDURE proc_read_jesd204b(c_si : IN NATURAL; @@ -471,11 +478,21 @@ BEGIN VARIABLE v_sp_power_sum_0 : REAL; VARIABLE v_sp_subband_power : REAL; VARIABLE v_W, v_T, v_U, v_S, v_B : NATURAL; -- array indicies + VARIABLE v_exp_input_delay : NATURAL; BEGIN dbg_restart <= 0; FOR REP IN 0 TO c_nof_restarts LOOP -- Wait for DUT power up after reset or after AIT rx_clk domain restart - WAIT FOR 1 us; + WAIT FOR 2 us; + + ---------------------------------------------------------------------------- + -- Set and readback input delay for si = 0 + ---------------------------------------------------------------------------- + v_exp_input_delay := 10 + REP; + mmf_mm_bus_wr(c_mm_file_reg_dp_shiftram, 0, v_exp_input_delay, tb_clk); + proc_common_wait_cross_clock_domain_latency(tb_clk, ext_clk); + mmf_mm_bus_rd(c_mm_file_reg_dp_shiftram, 0, rd_data, tb_clk); + rd_input_delay <= TO_UINT(rd_data); ---------------------------------------------------------------------------- -- Enable BS @@ -576,6 +593,31 @@ BEGIN ASSERT v_sp_power_sum_0 > c_lo_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR; ASSERT v_sp_power_sum_0 < c_hi_factor * c_exp_wg_power_sp_0 REPORT "Wrong SP power for SP 0" SEVERITY ERROR; + -- Try to reset via JESD_CTRL. This JESD_CTRL should be ignored. + -- Note: Awkward way to set MSbit without negative integer warning, using TO_SINT(v_word). + dbg_jesd_ctrl_reset_ignore <= '1'; -- marker in wave window + -- apply JESD_CTRL reset + v_word := (OTHERS => '0'); + v_word(c_sdp_jesd_ctrl_reset_bi) := '1'; -- reset + mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, TO_SINT(v_word), tb_clk); + proc_common_wait_cross_clock_domain_latency(tb_clk, ext_clk); + mmf_mm_bus_rd(c_mm_file_pio_jesd_ctrl, 0, rd_data, tb_clk); + pio_jesd_ctrl <= rd_data; + pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0); + pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT pio_jesd_ctrl_reset = '0' REPORT "JESD_CTRL reset should be ignored when BSN source is on." SEVERITY ERROR; + -- remove JESD_CTRL reset + v_word := (OTHERS => '0'); + v_word(c_sdp_jesd_ctrl_reset_bi) := '0'; -- reset + mmf_mm_bus_wr(c_mm_file_pio_jesd_ctrl, 0, TO_SINT(v_word), tb_clk); + proc_common_wait_cross_clock_domain_latency(tb_clk, ext_clk); + mmf_mm_bus_rd(c_mm_file_pio_jesd_ctrl, 0, rd_data, tb_clk); + pio_jesd_ctrl <= rd_data; + pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0); + pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi); + dbg_jesd_ctrl_reset_ignore <= '0'; + ---------------------------------------------------------------------------- -- Restart AIT -- . JESD_CTRL reset stops JESD204B OUT rx_clk and asserts JESD204B OUT @@ -603,6 +645,8 @@ BEGIN pio_jesd_ctrl <= rd_data; pio_jesd_ctrl_enable <= rd_data(c_sdp_jesd_ctrl_enable_w-1 DOWNTO 0); pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT pio_jesd_ctrl_reset = '1' REPORT "JESD_CTRL reset should be applied when BSN source is off." SEVERITY ERROR; WAIT FOR 1 us; -- Read Rx JESD_204B IP status during reset @@ -615,6 +659,12 @@ BEGIN reg_jesd204b_csr_rbd_count, reg_jesd204b_csr_dev_syncn); + -- Read input delay during reset + mmf_mm_bus_rd(c_mm_file_reg_dp_shiftram, 0, rd_data, tb_clk); + rd_input_delay <= TO_UINT(rd_data); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT rd_input_delay = v_exp_input_delay REPORT "wrong rd_input_delay during JESD reset." SEVERITY ERROR; + -- Hold JESD_CTRL reset for > one sync period, so also during a JESD204B_SYSREF pulse, -- to see that JESD_CTRL reset stops JESD204B OUT rx_sysref too. WAIT FOR c_pps_period; @@ -630,6 +680,12 @@ BEGIN pio_jesd_ctrl_reset <= rd_data(c_sdp_jesd_ctrl_reset_bi); dbg_jesd_ctrl_reset <= '0'; -- marker in wave window + -- Read input delay after reset + mmf_mm_bus_rd(c_mm_file_reg_dp_shiftram, 0, rd_data, tb_clk); + rd_input_delay <= TO_UINT(rd_data); + proc_common_wait_some_cycles(tb_clk, 1); + ASSERT rd_input_delay = v_exp_input_delay REPORT "wrong rd_input_delay after JESD reset." SEVERITY ERROR; + -- Wait for a JESD204B_SYSREF pulse WAIT FOR c_pps_period; -- Read Rx JESD_204B IP status 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 5b110bfb743ac919ebcbfabb9466f16cb0b9a54e..6fa7c9cf74f206ff9710b89107ab1822c7f389f4 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 @@ -140,9 +140,11 @@ ARCHITECTURE str OF node_sdp_adc_input_and_timing IS SIGNAL nxt_mux_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); - SIGNAL mm_rst_internal : STD_LOGIC; - SIGNAL mm_jesd_ctrl_reg : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL mm_rst_jesd : STD_LOGIC; + SIGNAL mm_jesd_ctrl_reg_wr : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); + SIGNAL mm_jesd_ctrl_reg_rd : STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0); SIGNAL jesd204b_disable_arr : STD_LOGIC_VECTOR(c_sdp_S_pn-1 DOWNTO 0); + SIGNAL jesd204b_reset_request : STD_LOGIC := '0'; BEGIN @@ -152,18 +154,30 @@ BEGIN rx_sysref <= dp_pps; END GENERATE; - -- The node AIT is reset at power up by mm_rst and under software control by jesd204b_disable_arr. - -- The mm_rst internal will cause a reset on the rx_rst by the reset sequencer in the u_jesd204b. - -- The MM jesd204b_disable_arr is intended for node AIT resynchronisation tests of the u_jesd204b. - -- The MM jesd204b_disable_arr should not be applied in an SDP application, because this will cause + -- The node AIT is reset at power up by mm_rst and under software control by mm_rst_jesd. + -- The mm_rst_jesd will cause a reset on the rx_rst by the reset sequencer in the u_jesd204b. + -- The mm_rst_jesd is intended for node AIT resynchronisation tests of the u_jesd204b. + -- The mm_rst_jesd should not be applied in an active SDP application, because this will cause -- a disturbance in the block timing of the out_sosi_arr(i).sync,bsn,sop,eop. The other logic -- in an SDP application assumes that the block timing of the out_sosi_arr(i) only contains - -- complete blocks, so from sop to eop. + -- complete blocks, so from sop to eop. Therefore, first mms_dp_bsn_source_v2 should be + -- disabled to stop and flush the block processing, before applying mm_rst_jesd. - mm_rst_internal <= mm_rst OR mm_jesd_ctrl_reg(c_sdp_jesd_ctrl_reset_bi); - gen_jesd_disable : FOR I IN 0 TO c_sdp_S_pn-1 GENERATE - jesd204b_disable_arr(i) <= mm_jesd_ctrl_reg(i); - END GENERATE; + -- Only accept JESD204B IP reset when the processing is disabled (indicated by bs_sosi.valid + -- = '0'), to avoid corrupt bs_sosi blocks entering the subsequent processing due to that a + -- JESD204B IP reset causes that the rx_clk stops. + mm_rst_jesd <= mm_rst OR jesd204b_reset_request; + + jesd204b_disable_arr <= mm_jesd_ctrl_reg_wr(c_sdp_S_pn-1 DOWNTO 0); + jesd204b_reset_request <= mm_jesd_ctrl_reg_wr(c_sdp_jesd_ctrl_reset_bi) AND NOT bs_sosi.valid; + + p_mm_jesd_ctrl_reg_rd : PROCESS(mm_jesd_ctrl_reg_wr, jesd204b_reset_request) + BEGIN + -- default readback what was written + mm_jesd_ctrl_reg_rd <= mm_jesd_ctrl_reg_wr; + -- report actual JESD204B reset status + mm_jesd_ctrl_reg_rd(c_sdp_jesd_ctrl_reset_bi) <= jesd204b_reset_request; + END PROCESS; gen_jesd : IF g_no_jesd = FALSE GENERATE ----------------------------------------------------------------------------- @@ -191,7 +205,7 @@ BEGIN -- MM mm_clk => mm_clk, - mm_rst => mm_rst_internal, + mm_rst => mm_rst_jesd, jesd204b_mosi => jesd204b_mosi, jesd204b_miso => jesd204b_miso, @@ -200,8 +214,7 @@ BEGIN serial_tx_arr => open, serial_rx_arr => JESD204B_SERIAL_DATA(c_sdp_S_pn-1 downto 0) ); - - + ----------------------------------------------------------------------------- -- Time delay: dp_shiftram -- . copied from unb1_bn_capture_input (apertif) @@ -214,13 +227,12 @@ 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) )); + 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'; + 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, @@ -232,7 +244,7 @@ BEGIN dp_rst => rx_rst, dp_clk => rx_clk, - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, sync_in => bs_sosi.sync, @@ -258,7 +270,7 @@ BEGIN ) PORT MAP ( -- Clocks and reset - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, dp_rst => rx_rst, dp_clk => rx_clk, @@ -281,7 +293,7 @@ BEGIN ) PORT MAP ( -- Memory-mapped clock domain - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, reg_mosi => reg_bsn_scheduler_wg_mosi, @@ -318,7 +330,7 @@ BEGIN ) PORT MAP ( -- Memory-mapped clock domain - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, reg_mosi => reg_wg_mosi, @@ -387,7 +399,7 @@ BEGIN ) PORT MAP ( -- Memory-mapped clock domain - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, reg_mosi => reg_bsn_monitor_input_mosi, reg_miso => reg_bsn_monitor_input_miso, @@ -412,7 +424,7 @@ BEGIN ) PORT MAP ( -- Memory-mapped clock domain - mm_rst => mm_rst_internal, + 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 @@ -440,7 +452,7 @@ BEGIN g_buf_use_sync => TRUE -- when TRUE start filling the buffer at the in_sync, else after the last word was read ) PORT MAP ( - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, dp_rst => rx_rst, dp_clk => rx_clk, @@ -466,7 +478,7 @@ BEGIN g_nof_data_per_sync_diff => c_sdp_N_fft/2 ) PORT MAP ( - mm_rst => mm_rst_internal, + mm_rst => mm_rst, mm_clk => mm_clk, dp_rst => rx_rst, dp_clk => rx_clk, @@ -527,8 +539,8 @@ BEGIN rd_dat => jesd_ctrl_miso.rddata(c_sdp_mm_jesd_ctrl_reg.dat_w-1 DOWNTO 0), rd_val => OPEN, -- data side - out_reg => mm_jesd_ctrl_reg, - in_reg => mm_jesd_ctrl_reg + out_reg => mm_jesd_ctrl_reg_wr, + in_reg => mm_jesd_ctrl_reg_rd ); END str; diff --git a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd index 66598b4d337c739710274cbe38b8ebebb8d85bf6..84c6953020fc5f8c44d5313a2f25398af3612de5 100644 --- a/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd +++ b/libraries/base/dp/src/vhdl/dp_bsn_source_v2.vhd @@ -29,9 +29,16 @@ -- sop and eop will be active. -- Alternatively, one can assert dp_on while dp_on_pps is high to -- start the data path on the next PPS. +-- The dp_on is asynchronous. The dp_bsn_source_v2 takes care that +-- src_out.valid starts with a src_out.sop and that src_out.valid can +-- only go low after a src_out.eop, to ensure that src_out only produces +-- complete sop-eop blocks that enter the subsequent processing. +-- The bs_start is active at the first src_out.sop after dp_on went high. -- Remarks: --- Starting the data path is only possible from the dp_off state, so one +-- . Starting the data path is only possible from the dp_off state, so one -- has to disable (dp_on='0') the data path before restarting it. +-- . Effectively dp_on_status = src_out.valid, because when the BSN source +-- is on, then src_out.valid = '1' at every clk cycle. -- -- author : P.Donker okt. 2020, added bsn_time_offset -- @@ -57,8 +64,8 @@ ENTITY dp_bsn_source_v2 IS dp_on : IN STD_LOGIC; dp_on_pps : IN STD_LOGIC; - dp_on_status : OUT STD_LOGIC; - bs_restart : OUT STD_LOGIC; + dp_on_status : OUT STD_LOGIC; -- = src_out.valid + bs_restart : OUT STD_LOGIC; -- = src_out.sop for first sop after dp_on went high nof_clk_per_sync : IN STD_LOGIC_VECTOR(c_word_w-1 DOWNTO 0) := TO_UVEC(g_nof_clk_per_sync, c_word_w); bsn_init : IN STD_LOGIC_VECTOR(g_bsn_w-1 DOWNTO 0) := (OTHERS=>'0');