diff --git a/applications/lofar2/designs/lofar2_unb2b_adc/src/vhdl/node_adc_input_and_timing.vhd b/applications/lofar2/designs/lofar2_unb2b_adc/src/vhdl/node_adc_input_and_timing.vhd index 392b5eac21f078d7f3bbb56f04619092bbfe325a..2894ca55e4d73e521d026f154b371d1808c9d0d5 100644 --- a/applications/lofar2/designs/lofar2_unb2b_adc/src/vhdl/node_adc_input_and_timing.vhd +++ b/applications/lofar2/designs/lofar2_unb2b_adc/src/vhdl/node_adc_input_and_timing.vhd @@ -1,513 +1,513 @@ -------------------------------------------------------------------------------- --- --- Copyright 2020 --- 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 : J Hargreaves --- Purpose: --- AIT - ADC (Jesd) receiver, input, timing and associated diagnostic blocks --- Description: --- Unb2b version for lab testing --- Contains all the signal processing blocks to receive and time the ADC input data --- See https://support.astron.nl/confluence/display/STAT/L5+SDPFW+DD%3A+ADC+data+input+and+timestamp - -LIBRARY IEEE, common_lib, unb2b_board_lib, technology_lib, diag_lib, aduh_lib, dp_lib, tech_jesd204b_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 technology_lib.technology_pkg.ALL; -USE unb2b_board_lib.unb2b_board_pkg.ALL; -USE unb2b_board_lib.unb2b_board_peripherals_pkg.ALL; -USE diag_lib.diag_pkg.ALL; -USE dp_lib.dp_stream_pkg.ALL; -USE work.lofar2_unb2b_adc_pkg.ALL; - -ENTITY node_adc_input_and_timing IS - GENERIC ( - g_technology : NATURAL := c_tech_arria10_e1sg; - g_buf_nof_data : NATURAL := 8192; --1024; - g_nof_streams : NATURAL := 12; - g_nof_sync_n : NATURAL := 4; -- Three ADCs per RCU share a sync - g_aduh_buffer_nof_symbols : NATURAL := 512; -- Default 512 - g_bsn_sync_timeout : NATURAL := 200000000; -- Default 200M, overide for short simulation - g_sim : BOOLEAN := FALSE - ); - PORT ( - -- clocks and resets - mm_clk : IN STD_LOGIC; - mm_rst : IN STD_LOGIC; - dp_clk : IN STD_LOGIC; - dp_rst : IN STD_LOGIC; - - -- mm control buses - -- JESD - jesd204b_mosi : IN t_mem_mosi := c_mem_mosi_rst; - jesd204b_miso : OUT t_mem_miso := c_mem_miso_rst; - - -- Shiftram (applies per-antenna delay) - reg_dp_shiftram_mosi : IN t_mem_mosi := c_mem_mosi_rst; - reg_dp_shiftram_miso : OUT t_mem_miso := c_mem_miso_rst; - - -- bsn source - reg_bsn_source_mosi : IN t_mem_mosi := c_mem_mosi_rst; - reg_bsn_source_miso : OUT t_mem_miso := c_mem_miso_rst; - - -- bsn scheduler - reg_bsn_scheduler_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; - reg_bsn_scheduler_wg_miso : OUT t_mem_miso := c_mem_miso_rst; - - -- WG - reg_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; - reg_wg_miso : OUT t_mem_miso := c_mem_miso_rst; - ram_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; - ram_wg_miso : OUT t_mem_miso := c_mem_miso_rst; - - -- BSN MONITOR - reg_bsn_monitor_input_mosi : IN t_mem_mosi; - reg_bsn_monitor_input_miso : OUT t_mem_miso; - - -- Data buffer for raw samples - ram_diag_data_buf_jesd_mosi : IN t_mem_mosi; - ram_diag_data_buf_jesd_miso : OUT t_mem_miso; - reg_diag_data_buf_jesd_mosi : IN t_mem_mosi; - reg_diag_data_buf_jesd_miso : OUT t_mem_miso; - - -- Data buffer for framed samples (variable depth) - ram_diag_data_buf_bsn_mosi : IN t_mem_mosi; - ram_diag_data_buf_bsn_miso : OUT t_mem_miso; - reg_diag_data_buf_bsn_mosi : IN t_mem_mosi; - reg_diag_data_buf_bsn_miso : OUT t_mem_miso; - - -- Aduh (statistics) monitor - ram_aduh_monitor_mosi : IN t_mem_mosi; - ram_aduh_monitor_miso : OUT t_mem_miso; - reg_aduh_monitor_mosi : IN t_mem_mosi; - reg_aduh_monitor_miso : OUT t_mem_miso; - - -- JESD io signals - jesd204b_serial_data : IN STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w*c_unb2b_board_tr_jesd204b.nof_bus)-1 downto 0); - jesd204b_refclk : IN STD_LOGIC; - jesd204b_sysref : IN STD_LOGIC; - jesd204b_sync_n : OUT STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w*c_unb2b_board_tr_jesd204b.nof_bus)-1 DOWNTO 0); - - -- Streaming data output - out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) - - ); -END node_adc_input_and_timing; - - -ARCHITECTURE str OF node_adc_input_and_timing IS - - -- Firmware version x.y - CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 1); - CONSTANT c_mm_clk_freq : NATURAL := c_unb2b_board_mm_clk_freq_100M; - CONSTANT c_lofar2_sample_clk_freq : NATURAL := 200 * 10**6; -- alternate 160MHz. TODO: Use to check PPS - - CONSTANT c_nof_streams_jesd204b : NATURAL := 12; -- IP is set up for 12 streams - CONSTANT c_nof_streams_db : NATURAL := 2; -- Streams of raw samples to record in db - - -- Waveform Generator - CONSTANT c_wg_buf_directory : STRING := "data/"; - CONSTANT c_wg_buf_dat_w : NATURAL := c_unb2b_board_peripherals_mm_reg_default.ram_diag_wg_dat_w; - CONSTANT c_wg_buf_addr_w : NATURAL := c_unb2b_board_peripherals_mm_reg_default.ram_diag_wg_adr_w; - SIGNAL wg_out_ovr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL wg_out_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL wg_out_data : STD_LOGIC_VECTOR(g_nof_streams*c_wg_buf_dat_w-1 DOWNTO 0); - SIGNAL wg_out_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); - SIGNAL trigger_wg : STD_LOGIC; - - -- Frame parameters TBC - CONSTANT c_bs_bsn_w : NATURAL := 64; --51; - CONSTANT c_bs_block_size : NATURAL := 1024; - CONSTANT c_bs_nof_block_per_sync : NATURAL := 390625; -- generate a sync every 2s for testing - CONSTANT c_dp_shiftram_nof_samples: NATURAL := 4096; - CONSTANT c_data_w : NATURAL := 16; - CONSTANT c_dp_fifo_dc_size : NATURAL := 64; - - - -- QSFP leds - SIGNAL qsfp_green_led_arr : STD_LOGIC_VECTOR(c_unb2b_board_tr_qsfp.nof_bus-1 DOWNTO 0); - SIGNAL qsfp_red_led_arr : STD_LOGIC_VECTOR(c_unb2b_board_tr_qsfp.nof_bus-1 DOWNTO 0); - - -- JESD signals - SIGNAL rx_clk : STD_LOGIC; -- formerly jesd204b_frame_clk - SIGNAL rx_rst : STD_LOGIC; - SIGNAL rx_sysref : STD_LOGIC; - - -- Sosis and sosi arrays - SIGNAL rx_sosi_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); - SIGNAL dp_shiftram_snk_in_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); - SIGNAL ant_sosi_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); - SIGNAL diag_data_buf_snk_in_arr : t_dp_sosi_arr(c_nof_streams_db-1 DOWNTO 0); - SIGNAL bs_sosi : t_dp_sosi; - SIGNAL wg_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL mux_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL nxt_mux_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - SIGNAL st_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); - - -BEGIN - - ----------------------------------------------------------------------------- - -- JESD204B IP (ADC Handler) - ----------------------------------------------------------------------------- - - u_jesd204b: ENTITY tech_jesd204b_lib.tech_jesd204b - GENERIC MAP( - g_sim => g_sim, - g_nof_streams => c_nof_streams_jesd204b, - g_nof_sync_n => g_nof_sync_n - ) - PORT MAP( - jesd204b_refclk => JESD204B_REFCLK, - jesd204b_sysref => JESD204B_SYSREF, - jesd204b_sync_n_arr => jesd204b_sync_n, - - rx_sosi_arr => rx_sosi_arr, - rx_clk => rx_clk, - rx_rst => rx_rst, - rx_sysref => rx_sysref, - - -- MM - mm_clk => mm_clk, - mm_rst => mm_rst, - - jesd204b_mosi => jesd204b_mosi, - jesd204b_miso => jesd204b_miso, - - -- Serial - serial_tx_arr => open, - serial_rx_arr => JESD204B_SERIAL_DATA(c_nof_streams_jesd204b-1 downto 0) - ); - - - gen_jesd_mon_in : FOR i IN 0 TO c_nof_streams_db-1 GENERATE - diag_data_buf_snk_in_arr(i).data(c_data_w-1 downto 0) <= rx_sosi_arr(i).data(c_data_w-1 downto 0); - diag_data_buf_snk_in_arr(i).valid <= rx_sosi_arr(i).valid; - diag_data_buf_snk_in_arr(i).sop <= '0'; - diag_data_buf_snk_in_arr(i).eop <= '0'; - diag_data_buf_snk_in_arr(i).err <= (OTHERS=>'0'); - END GENERATE; - - - ----------------------------------------------------------------------------- - -- Diagnostic Data Buffer (Records 8192 raw ADC samples after the PPS) - -- ToDo: Remove this JESD DB when the second (BSN) data buffer is working correctly - ----------------------------------------------------------------------------- - - u_diag_data_buffer : ENTITY diag_lib.mms_diag_data_buffer - GENERIC MAP ( - g_technology => g_technology, - g_nof_streams => c_nof_streams_db, - g_data_w => c_data_w, - g_buf_nof_data => 8192, - 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, - mm_clk => mm_clk, - dp_rst => rx_rst, - dp_clk => rx_clk, - - ram_data_buf_mosi => ram_diag_data_buf_jesd_mosi, - ram_data_buf_miso => ram_diag_data_buf_jesd_miso, - reg_data_buf_mosi => reg_diag_data_buf_jesd_mosi, - reg_data_buf_miso => reg_diag_data_buf_jesd_miso, - - in_sosi_arr => diag_data_buf_snk_in_arr, - in_sync => rx_sysref - ); - - ----------------------------------------------------------------------------- - -- 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 - ----------------------------------------------------------------------------- - - gen_force_valid : FOR I IN 0 TO c_nof_streams_jesd204b-1 GENERATE - p_sosi : PROCESS(rx_sosi_arr) - BEGIN - dp_shiftram_snk_in_arr(I) <= rx_sosi_arr(I); - dp_shiftram_snk_in_arr(I).valid <= '1'; - END PROCESS; - END GENERATE; - - - u_dp_shiftram : ENTITY dp_lib.dp_shiftram - GENERIC MAP ( - g_nof_streams => c_nof_streams_jesd204b, - g_nof_words => c_dp_shiftram_nof_samples, - g_data_w => c_data_w, - 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 - ); - - ----------------------------------------------------------------------------- - -- Timestamp - ----------------------------------------------------------------------------- - u_bsn_source : ENTITY dp_lib.mms_dp_bsn_source - GENERIC MAP ( - g_cross_clock_domain => TRUE, - g_block_size => c_bs_block_size, - g_nof_block_per_sync => c_bs_nof_block_per_sync, - g_bsn_w => c_bs_bsn_w - ) - PORT MAP ( - -- Clocks and reset - mm_rst => mm_rst, - mm_clk => mm_clk, - dp_rst => rx_rst, - dp_clk => rx_clk, - dp_pps => rx_sysref, - - -- Memory-mapped clock domain - reg_mosi => reg_bsn_source_mosi, - reg_miso => reg_bsn_source_miso, - - -- Streaming clock domain - bs_sosi => bs_sosi - ); - - u_bsn_trigger_wg : ENTITY dp_lib.mms_dp_bsn_scheduler - GENERIC MAP ( - g_cross_clock_domain => TRUE, - g_bsn_w => c_bs_bsn_w - ) - PORT MAP ( - -- Memory-mapped clock domain - mm_rst => mm_rst, - mm_clk => mm_clk, - - reg_mosi => reg_bsn_scheduler_wg_mosi, - reg_miso => reg_bsn_scheduler_wg_miso, - - -- Streaming clock domain - dp_rst => rx_rst, - dp_clk => rx_clk, - - snk_in => bs_sosi, -- only uses eop (= block sync), bsn[] - trigger_out => trigger_wg - ); - - - ----------------------------------------------------------------------------- - -- WG (Test Signal Generator) - ----------------------------------------------------------------------------- - - u_wg_arr : ENTITY diag_lib.mms_diag_wg_wideband_arr - GENERIC MAP ( - g_nof_streams => g_nof_streams, - g_cross_clock_domain => TRUE, - g_buf_dir => c_wg_buf_directory, - - -- Wideband parameters - g_wideband_factor => 1, - - -- Basic WG parameters, see diag_wg.vhd for their meaning - g_buf_dat_w => c_wg_buf_dat_w, - g_buf_addr_w => c_wg_buf_addr_w, - g_calc_support => TRUE, - g_calc_gain_w => 1, - g_calc_dat_w => c_wg_buf_dat_w - ) - PORT MAP ( - -- Memory-mapped clock domain - mm_rst => mm_rst, - mm_clk => mm_clk, - - reg_mosi => reg_wg_mosi, - reg_miso => reg_wg_miso, - - buf_mosi => ram_wg_mosi, - buf_miso => ram_wg_miso, - - -- Streaming clock domain - st_rst => rx_rst, - st_clk => rx_clk, - st_restart => trigger_wg, - - out_sosi_arr => wg_sosi_arr - ); - - - ----------------------------------------------------------------------------- - -- ADC/WG Mux (Input Select) - ----------------------------------------------------------------------------- - - gen_mux : FOR I IN 0 TO g_nof_streams-1 GENERATE - p_sosi : 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; - 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; - END PROCESS; - END GENERATE; - - mux_sosi_arr <= nxt_mux_sosi_arr WHEN rising_edge(rx_clk); - - ----------------------------------------------------------------------------- - -- Concatenate muxed data streams with bsn framing - ----------------------------------------------------------------------------- - - gen_concat : FOR I IN 0 TO g_nof_streams-1 GENERATE - p_sosi : PROCESS(mux_sosi_arr(I), bs_sosi) - BEGIN - st_sosi_arr(I) <= bs_sosi; - st_sosi_arr(I).data <= mux_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) - --------------------------------------------------------------------------------------- - - - --------------------------------------------------------------------------------------- - -- BSN monitor (Block Checker) - --------------------------------------------------------------------------------------- - u_bsn_monitor : ENTITY dp_lib.mms_dp_bsn_monitor - GENERIC MAP ( - g_nof_streams => 1, -- They're all the same - g_sync_timeout => g_bsn_sync_timeout, - g_bsn_w => c_bs_bsn_w, - g_log_first_bsn => FALSE - ) - PORT MAP ( - -- Memory-mapped clock domain - mm_rst => mm_rst, - mm_clk => mm_clk, - reg_mosi => reg_bsn_monitor_input_mosi, - reg_miso => reg_bsn_monitor_input_miso, - - -- Streaming clock domain - dp_rst => rx_rst, - dp_clk => rx_clk, - in_sosi_arr => st_sosi_arr(0 downto 0) - ); - - - ----------------------------------------------------------------------------- - -- Monitor ADU/WG output - ----------------------------------------------------------------------------- - u_aduh_monitor : ENTITY aduh_lib.mms_aduh_monitor_arr - GENERIC MAP ( - g_cross_clock_domain => TRUE, - g_nof_streams => g_nof_streams, - g_symbol_w => c_data_w, --TBD 16? - g_nof_symbols_per_data => 1, -- Wideband factor is 1 - g_nof_accumulations => 200000512, -- = 195313 blocks * 1024 samples - g_buffer_nof_symbols => g_aduh_buffer_nof_symbols, -- default 512, larger for full design - g_buffer_use_sync => TRUE -- True to capture all streams synchronously - ) - PORT MAP ( - -- Memory-mapped clock domain - 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_miso => reg_aduh_monitor_miso, - buf_mosi => ram_aduh_monitor_mosi, -- read and overwrite access to the signal path data buffers - buf_miso => ram_aduh_monitor_miso, - - -- Streaming clock domain - st_rst => rx_rst, - st_clk => rx_clk, - - in_sosi_arr => st_sosi_arr - ); - - - ----------------------------------------------------------------------------- --- Diagnostic Data Buffer - ----------------------------------------------------------------------------- - - u_diag_data_buffer_bsn : ENTITY diag_lib.mms_diag_data_buffer - GENERIC MAP ( - g_technology => g_technology, - g_nof_streams => g_nof_streams, - g_data_w => c_data_w, - g_buf_nof_data => g_buf_nof_data, - 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, - mm_clk => mm_clk, - dp_rst => rx_rst, - dp_clk => rx_clk, - - ram_data_buf_mosi => ram_diag_data_buf_bsn_mosi, - ram_data_buf_miso => ram_diag_data_buf_bsn_miso, - reg_data_buf_mosi => reg_diag_data_buf_bsn_mosi, - reg_data_buf_miso => reg_diag_data_buf_bsn_miso, - - in_sosi_arr => st_sosi_arr, - in_sync => st_sosi_arr(0).sync - ); - - - ----------------------------------------------------------------------------- - -- Output Stage - -- . Thin dual clock fifo to cross from jesd frame clock (rx_clk) to dp_clk domain - ----------------------------------------------------------------------------- - - gen_dp_fifo_dc : FOR I IN 0 TO g_nof_streams-1 GENERATE - u_dp_fifo_dc : ENTITY dp_lib.dp_fifo_dc - GENERIC MAP ( - g_data_w => c_data_w, - g_use_empty => FALSE, --TRUE, - g_use_ctrl => TRUE, - g_use_sync => TRUE, - g_use_bsn => TRUE, - g_fifo_size => c_dp_fifo_dc_size - ) - PORT MAP ( - wr_rst => rx_rst, - wr_clk => rx_clk, - rd_rst => dp_rst, - rd_clk => dp_clk, - snk_in => st_sosi_arr(I), - src_out => out_sosi_arr(I) - ); - END GENERATE; - -END str; \ No newline at end of file +------------------------------------------------------------------------------- +-- +-- Copyright 2020 +-- 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 : J Hargreaves +-- Purpose: +-- AIT - ADC (Jesd) receiver, input, timing and associated diagnostic blocks +-- Description: +-- Unb2b version for lab testing +-- Contains all the signal processing blocks to receive and time the ADC input data +-- See https://support.astron.nl/confluence/display/STAT/L5+SDPFW+DD%3A+ADC+data+input+and+timestamp + +LIBRARY IEEE, common_lib, unb2b_board_lib, technology_lib, diag_lib, aduh_lib, dp_lib, tech_jesd204b_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 technology_lib.technology_pkg.ALL; +USE unb2b_board_lib.unb2b_board_pkg.ALL; +USE unb2b_board_lib.unb2b_board_peripherals_pkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE work.lofar2_unb2b_adc_pkg.ALL; + +ENTITY node_adc_input_and_timing IS + GENERIC ( + g_technology : NATURAL := c_tech_arria10_e1sg; + g_buf_nof_data : NATURAL := 8192; --1024; + g_nof_streams : NATURAL := 12; + g_nof_sync_n : NATURAL := 4; -- Three ADCs per RCU share a sync + g_aduh_buffer_nof_symbols : NATURAL := 512; -- Default 512 + g_bsn_sync_timeout : NATURAL := 200000000; -- Default 200M, overide for short simulation + g_sim : BOOLEAN := FALSE + ); + PORT ( + -- clocks and resets + mm_clk : IN STD_LOGIC; + mm_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; + dp_rst : IN STD_LOGIC; + + -- mm control buses + -- JESD + jesd204b_mosi : IN t_mem_mosi := c_mem_mosi_rst; + jesd204b_miso : OUT t_mem_miso := c_mem_miso_rst; + + -- Shiftram (applies per-antenna delay) + reg_dp_shiftram_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_dp_shiftram_miso : OUT t_mem_miso := c_mem_miso_rst; + + -- bsn source + reg_bsn_source_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_bsn_source_miso : OUT t_mem_miso := c_mem_miso_rst; + + -- bsn scheduler + reg_bsn_scheduler_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_bsn_scheduler_wg_miso : OUT t_mem_miso := c_mem_miso_rst; + + -- WG + reg_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_wg_miso : OUT t_mem_miso := c_mem_miso_rst; + ram_wg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + ram_wg_miso : OUT t_mem_miso := c_mem_miso_rst; + + -- BSN MONITOR + reg_bsn_monitor_input_mosi : IN t_mem_mosi; + reg_bsn_monitor_input_miso : OUT t_mem_miso; + + -- Data buffer for raw samples + ram_diag_data_buf_jesd_mosi : IN t_mem_mosi; + ram_diag_data_buf_jesd_miso : OUT t_mem_miso; + reg_diag_data_buf_jesd_mosi : IN t_mem_mosi; + reg_diag_data_buf_jesd_miso : OUT t_mem_miso; + + -- Data buffer for framed samples (variable depth) + ram_diag_data_buf_bsn_mosi : IN t_mem_mosi; + ram_diag_data_buf_bsn_miso : OUT t_mem_miso; + reg_diag_data_buf_bsn_mosi : IN t_mem_mosi; + reg_diag_data_buf_bsn_miso : OUT t_mem_miso; + + -- Aduh (statistics) monitor + ram_aduh_monitor_mosi : IN t_mem_mosi; + ram_aduh_monitor_miso : OUT t_mem_miso; + reg_aduh_monitor_mosi : IN t_mem_mosi; + reg_aduh_monitor_miso : OUT t_mem_miso; + + -- JESD io signals + jesd204b_serial_data : IN STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w*c_unb2b_board_tr_jesd204b.nof_bus)-1 downto 0); + jesd204b_refclk : IN STD_LOGIC; + jesd204b_sysref : IN STD_LOGIC; + jesd204b_sync_n : OUT STD_LOGIC_VECTOR((c_unb2b_board_tr_jesd204b.bus_w*c_unb2b_board_tr_jesd204b.nof_bus)-1 DOWNTO 0); + + -- Streaming data output + out_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0) + + ); +END node_adc_input_and_timing; + + +ARCHITECTURE str OF node_adc_input_and_timing IS + + -- Firmware version x.y + CONSTANT c_fw_version : t_unb2b_board_fw_version := (1, 1); + CONSTANT c_mm_clk_freq : NATURAL := c_unb2b_board_mm_clk_freq_100M; + CONSTANT c_lofar2_sample_clk_freq : NATURAL := 200 * 10**6; -- alternate 160MHz. TODO: Use to check PPS + + CONSTANT c_nof_streams_jesd204b : NATURAL := 12; -- IP is set up for 12 streams + CONSTANT c_nof_streams_db : NATURAL := 2; -- Streams of raw samples to record in db + + -- Waveform Generator + CONSTANT c_wg_buf_directory : STRING := "data/"; + CONSTANT c_wg_buf_dat_w : NATURAL := 18; --default value of WG that fits 14 bits of ADC data + CONSTANT c_wg_buf_addr_w : NATURAL := 10; --default value of WG for 1024 samples; + SIGNAL wg_out_ovr : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL wg_out_val : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL wg_out_data : STD_LOGIC_VECTOR(g_nof_streams*c_wg_buf_dat_w-1 DOWNTO 0); + SIGNAL wg_out_sync : STD_LOGIC_VECTOR(g_nof_streams-1 DOWNTO 0); + SIGNAL trigger_wg : STD_LOGIC; + + -- Frame parameters TBC + CONSTANT c_bs_bsn_w : NATURAL := 64; --51; + CONSTANT c_bs_block_size : NATURAL := 1024; + CONSTANT c_bs_nof_block_per_sync : NATURAL := 390625; -- generate a sync every 2s for testing + CONSTANT c_dp_shiftram_nof_samples: NATURAL := 4096; + CONSTANT c_data_w : NATURAL := 16; + CONSTANT c_dp_fifo_dc_size : NATURAL := 64; + + + -- QSFP leds + SIGNAL qsfp_green_led_arr : STD_LOGIC_VECTOR(c_unb2b_board_tr_qsfp.nof_bus-1 DOWNTO 0); + SIGNAL qsfp_red_led_arr : STD_LOGIC_VECTOR(c_unb2b_board_tr_qsfp.nof_bus-1 DOWNTO 0); + + -- JESD signals + SIGNAL rx_clk : STD_LOGIC; -- formerly jesd204b_frame_clk + SIGNAL rx_rst : STD_LOGIC; + SIGNAL rx_sysref : STD_LOGIC; + + -- Sosis and sosi arrays + SIGNAL rx_sosi_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); + SIGNAL dp_shiftram_snk_in_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); + SIGNAL ant_sosi_arr : t_dp_sosi_arr(c_nof_streams_jesd204b-1 DOWNTO 0); + SIGNAL diag_data_buf_snk_in_arr : t_dp_sosi_arr(c_nof_streams_db-1 DOWNTO 0); + SIGNAL bs_sosi : t_dp_sosi; + SIGNAL wg_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL mux_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL nxt_mux_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + SIGNAL st_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + + +BEGIN + + ----------------------------------------------------------------------------- + -- JESD204B IP (ADC Handler) + ----------------------------------------------------------------------------- + + u_jesd204b: ENTITY tech_jesd204b_lib.tech_jesd204b + GENERIC MAP( + g_sim => g_sim, + g_nof_streams => c_nof_streams_jesd204b, + g_nof_sync_n => g_nof_sync_n + ) + PORT MAP( + jesd204b_refclk => JESD204B_REFCLK, + jesd204b_sysref => JESD204B_SYSREF, + jesd204b_sync_n_arr => jesd204b_sync_n, + + rx_sosi_arr => rx_sosi_arr, + rx_clk => rx_clk, + rx_rst => rx_rst, + rx_sysref => rx_sysref, + + -- MM + mm_clk => mm_clk, + mm_rst => mm_rst, + + jesd204b_mosi => jesd204b_mosi, + jesd204b_miso => jesd204b_miso, + + -- Serial + serial_tx_arr => open, + serial_rx_arr => JESD204B_SERIAL_DATA(c_nof_streams_jesd204b-1 downto 0) + ); + + + gen_jesd_mon_in : FOR i IN 0 TO c_nof_streams_db-1 GENERATE + diag_data_buf_snk_in_arr(i).data(c_data_w-1 downto 0) <= rx_sosi_arr(i).data(c_data_w-1 downto 0); + diag_data_buf_snk_in_arr(i).valid <= rx_sosi_arr(i).valid; + diag_data_buf_snk_in_arr(i).sop <= '0'; + diag_data_buf_snk_in_arr(i).eop <= '0'; + diag_data_buf_snk_in_arr(i).err <= (OTHERS=>'0'); + END GENERATE; + + + ----------------------------------------------------------------------------- + -- Diagnostic Data Buffer (Records 8192 raw ADC samples after the PPS) + -- ToDo: Remove this JESD DB when the second (BSN) data buffer is working correctly + ----------------------------------------------------------------------------- + + u_diag_data_buffer : ENTITY diag_lib.mms_diag_data_buffer + GENERIC MAP ( + g_technology => g_technology, + g_nof_streams => c_nof_streams_db, + g_data_w => c_data_w, + g_buf_nof_data => 8192, + 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, + mm_clk => mm_clk, + dp_rst => rx_rst, + dp_clk => rx_clk, + + ram_data_buf_mosi => ram_diag_data_buf_jesd_mosi, + ram_data_buf_miso => ram_diag_data_buf_jesd_miso, + reg_data_buf_mosi => reg_diag_data_buf_jesd_mosi, + reg_data_buf_miso => reg_diag_data_buf_jesd_miso, + + in_sosi_arr => diag_data_buf_snk_in_arr, + in_sync => rx_sysref + ); + + ----------------------------------------------------------------------------- + -- 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 + ----------------------------------------------------------------------------- + + gen_force_valid : FOR I IN 0 TO c_nof_streams_jesd204b-1 GENERATE + p_sosi : PROCESS(rx_sosi_arr) + BEGIN + dp_shiftram_snk_in_arr(I) <= rx_sosi_arr(I); + dp_shiftram_snk_in_arr(I).valid <= '1'; + END PROCESS; + END GENERATE; + + + u_dp_shiftram : ENTITY dp_lib.dp_shiftram + GENERIC MAP ( + g_nof_streams => c_nof_streams_jesd204b, + g_nof_words => c_dp_shiftram_nof_samples, + g_data_w => c_data_w, + 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 + ); + + ----------------------------------------------------------------------------- + -- Timestamp + ----------------------------------------------------------------------------- + u_bsn_source : ENTITY dp_lib.mms_dp_bsn_source + GENERIC MAP ( + g_cross_clock_domain => TRUE, + g_block_size => c_bs_block_size, + g_nof_block_per_sync => c_bs_nof_block_per_sync, + g_bsn_w => c_bs_bsn_w + ) + PORT MAP ( + -- Clocks and reset + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => rx_rst, + dp_clk => rx_clk, + dp_pps => rx_sysref, + + -- Memory-mapped clock domain + reg_mosi => reg_bsn_source_mosi, + reg_miso => reg_bsn_source_miso, + + -- Streaming clock domain + bs_sosi => bs_sosi + ); + + u_bsn_trigger_wg : ENTITY dp_lib.mms_dp_bsn_scheduler + GENERIC MAP ( + g_cross_clock_domain => TRUE, + g_bsn_w => c_bs_bsn_w + ) + PORT MAP ( + -- Memory-mapped clock domain + mm_rst => mm_rst, + mm_clk => mm_clk, + + reg_mosi => reg_bsn_scheduler_wg_mosi, + reg_miso => reg_bsn_scheduler_wg_miso, + + -- Streaming clock domain + dp_rst => rx_rst, + dp_clk => rx_clk, + + snk_in => bs_sosi, -- only uses eop (= block sync), bsn[] + trigger_out => trigger_wg + ); + + + ----------------------------------------------------------------------------- + -- WG (Test Signal Generator) + ----------------------------------------------------------------------------- + + u_wg_arr : ENTITY diag_lib.mms_diag_wg_wideband_arr + GENERIC MAP ( + g_nof_streams => g_nof_streams, + g_cross_clock_domain => TRUE, + g_buf_dir => c_wg_buf_directory, + + -- Wideband parameters + g_wideband_factor => 1, + + -- Basic WG parameters, see diag_wg.vhd for their meaning + g_buf_dat_w => c_wg_buf_dat_w, + g_buf_addr_w => c_wg_buf_addr_w, + g_calc_support => TRUE, + g_calc_gain_w => 1, + g_calc_dat_w => c_wg_buf_dat_w + ) + PORT MAP ( + -- Memory-mapped clock domain + mm_rst => mm_rst, + mm_clk => mm_clk, + + reg_mosi => reg_wg_mosi, + reg_miso => reg_wg_miso, + + buf_mosi => ram_wg_mosi, + buf_miso => ram_wg_miso, + + -- Streaming clock domain + st_rst => rx_rst, + st_clk => rx_clk, + st_restart => trigger_wg, + + out_sosi_arr => wg_sosi_arr + ); + + + ----------------------------------------------------------------------------- + -- ADC/WG Mux (Input Select) + ----------------------------------------------------------------------------- + + gen_mux : FOR I IN 0 TO g_nof_streams-1 GENERATE + p_sosi : 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; + 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; + END PROCESS; + END GENERATE; + + mux_sosi_arr <= nxt_mux_sosi_arr WHEN rising_edge(rx_clk); + + ----------------------------------------------------------------------------- + -- Concatenate muxed data streams with bsn framing + ----------------------------------------------------------------------------- + + gen_concat : FOR I IN 0 TO g_nof_streams-1 GENERATE + p_sosi : PROCESS(mux_sosi_arr(I), bs_sosi) + BEGIN + st_sosi_arr(I) <= bs_sosi; + st_sosi_arr(I).data <= mux_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) + --------------------------------------------------------------------------------------- + + + --------------------------------------------------------------------------------------- + -- BSN monitor (Block Checker) + --------------------------------------------------------------------------------------- + u_bsn_monitor : ENTITY dp_lib.mms_dp_bsn_monitor + GENERIC MAP ( + g_nof_streams => 1, -- They're all the same + g_sync_timeout => g_bsn_sync_timeout, + g_bsn_w => c_bs_bsn_w, + g_log_first_bsn => FALSE + ) + PORT MAP ( + -- Memory-mapped clock domain + mm_rst => mm_rst, + mm_clk => mm_clk, + reg_mosi => reg_bsn_monitor_input_mosi, + reg_miso => reg_bsn_monitor_input_miso, + + -- Streaming clock domain + dp_rst => rx_rst, + dp_clk => rx_clk, + in_sosi_arr => st_sosi_arr(0 downto 0) + ); + + + ----------------------------------------------------------------------------- + -- Monitor ADU/WG output + ----------------------------------------------------------------------------- + u_aduh_monitor : ENTITY aduh_lib.mms_aduh_monitor_arr + GENERIC MAP ( + g_cross_clock_domain => TRUE, + g_nof_streams => g_nof_streams, + g_symbol_w => c_data_w, --TBD 16? + g_nof_symbols_per_data => 1, -- Wideband factor is 1 + g_nof_accumulations => 200000512, -- = 195313 blocks * 1024 samples + g_buffer_nof_symbols => g_aduh_buffer_nof_symbols, -- default 512, larger for full design + g_buffer_use_sync => TRUE -- True to capture all streams synchronously + ) + PORT MAP ( + -- Memory-mapped clock domain + 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_miso => reg_aduh_monitor_miso, + buf_mosi => ram_aduh_monitor_mosi, -- read and overwrite access to the signal path data buffers + buf_miso => ram_aduh_monitor_miso, + + -- Streaming clock domain + st_rst => rx_rst, + st_clk => rx_clk, + + in_sosi_arr => st_sosi_arr + ); + + + ----------------------------------------------------------------------------- +-- Diagnostic Data Buffer + ----------------------------------------------------------------------------- + + u_diag_data_buffer_bsn : ENTITY diag_lib.mms_diag_data_buffer + GENERIC MAP ( + g_technology => g_technology, + g_nof_streams => g_nof_streams, + g_data_w => c_data_w, + g_buf_nof_data => g_buf_nof_data, + 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, + mm_clk => mm_clk, + dp_rst => rx_rst, + dp_clk => rx_clk, + + ram_data_buf_mosi => ram_diag_data_buf_bsn_mosi, + ram_data_buf_miso => ram_diag_data_buf_bsn_miso, + reg_data_buf_mosi => reg_diag_data_buf_bsn_mosi, + reg_data_buf_miso => reg_diag_data_buf_bsn_miso, + + in_sosi_arr => st_sosi_arr, + in_sync => st_sosi_arr(0).sync + ); + + + ----------------------------------------------------------------------------- + -- Output Stage + -- . Thin dual clock fifo to cross from jesd frame clock (rx_clk) to dp_clk domain + ----------------------------------------------------------------------------- + + gen_dp_fifo_dc : FOR I IN 0 TO g_nof_streams-1 GENERATE + u_dp_fifo_dc : ENTITY dp_lib.dp_fifo_dc + GENERIC MAP ( + g_data_w => c_data_w, + g_use_empty => FALSE, --TRUE, + g_use_ctrl => TRUE, + g_use_sync => TRUE, + g_use_bsn => TRUE, + g_fifo_size => c_dp_fifo_dc_size + ) + PORT MAP ( + wr_rst => rx_rst, + wr_clk => rx_clk, + rd_rst => dp_rst, + rd_clk => dp_clk, + snk_in => st_sosi_arr(I), + src_out => out_sosi_arr(I) + ); + END GENERATE; + +END str;