diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_nodes.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_nodes.vhd new file mode 100644 index 0000000000000000000000000000000000000000..309e8cd4812445b26fe2f441f7b73b6699c0ae2b --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_nodes.vhd @@ -0,0 +1,753 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, unb1_board_lib, correlator_lib, filter_lib, fft_lib, rTwoSDF_lib, diag_lib, dp_lib, eth_lib, tech_tse_lib, tr_10GbE_lib, apertif_lib, wpfb_lib, bf_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 common_lib.common_field_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; +USE common_lib.common_interface_layers_pkg.ALL; +USE common_lib.common_network_total_header_pkg.ALL; +USE unb1_board_lib.unb1_board_pkg.ALL; +USE filter_lib.fil_pkg.ALL; +USE fft_lib.fft_pkg.ALL; +USE rTwoSDF_lib.rTwoSDFPkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE eth_lib.eth_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE tech_tse_lib.tb_tech_tse_pkg.ALL; +USE apertif_lib.apertif_udp_offload_pkg.ALL; +USE wpfb_lib.wpfb_pkg.ALL; +USE bf_lib.bf_pkg.ALL; +USE work.apertif_unb1_correlator_pkg.ALL; + +-- Purpose: +-- . Calculate all cross- and autocorrelations of the incoming beamlets +-- Description: +-- . The incpoming beamlets (3x 10GbE from fn_beamformer) are distributed among the 8 FPGAs per board; each FPGA correlates +-- 1/8th of the beamlets. +-- Remarks: +-- . The BG version (g_use_bg=TRUE) functionally works. +-- . The 10G-input version (no BG) needs the DDR3 transpose in fn_beamformer to be in place. +-- . fn_beamformer now outputs 176/256 beamlets but this might be increased to 192/256 (9.6Gbps) again as its 10G issue is solved. +-- . URGENT: +-- . We need 9b filter coefficients before we can synthesize including the mesh terminals! --FIXME +-- . Note: the 18b coeffieciens *do* fit and meet timing with only BG (without 10G RX stage). +-- . Other: +-- . Synthesis incl. mesh terminals went OK but used 96% of the logic resources. +-- . Keep an eye on the FIXME marks. + +ENTITY apertif_unb1_correlator_nodes IS + GENERIC ( + g_design_name : STRING := "apertif_unb1_correlator"; + g_design_note : STRING := "revision info"; + g_use_bg : BOOLEAN := FALSE; -- Overridden (TRUE) by TB but still a valid synthesis option; this replaces the 10GbE input stage with block gens. + g_sim : BOOLEAN := FALSE; -- Overridden by TB + g_sim_level : NATURAL := 0; + g_sim_fast : BOOLEAN := TRUE; -- TRUE = fast accumulator model and no inter-channel delay in the correlator output stream. + g_sim_unb_nr : NATURAL := 0; + g_sim_node_nr : NATURAL := 0; + g_stamp_date : NATURAL := 0; -- Date (YYYYMMDD) -- set by QSF + g_stamp_time : NATURAL := 0; -- Time (HHMMSS) -- set by QSF + g_stamp_svn : NATURAL := 0; -- SVN revision -- set by QSF + g_use_dumb_mesh_terminals : BOOLEAN := FALSE -- Add dumb mesh terminals to the design. Non-functional, for synthesis results only. + ); + PORT ( + -- GENERAL + CLK : IN STD_LOGIC; -- System Clock + PPS : IN STD_LOGIC; -- System Sync + WDI : OUT STD_LOGIC; -- Watchdog Clear + INTA : INOUT STD_LOGIC; -- FPGA interconnect line + INTB : INOUT STD_LOGIC; -- FPGA interconnect line + + -- Others + VERSION : IN STD_LOGIC_VECTOR(c_unb1_board_aux.version_w-1 DOWNTO 0); + ID : IN STD_LOGIC_VECTOR(c_unb1_board_aux.id_w-1 DOWNTO 0); + TESTIO : INOUT STD_LOGIC_VECTOR(c_unb1_board_aux.testio_w-1 DOWNTO 0); + + -- I2C Interface to Sensors + sens_sc : INOUT STD_LOGIC; + sens_sd : INOUT STD_LOGIC; + + -- 1GbE Control Interface + ETH_clk : IN STD_LOGIC; + ETH_SGIN : IN STD_LOGIC; + ETH_SGOUT : OUT STD_LOGIC; + + -- Transceiver clocks + SA_CLK : IN STD_LOGIC := '0'; -- SerDes Clock BN-BI / SI_FN + SB_CLK : IN STD_LOGIC := '0'; -- SerDes clock FN-BN (tr_mesh) + + -- Mesh Serial I/O + FN_BN_0_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_0_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_1_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_1_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_2_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_2_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_3_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_3_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + + -- Serial I/O: 10GbE receivers + SI_FN_0_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_0_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_1_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_1_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_2_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_2_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_3_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_3_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + + SI_FN_0_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_1_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_2_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_3_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_RSTN : OUT STD_LOGIC := '1' -- ResetN is pulled up in the Vitesse chip, but pulled down again by external 1k resistor. + -- So we need to assign a '1' to it. + ); +END apertif_unb1_correlator_nodes; + + +ARCHITECTURE str OF apertif_unb1_correlator_nodes IS + + -- Firmware version x.y + CONSTANT c_fw_version : t_unb1_board_fw_version := (0, 5); + -- Enable block generators + CONSTANT c_use_phy : t_c_unb1_board_use_phy := (1, sel_a_b(g_use_bg, 0, 1), 0, 0, 0, 0, 0, 1); + + CONSTANT c_nof_nodes : NATURAL := 8; + CONSTANT c_nof_10GbE_streams : NATURAL := 3; -- The number of 10G input streams + CONSTANT c_nof_bf_modules : NATURAL := c_bf.nof_bf_units; -- We have 4 BF modules here because each sending fn_beamformer design has 4 bf units. + CONSTANT c_compl_dat_w : NATURAL := 8; + + CONSTANT c_use_input_node : BOOLEAN := func_rev_selector(g_design_name, "c_use_input_node"); + CONSTANT c_use_mesh_node : BOOLEAN := func_rev_selector(g_design_name, "c_use_mesh_node"); + CONSTANT c_use_processing_node : BOOLEAN := func_rev_selector(g_design_name, "c_use_processing_node"); + CONSTANT c_use_bg_input : BOOLEAN := func_rev_selector(g_design_name, "c_use_bg_input"); + CONSTANT c_use_db_input : BOOLEAN := func_rev_selector(g_design_name, "c_use_db_input"); + CONSTANT c_use_bg_mesh : BOOLEAN := func_rev_selector(g_design_name, "c_use_bg_mesh"); + CONSTANT c_use_db_mesh : BOOLEAN := func_rev_selector(g_design_name, "c_use_db_mesh"); + CONSTANT c_use_interleave : BOOLEAN := func_rev_selector(g_design_name, "c_use_interleave"); + CONSTANT c_use_wpfb : BOOLEAN := func_rev_selector(g_design_name, "c_use_wpfb"); + CONSTANT c_use_repack : BOOLEAN := func_rev_selector(g_design_name, "c_use_repack"); + + CONSTANT c_mesh_data_w : NATURAL := sel_a_b(g_design_name = "apertif_unb1_correlator_mesh_ref", 16, 48); + + CONSTANT c_usr_data_w : NATURAL := 16; + CONSTANT c_bg_file_name_prefix : STRING := "hex/composite_signals"; + + -- BSN Alignern + FIFO's + CONSTANT c_block_period : NATURAL := 186; --256; --FIXME: first block size was 176/256. Now 128/186,18 (non-integer...), assuming 186 is OK. + CONSTANT c_block_size : NATURAL := 128; --176 + CONSTANT c_bsn_align_latency : NATURAL := 3; + CONSTANT c_bsn_align_sop_timeout : NATURAL := (c_bsn_align_latency + 1) * c_block_period; -- wait somewhat more than c_bsn_align_latency periods + CONSTANT c_bsn_align_xoff_timeout : NATURAL := c_bsn_align_latency * 2 * c_block_period; -- flush factor 2 longer than needed + CONSTANT c_dp_fifo_size : NATURAL := (c_bsn_align_latency + 5) * c_block_size; -- be able to fit blocks for as long as sop time out; + CONSTANT c_dp_fifo_fill : NATURAL := c_block_size; + CONSTANT c_nof_blocks_per_sync : NATURAL := 800000; + CONSTANT c_bsn_sync_time_out : NATURAL := (c_block_period * c_nof_blocks_per_sync * 10)/8; --*10/8 as margin + + -- Re- and Deinterleaver + CONSTANT c_use_complex : BOOLEAN := TRUE; + + -- Correlator + CONSTANT c_nof_visibility_streams : NATURAL := 1; + + -- System + SIGNAL cs_sim : STD_LOGIC; + SIGNAL xo_clk : STD_LOGIC; + SIGNAL xo_rst : STD_LOGIC; + SIGNAL xo_rst_n : STD_LOGIC; + SIGNAL mm_clk : STD_LOGIC; + SIGNAL mm_locked : STD_LOGIC; + SIGNAL mm_rst : STD_LOGIC; + SIGNAL cal_clk : STD_LOGIC; + SIGNAL epcs_clk : STD_LOGIC; + + SIGNAL dp_rst : STD_LOGIC; + SIGNAL dp_clk : STD_LOGIC; + SIGNAL dp_pps : STD_LOGIC; + SIGNAL sa_rst : STD_LOGIC; + + SIGNAL this_chip_id : STD_LOGIC_VECTOR(c_unb1_board_nof_chip_w-1 DOWNTO 0); -- [2:0], so range 0-3 for FN and range 4-7 BN + + -- PIOs + SIGNAL pout_wdi : STD_LOGIC; + + SIGNAL eth1g_tse_clk : STD_LOGIC; + SIGNAL eth1g_mm_rst : STD_LOGIC; + SIGNAL eth1g_reg_interrupt : STD_LOGIC; -- Interrupt + + -- MM Register interfaces + SIGNAL reg_wdi_mosi : t_mem_mosi; + SIGNAL reg_wdi_miso : t_mem_miso; + SIGNAL reg_unb_system_info_mosi : t_mem_mosi; + SIGNAL reg_unb_system_info_miso : t_mem_miso; + SIGNAL rom_unb_system_info_mosi : t_mem_mosi; + SIGNAL rom_unb_system_info_miso : t_mem_miso; + SIGNAL reg_unb_sens_mosi : t_mem_mosi; + SIGNAL reg_unb_sens_miso : t_mem_miso; + SIGNAL reg_ppsh_mosi : t_mem_mosi; + SIGNAL reg_ppsh_miso : t_mem_miso; + SIGNAL eth1g_ram_mosi : t_mem_mosi; + SIGNAL eth1g_ram_miso : t_mem_miso; + SIGNAL eth1g_reg_mosi : t_mem_mosi; + SIGNAL eth1g_reg_miso : t_mem_miso; + SIGNAL eth1g_tse_mosi : t_mem_mosi; + SIGNAL eth1g_tse_miso : t_mem_miso; + SIGNAL reg_diag_bg_input_mosi : t_mem_mosi; + SIGNAL reg_diag_bg_input_miso : t_mem_miso; + SIGNAL reg_diag_bg_mesh_mosi : t_mem_mosi; + SIGNAL reg_diag_bg_mesh_miso : t_mem_miso; + SIGNAL ram_diag_bg_mesh_mosi : t_mem_mosi; + SIGNAL ram_diag_bg_mesh_miso : t_mem_miso; + SIGNAL reg_diagnostics_mosi : t_mem_mosi; + SIGNAL reg_diagnostics_miso : t_mem_miso; + SIGNAL reg_tr_nonbonded_mosi : t_mem_mosi; + SIGNAL reg_tr_nonbonded_miso : t_mem_miso; + SIGNAL reg_diag_data_buf_input_mosi : t_mem_mosi; + SIGNAL reg_diag_data_buf_input_miso : t_mem_miso; + SIGNAL ram_diag_data_buf_input_mosi : t_mem_mosi; + SIGNAL ram_diag_data_buf_input_miso : t_mem_miso; + SIGNAL reg_diag_data_buf_mesh_mosi : t_mem_mosi; + SIGNAL reg_diag_data_buf_mesh_miso : t_mem_miso; + SIGNAL ram_diag_data_buf_mesh_mosi : t_mem_mosi; + SIGNAL ram_diag_data_buf_mesh_miso : t_mem_miso; + SIGNAL ram_fil_coefs_mosi : t_mem_mosi; + SIGNAL ram_fil_coefs_miso : t_mem_miso; + SIGNAL reg_mdio_0_mosi : t_mem_mosi; + SIGNAL reg_mdio_0_miso : t_mem_miso; + SIGNAL reg_mdio_1_mosi : t_mem_mosi; + SIGNAL reg_mdio_1_miso : t_mem_miso; + SIGNAL reg_mdio_2_mosi : t_mem_mosi; + SIGNAL reg_mdio_2_miso : t_mem_miso; + SIGNAL reg_dp_offload_rx_hdr_dat_mosi : t_mem_mosi; + SIGNAL reg_dp_offload_rx_hdr_dat_miso : t_mem_miso; + SIGNAL reg_dp_offload_tx_hdr_dat_mosi : t_mem_mosi; + SIGNAL reg_dp_offload_tx_hdr_dat_miso : t_mem_miso; + SIGNAL reg_tr_10gbe_mosi : t_mem_mosi; + SIGNAL reg_tr_10gbe_miso : t_mem_miso; + SIGNAL reg_tr_xaui_mosi : t_mem_mosi; + SIGNAL reg_tr_xaui_miso : t_mem_miso; + SIGNAL reg_bsn_monitor_mosi : t_mem_mosi; + SIGNAL reg_bsn_monitor_miso : t_mem_miso; + + SIGNAL reg_mdio_mosi_arr : t_mem_mosi_arr(c_unb1_board_nof_mdio-1 DOWNTO 0); + SIGNAL reg_mdio_miso_arr : t_mem_miso_arr(c_unb1_board_nof_mdio-1 DOWNTO 0); + + -- BSN monitors + SIGNAL dp_bsn_monitor_in_siso_arr : t_dp_siso_arr(c_nof_10GbE_streams+1+1-1 DOWNTO 0); + SIGNAL dp_bsn_monitor_in_sosi_arr : t_dp_sosi_arr(c_nof_10GbE_streams+1+1-1 DOWNTO 0); + + SIGNAL dp_offload_tx_src_out_arr : t_dp_sosi_arr(c_nof_visibility_streams-1 DOWNTO 0); + SIGNAL dp_offload_tx_src_in_arr : t_dp_siso_arr(c_nof_visibility_streams-1 DOWNTO 0); + + SIGNAL mesh_data_in_sosi_arr : t_dp_sosi_arr(c_nof_nodes-1 DOWNTO 0); + SIGNAL mesh_data_in_siso_arr : t_dp_siso_arr(c_nof_nodes-1 DOWNTO 0); + SIGNAL mesh_data_out_sosi_arr : t_dp_sosi_arr(c_nof_nodes-1 DOWNTO 0); + SIGNAL mesh_data_out_siso_arr : t_dp_siso_arr(c_nof_nodes-1 DOWNTO 0); + +BEGIN + + gen_node_input : IF c_use_input_node = TRUE GENERATE + u_input_node : ENTITY work.node_apertif_unb1_correlator_input + GENERIC MAP ( + g_sim => g_sim, --: BOOLEAN := FALSE; -- Overridden by TB + g_use_bg => c_use_bg_input, --: BOOLEAN := FALSE; -- Overridden (TRUE) by TB but still a valid synthesis option; this replaces the 10GbE input stage with block gens. + g_use_db => c_use_db_input, --: BOOLEAN := FALSE; -- Enable the databuffers when set tot TRUE. + g_use_interleave => c_use_interleave, + g_bg_file_name_prefix => c_bg_file_name_prefix, --: STRING := "hex/composite_signals"; + g_usr_data_w => c_usr_data_w, --: NATURAL := 16; -- Specifies the datawidth of Re + Im + g_nof_output_streams => c_nof_nodes --: NATURAL := 8 -- 8 Indicates the number of output streams, where each stream is targetting a unique node. + ) + PORT MAP ( + -- System + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + + -- Output array + data_src_out_arr => mesh_data_in_sosi_arr, + data_src_in_arr => mesh_data_in_siso_arr, + + -- MM + reg_diag_bg_mosi => reg_diag_bg_input_mosi, + reg_diag_bg_miso => reg_diag_bg_input_miso, + reg_tr_10GbE_mosi => reg_tr_10GbE_mosi, + reg_tr_10GbE_miso => reg_tr_10GbE_miso, + reg_tr_xaui_mosi => reg_tr_xaui_mosi, + reg_tr_xaui_miso => reg_tr_xaui_miso, + reg_mdio_mosi_arr => reg_mdio_mosi_arr, + reg_mdio_miso_arr => reg_mdio_miso_arr, + ram_diag_data_buf_mosi => ram_diag_data_buf_input_mosi, + ram_diag_data_buf_miso => ram_diag_data_buf_input_miso, + reg_diag_data_buf_mosi => reg_diag_data_buf_input_mosi, + reg_diag_data_buf_miso => reg_diag_data_buf_input_miso, + reg_dp_offload_rx_hdr_dat_mosi => reg_dp_offload_rx_hdr_dat_mosi, + reg_dp_offload_rx_hdr_dat_miso => reg_dp_offload_rx_hdr_dat_miso, + + -- Transceiver clocks + SA_CLK => SA_CLK, + + -- Serial I/O: 10GbE receivers + SI_FN_0_TX => SI_FN_0_TX, + SI_FN_0_RX => SI_FN_0_RX, + SI_FN_1_TX => SI_FN_1_TX, + SI_FN_1_RX => SI_FN_1_RX, + SI_FN_2_TX => SI_FN_2_TX, + SI_FN_2_RX => SI_FN_2_RX, + SI_FN_3_TX => SI_FN_3_TX, + SI_FN_3_RX => SI_FN_3_RX, + + SI_FN_0_CNTRL => SI_FN_0_CNTRL, + SI_FN_1_CNTRL => SI_FN_1_CNTRL, + SI_FN_2_CNTRL => SI_FN_2_CNTRL, + SI_FN_3_CNTRL => SI_FN_3_CNTRL, + SI_FN_RSTN => SI_FN_RSTN + ); + END GENERATE; + + gen_node_mesh : IF c_use_mesh_node = TRUE GENERATE + u_mesh_node : ENTITY work.node_apertif_unb1_correlator_mesh + GENERIC MAP( + g_sim => g_sim, + g_sim_level => g_sim_level, + g_sim_node_nr => g_sim_node_nr, + g_node_type => e_any, + g_use_bg => c_use_bg_mesh, + g_use_db => c_use_db_mesh, + g_nof_input_streams => c_nof_nodes, + g_nof_output_streams => c_nof_nodes, + g_use_repack => c_use_repack, + g_usr_use_complex => c_use_complex, + g_usr_data_w => c_mesh_data_w, + g_usr_frame_len => 128, + g_aux => c_unb1_board_aux + ) + PORT MAP( + -- System + chip_id => this_chip_id, + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + dp_pps => dp_pps, + tr_mesh_clk => SB_clk, + cal_clk => cal_clk, + + -- Input array + data_snk_in_arr => mesh_data_in_sosi_arr, + data_snk_out_arr => mesh_data_in_siso_arr, + + -- Output array + data_src_out_arr => mesh_data_out_sosi_arr, + data_src_in_arr => mesh_data_out_siso_arr, + + -- MM interface + reg_diag_bg_mosi => reg_diag_bg_mesh_mosi, + reg_diag_bg_miso => reg_diag_bg_mesh_miso, + reg_tr_nonbonded_mosi => reg_tr_nonbonded_mosi, + reg_tr_nonbonded_miso => reg_tr_nonbonded_miso, + reg_diagnostics_mosi => reg_diagnostics_mosi, + reg_diagnostics_miso => reg_diagnostics_miso, + reg_bsn_monitor_mosi => reg_bsn_monitor_mosi, + reg_bsn_monitor_miso => reg_bsn_monitor_miso, + ram_diag_data_buf_mosi => ram_diag_data_buf_mesh_mosi, + ram_diag_data_buf_miso => ram_diag_data_buf_mesh_miso, + reg_diag_data_buf_mosi => reg_diag_data_buf_mesh_mosi, + reg_diag_data_buf_miso => reg_diag_data_buf_mesh_miso, + + FN_BN_0_TX => FN_BN_0_TX, + FN_BN_0_RX => FN_BN_0_RX, + FN_BN_1_TX => FN_BN_1_TX, + FN_BN_1_RX => FN_BN_1_RX, + FN_BN_2_TX => FN_BN_2_TX, + FN_BN_2_RX => FN_BN_2_RX, + FN_BN_3_TX => FN_BN_3_TX, + FN_BN_3_RX => FN_BN_3_RX + ); + END GENERATE; + + gen_no_node_mesh : IF c_use_mesh_node = FALSE GENERATE + mesh_data_out_sosi_arr <= mesh_data_in_sosi_arr; + mesh_data_in_siso_arr <= mesh_data_out_siso_arr; + END GENERATE; + + gen_node_processing : IF c_use_processing_node = TRUE GENERATE + u_node_processing : ENTITY work.apertif_unb1_correlator_processing + GENERIC MAP ( + g_sim => g_sim, + g_sim_fast => g_sim_fast, + g_use_wpfb => c_use_wpfb, + g_usr_data_w => c_usr_data_w, + g_nof_input_streams => c_nof_nodes, + g_nof_output_streams => c_nof_visibility_streams + ) + PORT MAP ( + -- System + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + + ID => ID, + + -- Input array + data_snk_in_arr => mesh_data_out_sosi_arr, + data_snk_out_arr => mesh_data_out_siso_arr, + + -- Output array + data_src_out_arr => dp_offload_tx_src_out_arr, + data_src_in_arr => dp_offload_tx_src_in_arr, + + -- MM + ram_fil_coefs_mosi => ram_fil_coefs_mosi, + ram_fil_coefs_miso => ram_fil_coefs_miso, + reg_dp_offload_tx_hdr_dat_mosi => reg_dp_offload_tx_hdr_dat_mosi, + reg_dp_offload_tx_hdr_dat_miso => reg_dp_offload_tx_hdr_dat_miso + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- RX: BSN monitors at several stages in the stream + ----------------------------------------------------------------------------- +-- u_dp_bsn_monitor : ENTITY dp_lib.mms_dp_bsn_monitor +-- GENERIC MAP ( +-- g_nof_streams => 5, +-- g_sync_timeout => c_bsn_sync_time_out, +-- g_log_first_bsn => TRUE +-- ) +-- PORT MAP ( +-- mm_rst => mm_rst, +-- mm_clk => mm_clk, +-- reg_mosi => reg_bsn_monitor_mosi, +-- reg_miso => reg_bsn_monitor_miso, +-- +-- dp_rst => dp_rst, +-- dp_clk => dp_clk, +-- in_siso_arr => dp_bsn_monitor_in_siso_arr, +-- in_sosi_arr => dp_bsn_monitor_in_sosi_arr +-- ); +-- +-- -- 0) Monitor the BSN-aligned output +-- dp_bsn_monitor_in_sosi_arr(0) <= dp_bsn_align_src_out_arr(0); +-- dp_bsn_monitor_in_siso_arr(0) <= dp_bsn_align_src_in_arr(0); +-- -- 1) Monitor the rewired/reinterleaver stage output / WPFB input +-- dp_bsn_monitor_in_sosi_arr(1) <= wpfb_snk_in_arr(0); +-- dp_bsn_monitor_in_siso_arr(1) <= c_dp_siso_rdy; +-- -- 2) Monitor the WPFB output / correlator input +-- dp_bsn_monitor_in_sosi_arr(2) <= wpfb_src_out_arr(0); +-- dp_bsn_monitor_in_siso_arr(2) <= c_dp_siso_rdy; +-- -- 3) Monitor the correlator output / visibility offload input +-- dp_bsn_monitor_in_sosi_arr(3) <= correlator_src_out_arr(0); +-- dp_bsn_monitor_in_siso_arr(3) <= c_dp_siso_rdy; +-- -- 3) Monitor the correlator output / visibility offload input +-- dp_bsn_monitor_in_sosi_arr(4) <= dp_offload_tx_src_out_arr(0); +-- dp_bsn_monitor_in_siso_arr(4) <= dp_offload_tx_src_in_arr(0); + + + + ----------------------------------------------------------------------------- + -- General control function + ----------------------------------------------------------------------------- + u_ctrl : ENTITY unb1_board_lib.ctrl_unb1_board + GENERIC MAP ( + g_sim => g_sim, + g_sim_flash_model => FALSE, + g_design_name => g_design_name, + g_stamp_date => g_stamp_date, + g_stamp_time => g_stamp_time, + g_stamp_svn => g_stamp_svn, + g_fw_version => c_fw_version, + g_mm_clk_freq => c_unb1_board_mm_clk_freq_50M, + g_udp_offload => TRUE, + g_udp_offload_nof_streams => 1, + g_use_phy => c_use_phy, + g_aux => c_unb1_board_aux, + g_dp_clk_use_pll => TRUE, + g_xo_clk_use_pll => TRUE + ) + PORT MAP ( + -- Clock and reset signals + cs_sim => cs_sim, + xo_clk => xo_clk, + xo_rst => xo_rst, + xo_rst_n => xo_rst_n, + + mm_clk_out => mm_clk, + mm_clk => mm_clk, + mm_rst => mm_rst, + + mm_locked => mm_locked, + mm_locked_out => mm_locked, + + epcs_clk => epcs_clk, + epcs_clk_out => epcs_clk, + + dp_rst => dp_rst, + dp_clk => dp_clk, + dp_pps => dp_pps, + dp_rst_in => dp_rst, + dp_clk_in => dp_clk, + + cal_rec_clk => cal_clk, + + this_chip_id => this_chip_id, + + -- Toggle WDI + pout_wdi => pout_wdi, + + -- MM buses + -- . Manual WDI override + reg_wdi_mosi => reg_wdi_mosi, + reg_wdi_miso => reg_wdi_miso, + + -- . System_info + reg_unb_system_info_mosi => reg_unb_system_info_mosi, + reg_unb_system_info_miso => reg_unb_system_info_miso, + rom_unb_system_info_mosi => rom_unb_system_info_mosi, + rom_unb_system_info_miso => rom_unb_system_info_miso, + + -- . UniBoard I2C sensors + reg_unb_sens_mosi => reg_unb_sens_mosi, + reg_unb_sens_miso => reg_unb_sens_miso, + + -- . PPSH + reg_ppsh_mosi => reg_ppsh_mosi, + reg_ppsh_miso => reg_ppsh_miso, + + -- eth1g + eth1g_tse_clk_out => eth1g_tse_clk, + eth1g_tse_clk => eth1g_tse_clk, + eth1g_mm_rst => eth1g_mm_rst, + eth1g_tse_mosi => eth1g_tse_mosi, + eth1g_tse_miso => eth1g_tse_miso, + eth1g_reg_mosi => eth1g_reg_mosi, + eth1g_reg_miso => eth1g_reg_miso, + eth1g_reg_interrupt => eth1g_reg_interrupt, + eth1g_ram_mosi => eth1g_ram_mosi, + eth1g_ram_miso => eth1g_ram_miso, + + -- eth1g UDP streaming ports + udp_tx_sosi_arr => dp_offload_tx_src_out_arr, + udp_tx_siso_arr => dp_offload_tx_src_in_arr, + + -- FPGA pins + -- . General + CLK => CLK, + PPS => PPS, + WDI => WDI, + INTA => INTA, + INTB => INTB, + -- . Others + VERSION => VERSION, + ID => ID, + TESTIO => TESTIO, + -- . I2C Interface to Sensors + sens_sc => sens_sc, + sens_sd => sens_sd, + -- . 1GbE Control Interface + ETH_clk => ETH_clk, + ETH_SGIN => ETH_SGIN, + ETH_SGOUT => ETH_SGOUT + ); + + ----------------------------------------------------------------------------- + -- MM master + ----------------------------------------------------------------------------- + u_mmm_apertif_unb1_correlator : ENTITY work.mmm_apertif_unb1_correlator + GENERIC MAP( + g_sim => g_sim, + g_sim_unb_nr => g_sim_unb_nr, + g_sim_node_nr => g_sim_node_nr + ) + PORT MAP( + mm_clk => mm_clk, + mm_rst => mm_rst, + pout_wdi => pout_wdi, + reg_wdi_mosi => reg_wdi_mosi, + reg_wdi_miso => reg_wdi_miso, + reg_unb_system_info_mosi => reg_unb_system_info_mosi, + reg_unb_system_info_miso => reg_unb_system_info_miso, + rom_unb_system_info_mosi => rom_unb_system_info_mosi, + rom_unb_system_info_miso => rom_unb_system_info_miso, + reg_unb_sens_mosi => reg_unb_sens_mosi, + reg_unb_sens_miso => reg_unb_sens_miso, + reg_ppsh_mosi => reg_ppsh_mosi, + reg_ppsh_miso => reg_ppsh_miso, + eth1g_mm_rst => eth1g_mm_rst, + eth1g_reg_interrupt => eth1g_reg_interrupt, + eth1g_ram_mosi => eth1g_ram_mosi, + eth1g_ram_miso => eth1g_ram_miso, + eth1g_reg_mosi => eth1g_reg_mosi, + eth1g_reg_miso => eth1g_reg_miso, + eth1g_tse_mosi => eth1g_tse_mosi, + eth1g_tse_miso => eth1g_tse_miso, + reg_diag_bg_input_mosi => reg_diag_bg_input_mosi, + reg_diag_bg_input_miso => reg_diag_bg_input_miso, + reg_diag_bg_mesh_mosi => reg_diag_bg_mesh_mosi, + reg_diag_bg_mesh_miso => reg_diag_bg_mesh_miso, + ram_diag_bg_mesh_mosi => ram_diag_bg_mesh_mosi, + ram_diag_bg_mesh_miso => ram_diag_bg_mesh_miso, + reg_diagnostics_mosi => reg_diagnostics_mosi, + reg_diagnostics_miso => reg_diagnostics_miso, + reg_tr_nonbonded_mosi => reg_tr_nonbonded_mosi, + reg_tr_nonbonded_miso => reg_tr_nonbonded_miso, + reg_diag_data_buf_input_mosi => reg_diag_data_buf_input_mosi, + reg_diag_data_buf_input_miso => reg_diag_data_buf_input_miso, + ram_diag_data_buf_input_mosi => ram_diag_data_buf_input_mosi, + ram_diag_data_buf_input_miso => ram_diag_data_buf_input_miso, + reg_diag_data_buf_mesh_mosi => reg_diag_data_buf_mesh_mosi, + reg_diag_data_buf_mesh_miso => reg_diag_data_buf_mesh_miso, + ram_diag_data_buf_mesh_mosi => ram_diag_data_buf_mesh_mosi, + ram_diag_data_buf_mesh_miso => ram_diag_data_buf_mesh_miso, + ram_fil_coefs_mosi => ram_fil_coefs_mosi, + ram_fil_coefs_miso => ram_fil_coefs_miso, + reg_mdio_0_mosi => reg_mdio_0_mosi, + reg_mdio_0_miso => reg_mdio_0_miso, + reg_mdio_1_mosi => reg_mdio_1_mosi, + reg_mdio_1_miso => reg_mdio_1_miso, + reg_mdio_2_mosi => reg_mdio_2_mosi, + reg_mdio_2_miso => reg_mdio_2_miso, + reg_dp_offload_rx_hdr_dat_mosi => reg_dp_offload_rx_hdr_dat_mosi, + reg_dp_offload_rx_hdr_dat_miso => reg_dp_offload_rx_hdr_dat_miso, + reg_dp_offload_tx_hdr_dat_mosi => reg_dp_offload_tx_hdr_dat_mosi, + reg_dp_offload_tx_hdr_dat_miso => reg_dp_offload_tx_hdr_dat_miso, + reg_tr_10gbe_mosi => reg_tr_10gbe_mosi, + reg_tr_10gbe_miso => reg_tr_10gbe_miso, + reg_tr_xaui_mosi => reg_tr_xaui_mosi, + reg_tr_xaui_miso => reg_tr_xaui_miso, + reg_bsn_monitor_mosi => reg_bsn_monitor_mosi, + reg_bsn_monitor_miso => reg_bsn_monitor_miso + ); + + + reg_mdio_mosi_arr(0) <= reg_mdio_0_mosi; + reg_mdio_mosi_arr(1) <= reg_mdio_1_mosi; + reg_mdio_mosi_arr(2) <= reg_mdio_2_mosi; + + reg_mdio_0_miso <= reg_mdio_miso_arr(0); + reg_mdio_1_miso <= reg_mdio_miso_arr(1); + reg_mdio_2_miso <= reg_mdio_miso_arr(2); + + +-- u_mmm : ENTITY work.mmm_apertif_unb1_correlator +-- GENERIC MAP ( +-- g_sim => g_sim, +-- g_sim_unb_nr => g_sim_unb_nr, +-- g_sim_node_nr => g_sim_node_nr, +-- g_wpfb => c_wpfb, +-- g_hdr_field_arr => c_apertif_udp_offload_hdr_field_arr +-- ) +-- PORT MAP( +-- xo_clk => xo_clk, +-- xo_rst_n => xo_rst_n, +-- xo_rst => xo_rst, +-- +-- mm_rst => mm_rst, +-- mm_clk => mm_clk, +-- mm_locked => mm_locked, +-- +-- -- PIOs +-- pout_wdi => pout_wdi, +-- +-- -- Manual WDI override +-- reg_wdi_mosi => reg_wdi_mosi, +-- reg_wdi_miso => reg_wdi_miso, +-- +-- -- system_info +-- reg_unb_system_info_mosi => reg_unb_system_info_mosi, +-- reg_unb_system_info_miso => reg_unb_system_info_miso, +-- rom_unb_system_info_mosi => rom_unb_system_info_mosi, +-- rom_unb_system_info_miso => rom_unb_system_info_miso, +-- +-- -- UniBoard I2C sensors +-- reg_unb_sens_mosi => reg_unb_sens_mosi, +-- reg_unb_sens_miso => reg_unb_sens_miso, +-- +-- -- PPSH +-- reg_ppsh_mosi => reg_ppsh_mosi, +-- reg_ppsh_miso => reg_ppsh_miso, +-- +-- -- Block generator input +-- reg_diag_bg_input_mosi => reg_diag_bg_input_mosi, +-- reg_diag_bg_input_miso => reg_diag_bg_input_miso, +-- +-- -- Block generator mesh +-- reg_diag_bg_mesh_mosi => reg_diag_bg_mesh_mosi, +-- reg_diag_bg_mesh_miso => reg_diag_bg_mesh_miso, +-- ram_diag_bg_mesh_mosi => ram_diag_bg_mesh_mosi, +-- ram_diag_bg_mesh_miso => ram_diag_bg_mesh_miso, +-- +-- -- 10 GbE +-- reg_tr_10GbE_mosi => reg_tr_10GbE_mosi, +-- reg_tr_10GbE_miso => reg_tr_10GbE_miso, +-- reg_tr_xaui_mosi => reg_tr_xaui_mosi, +-- reg_tr_xaui_miso => reg_tr_xaui_miso, +-- reg_mdio_mosi_arr => reg_mdio_mosi_arr, +-- reg_mdio_miso_arr => reg_mdio_miso_arr, +-- +-- -- DP offload RX +-- reg_dp_offload_rx_hdr_dat_mosi => reg_dp_offload_rx_hdr_dat_mosi, +-- reg_dp_offload_rx_hdr_dat_miso => reg_dp_offload_rx_hdr_dat_miso, +-- +-- reg_bsn_monitor_mosi => reg_bsn_monitor_mosi, +-- reg_bsn_monitor_miso => reg_bsn_monitor_miso, +-- +-- -- . Data buffers input +-- reg_diag_data_buf_input_mosi => reg_diag_data_buf_input_mosi, +-- reg_diag_data_buf_input_miso => reg_diag_data_buf_input_miso, +-- ram_diag_data_buf_input_mosi => ram_diag_data_buf_input_mosi, +-- ram_diag_data_buf_input_miso => ram_diag_data_buf_input_miso, +-- +-- -- . Data buffers mesh +-- reg_diag_data_buf_mesh_mosi => reg_diag_data_buf_mesh_mosi, +-- reg_diag_data_buf_mesh_miso => reg_diag_data_buf_mesh_miso, +-- ram_diag_data_buf_mesh_mosi => ram_diag_data_buf_mesh_mosi, +-- ram_diag_data_buf_mesh_miso => ram_diag_data_buf_mesh_miso, +-- +-- -- 1GbE visibility offload TX +-- reg_dp_offload_tx_hdr_dat_mosi => reg_dp_offload_tx_hdr_dat_mosi, +-- reg_dp_offload_tx_hdr_dat_miso => reg_dp_offload_tx_hdr_dat_miso, +-- +-- -- Filter coefficients +-- ram_fil_coefs_mosi => ram_fil_coefs_mosi, +-- ram_fil_coefs_miso => ram_fil_coefs_miso, +-- +-- -- eth1g +-- eth1g_tse_clk => eth1g_tse_clk, +-- eth1g_mm_rst => eth1g_mm_rst, +-- eth1g_tse_mosi => eth1g_tse_mosi, +-- eth1g_tse_miso => eth1g_tse_miso, +-- eth1g_reg_mosi => eth1g_reg_mosi, +-- eth1g_reg_miso => eth1g_reg_miso, +-- eth1g_reg_interrupt => eth1g_reg_interrupt, +-- eth1g_ram_mosi => eth1g_ram_mosi, +-- eth1g_ram_miso => eth1g_ram_miso +-- ); + +END str; + diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..dda879bae269e0aa8cc436010b6722ba815a3bcd --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/apertif_unb1_correlator_pkg.vhd @@ -0,0 +1,90 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; + +PACKAGE apertif_unb1_correlator_pkg IS + + CONSTANT c_nof_revisions : NATURAL := 4; + CONSTANT c_nof_constants : NATURAL := 10; + + TYPE t_apertif_unb1_correlator_revision_matrix IS ARRAY(INTEGER RANGE 0 TO c_nof_constants-1, INTEGER RANGE 0 TO c_nof_revisions-1) OF BOOLEAN; + CONSTANT c_apertif_unb1_correlator_revision_matrix : t_apertif_unb1_correlator_revision_matrix := + (-- 0 1 2 3 + ( TRUE, TRUE, TRUE, FALSE), -- c_use_input_node + ( TRUE, TRUE, TRUE, TRUE), -- c_use_mesh_node + ( TRUE, TRUE, TRUE, FALSE), -- c_use_processing_node + ( TRUE, TRUE, TRUE, FALSE), -- c_use_bg_input + ( TRUE, TRUE, TRUE, FALSE), -- c_use_db_input + ( TRUE, TRUE, TRUE, FALSE), -- c_use_interleave + ( TRUE, TRUE, TRUE, TRUE), -- c_use_bg_mesh + ( TRUE, TRUE, TRUE, TRUE), -- c_use_db_mesh + ( TRUE, TRUE, TRUE, FALSE), -- c_use_repack + ( TRUE, TRUE, TRUE, FALSE) -- c_use_wpfb + ); + + FUNCTION func_revision_number(g_design_name : STRING) RETURN NATURAL; + FUNCTION func_constant_number(c_name : STRING) RETURN NATURAL; + FUNCTION func_rev_selector(g_design_name, c_name : STRING) RETURN BOOLEAN; + +END apertif_unb1_correlator_pkg; + +PACKAGE BODY apertif_unb1_correlator_pkg IS + + FUNCTION func_revision_number(g_design_name : STRING) RETURN NATURAL IS + BEGIN + IF g_design_name = "apertif_unb1_correlator_full" THEN RETURN 0; + ELSIF g_design_name = "apertif_unb1_correlator_lite" THEN RETURN 1; + ELSIF g_design_name = "apertif_unb1_correlator_lite_bg" THEN RETURN 2; + ELSIF g_design_name = "apertif_unb1_correlator_mesh_ref" THEN RETURN 3; + ELSE RETURN 0; + END IF; + END; + + FUNCTION func_constant_number(c_name : STRING) RETURN NATURAL IS + BEGIN + IF c_name = "c_use_input_node" THEN RETURN 0; + ELSIF c_name = "c_use_mesh_node" THEN RETURN 1; + ELSIF c_name = "c_use_processing_node" THEN RETURN 2; + ELSIF c_name = "c_use_bg_input" THEN RETURN 3; + ELSIF c_name = "c_use_db_input" THEN RETURN 4; + ELSIF c_name = "c_use_interleave" THEN RETURN 5; + ELSIF c_name = "c_use_bg_mesh" THEN RETURN 6; + ELSIF c_name = "c_use_db_mesh" THEN RETURN 7; + ELSIF c_name = "c_use_repack" THEN RETURN 8; + ELSIF c_name = "c_use_wpfb" THEN RETURN 9; + ELSE RETURN 0; + END IF; + END; + + FUNCTION func_rev_selector(g_design_name, c_name : STRING) RETURN BOOLEAN IS + VARIABLE v_rev_index : NATURAL := func_revision_number(g_design_name); + VARIABLE v_con_index : NATURAL := func_constant_number(c_name); + BEGIN + RETURN c_apertif_unb1_correlator_revision_matrix(v_con_index, v_rev_index); + END; + + +END apertif_unb1_correlator_pkg; + diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_input.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_input.vhd new file mode 100644 index 0000000000000000000000000000000000000000..79a01b30be15bd52f037db5629c94bb8841f2a59 --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_input.vhd @@ -0,0 +1,632 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, unb1_board_lib, correlator_lib, filter_lib, fft_lib, rTwoSDF_lib, diag_lib, dp_lib, eth_lib, tech_tse_lib, tr_10GbE_lib, apertif_lib, bf_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 common_lib.common_field_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; +USE common_lib.common_interface_layers_pkg.ALL; +USE common_lib.common_network_total_header_pkg.ALL; +USE unb1_board_lib.unb1_board_pkg.ALL; +USE filter_lib.fil_pkg.ALL; +USE fft_lib.fft_pkg.ALL; +USE rTwoSDF_lib.rTwoSDFPkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE eth_lib.eth_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE tech_tse_lib.tb_tech_tse_pkg.ALL; +USE apertif_lib.apertif_udp_offload_pkg.ALL; +USE bf_lib.bf_pkg.ALL; + +-- Purpose: +-- . Receive incoming beamlets via 3x10G receivers and reorder them. +-- Description: +-- . The incpoming beamlets (3x 10GbE from fn_beamformer) are received and reorderer in order to +-- distribute them among the 8 FPGAs per board; each FPGA correlates 1/8th of the beamlets. +-- Remarks: + +ENTITY node_apertif_unb1_correlator_input IS + GENERIC ( + g_sim : BOOLEAN := FALSE; -- Overridden by TB + g_use_bg : BOOLEAN := FALSE; -- Overridden (TRUE) by TB but still a valid synthesis option; this replaces the 10GbE input stage with block gens. + g_use_db : BOOLEAN := FALSE; -- Enable the databuffers when set tot TRUE. + g_use_interleave : BOOLEAN := FALSE; -- Enable the de-interleaver and concatenation + g_bg_file_name_prefix : STRING := "hex/composite_signals"; + g_usr_data_w : NATURAL := 16; -- Specifies the datawidth of Re + Im + g_nof_output_streams : NATURAL := 8 -- 8 Indicates the number of output streams, where each stream is targetting a unique node. + ); + PORT ( + -- System + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; -- 50 MHz from xo_clk PLL in SOPC system + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; -- 200 MHz from CLK system clock + + -- Output array + data_src_out_arr : OUT t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + data_src_in_arr : IN t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rst); + + -- MM + --. Block generator + reg_diag_bg_mosi : IN t_mem_mosi; + reg_diag_bg_miso : OUT t_mem_miso; + + --. 10G Receiver + reg_tr_10GbE_mosi : IN t_mem_mosi; + reg_tr_10GbE_miso : OUT t_mem_miso; + reg_tr_xaui_mosi : IN t_mem_mosi; + reg_tr_xaui_miso : OUT t_mem_miso; + reg_mdio_mosi_arr : IN t_mem_mosi_arr(c_unb1_board_nof_mdio-1 DOWNTO 0); + reg_mdio_miso_arr : OUT t_mem_miso_arr(c_unb1_board_nof_mdio-1 DOWNTO 0); + + --. Databuffer + ram_diag_data_buf_mosi : IN t_mem_mosi; + ram_diag_data_buf_miso : OUT t_mem_miso; + reg_diag_data_buf_mosi : IN t_mem_mosi; + reg_diag_data_buf_miso : OUT t_mem_miso; + + --. DP offload RX + reg_dp_offload_rx_hdr_dat_mosi : IN t_mem_mosi; + reg_dp_offload_rx_hdr_dat_miso : OUT t_mem_miso; + + -- Transceiver clocks + SA_CLK : IN STD_LOGIC; -- SerDes Clock BN-BI / SI_FN + + -- Serial I/O: 10GbE receivers + SI_FN_0_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_0_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_1_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_1_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_2_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_2_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_3_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + SI_FN_3_RX : IN STD_LOGIC_VECTOR(c_unb1_board_ci.tr.bus_w-1 DOWNTO 0); + + SI_FN_0_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_1_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_2_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_3_CNTRL : INOUT STD_LOGIC_VECTOR(c_unb1_board_ci.tr.cntrl_w-1 DOWNTO 0); + SI_FN_RSTN : OUT STD_LOGIC := '1' + ); +END node_apertif_unb1_correlator_input; + + +ARCHITECTURE str OF node_apertif_unb1_correlator_input IS + + -- General + CONSTANT c_nof_10GbE_streams : NATURAL := 3; -- The number of 10G input streams + CONSTANT c_nof_bf_modules : NATURAL := c_bf.nof_bf_units; -- We have 4 BF modules here because each sending fn_beamformer design has 4 bf units. + CONSTANT c_interleave_factor : NATURAL := 2; + CONSTANT c_nof_interleaved_streams : NATURAL := c_nof_10GbE_streams*c_nof_bf_modules; -- 12 + CONSTANT c_nof_deinterleaved_streams : NATURAL := c_interleave_factor*c_nof_interleaved_streams; -- 24 + CONSTANT c_compl_dat_w : NATURAL := g_usr_data_w/c_nof_complex; -- 16/2=8 + CONSTANT c_nof_channels : NATURAL := 64; + CONSTANT c_block_size : NATURAL := 128; + CONSTANT c_block_period : NATURAL := 186; --256; --FIXME: first block size was 176/256. Now 128/186,18 (non-integer...), assuming 186 is OK. + CONSTANT c_nof_blocks_per_sync : NATURAL := 800000; + CONSTANT c_integration_period : NATURAL := c_nof_blocks_per_sync/c_nof_channels; + + -- Block generator + CONSTANT c_bg_nof_streams : NATURAL := sel_a_b(g_use_interleave, c_nof_interleaved_streams, g_nof_output_streams); -- 12 or 8 + CONSTANT c_bg_data_w : NATURAL := g_usr_data_w; -- must be 2x6=12 or 2x8=16 + CONSTANT c_bg_block_size : NATURAL := c_block_size; + CONSTANT c_bg_gapsize : NATURAL := 0; --40 + + CONSTANT c_bg_blocks_per_sync : NATURAL := c_integration_period; + CONSTANT c_bg_ctrl : t_diag_block_gen := (sel_a_b(g_sim, '1', '0'), -- enable: On by default in simulation; MM enable required on hardware. + '0', -- enable_sync + TO_UVEC( c_bg_block_size, c_diag_bg_samples_per_packet_w), + TO_UVEC(c_bg_blocks_per_sync, c_diag_bg_blocks_per_sync_w), + TO_UVEC( c_bg_gapsize, c_diag_bg_gapsize_w), + TO_UVEC( 0, c_diag_bg_mem_low_adrs_w), + TO_UVEC( c_bg_block_size-1, c_diag_bg_mem_high_adrs_w), + TO_UVEC( 0, c_diag_bg_bsn_init_w)); + + -- BSN Alignern + FIFO's + CONSTANT c_bsn_align_latency : NATURAL := 3; + CONSTANT c_bsn_align_sop_timeout : NATURAL := (c_bsn_align_latency + 1) * c_block_period; -- wait somewhat more than c_bsn_align_latency periods + CONSTANT c_bsn_align_xoff_timeout : NATURAL := c_bsn_align_latency * 2 * c_block_period; -- flush factor 2 longer than needed + CONSTANT c_dp_fifo_size : NATURAL := (c_bsn_align_latency + 5) * c_block_size; -- be able to fit blocks for as long as sop time out; + CONSTANT c_dp_fifo_fill : NATURAL := c_block_size; + + -- Databuffer + CONSTANT c_db_nof_data_words : NATURAL := 2*c_block_size; + + -- Re- and Deinterleaver + CONSTANT c_use_complex : BOOLEAN := TRUE; + + -- System + SIGNAL sa_rst : STD_LOGIC := '0'; + + -- Block generator / datapath + SIGNAL data_sosi_arr : t_dp_sosi_arr(c_bg_nof_streams-1 DOWNTO 0); + + -- Interface: 10GbE + SIGNAL xaui_tx_arr : t_xaui_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL xaui_rx_arr : t_xaui_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL unb_xaui_tx_arr : t_unb1_board_xaui_sl_2arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL unb_xaui_rx_arr : t_unb1_board_xaui_sl_2arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL mdio_mdc_arr : STD_LOGIC_VECTOR(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL mdio_mdat_in_arr : STD_LOGIC_VECTOR(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL mdio_mdat_oen_arr : STD_LOGIC_VECTOR(c_nof_10GbE_streams-1 DOWNTO 0); + + -- DP offload RX + SIGNAL dp_offload_rx_snk_in_arr : t_dp_sosi_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL dp_offload_rx_snk_out_arr : t_dp_siso_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL dp_offload_rx_src_out_arr : t_dp_sosi_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL dp_offload_rx_src_in_arr : t_dp_siso_arr(c_nof_10GbE_streams-1 DOWNTO 0) := (OTHERS=> c_dp_siso_rdy); + SIGNAL dp_offload_rx_restored_src_out_arr : t_dp_sosi_arr(c_nof_10GbE_streams-1 DOWNTO 0) := (OTHERS=> c_dp_sosi_rst); + SIGNAL hdr_fields_out_arr : t_slv_1024_arr(c_nof_10GbE_streams-1 DOWNTO 0); + + -- BSN Aligner + SIGNAL dp_fifo_fill_src_in_arr : t_dp_siso_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL dp_fifo_fill_src_out_arr : t_dp_sosi_arr(c_nof_10GbE_streams-1 DOWNTO 0); + SIGNAL dp_bsn_align_src_in_arr : t_dp_siso_arr(c_nof_10GbE_streams-1 DOWNTO 0) := (OTHERS=> c_dp_siso_rdy); + SIGNAL dp_bsn_align_src_out_arr : t_dp_sosi_arr(c_nof_10GbE_streams-1 DOWNTO 0); + + -- De- and Reinterleaver + SIGNAL deinterleaved_arr : t_dp_sosi_arr(c_nof_deinterleaved_streams-1 DOWNTO 0); + + --Data buffers + SIGNAL diag_data_buf_snk_in_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + + -- dp_block_gen + SIGNAL dp_block_gen_src_out_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); --FIXME should be 3, not 12 + +BEGIN + + ----------------------------------------------------------------------------- + -- Block generators + ----------------------------------------------------------------------------- + gen_block_gen : IF g_use_bg = TRUE GENERATE + u_mms_diag_block_gen : ENTITY diag_lib.mms_diag_block_gen + GENERIC MAP ( + g_nof_streams => c_bg_nof_streams, + g_buf_dat_w => c_bg_data_w, + g_buf_addr_w => ceil_log2(c_bg_block_size), + g_file_name_prefix => g_bg_file_name_prefix, + g_diag_block_gen_rst => c_bg_ctrl + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + + dp_rst => dp_rst, + dp_clk => dp_clk, + + reg_bg_ctrl_mosi => reg_diag_bg_mosi, + reg_bg_ctrl_miso => reg_diag_bg_miso, + + out_sosi_arr => data_sosi_arr + ); + END GENERATE; + + gen_10GbE : IF g_use_bg = FALSE GENERATE + ----------------------------------------------------------------------------- + -- Interface : 10GbE + ----------------------------------------------------------------------------- + -- Wire together different types + gen_wires: FOR i IN 0 TO c_nof_10GbE_streams-1 GENERATE + unb_xaui_tx_arr(i) <= xaui_tx_arr(i); + xaui_rx_arr(i) <= unb_xaui_rx_arr(i); + END GENERATE; + + u_front_io : ENTITY unb1_board_lib.unb1_board_front_io + GENERIC MAP ( + g_nof_xaui => c_nof_10GbE_streams + ) + PORT MAP ( + xaui_tx_arr => unb_xaui_tx_arr, + xaui_rx_arr => unb_xaui_rx_arr, + + mdio_mdc_arr => mdio_mdc_arr, + mdio_mdat_in_arr => mdio_mdat_in_arr, + mdio_mdat_oen_arr => mdio_mdat_oen_arr, + + -- Serial I/O + SI_FN_0_TX => SI_FN_0_TX, + SI_FN_0_RX => SI_FN_0_RX, + SI_FN_1_TX => SI_FN_1_TX, + SI_FN_1_RX => SI_FN_1_RX, + SI_FN_2_TX => SI_FN_2_TX, + SI_FN_2_RX => SI_FN_2_RX, + + SI_FN_0_CNTRL => SI_FN_0_CNTRL, + SI_FN_1_CNTRL => SI_FN_1_CNTRL, + SI_FN_2_CNTRL => SI_FN_2_CNTRL, + SI_FN_3_CNTRL => SI_FN_3_CNTRL + ); + + u_areset_sa_rst : ENTITY common_lib.common_areset + GENERIC MAP( + g_rst_level => '1', + g_delay_len => 4 + ) + PORT MAP( + clk => SA_CLK, + in_rst => '0', + out_rst => sa_rst + ); + + u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE + GENERIC MAP( + g_sim => g_sim, + g_sim_level => 1, + g_nof_macs => c_nof_10GbE_streams, + g_use_mdio => TRUE + ) + + PORT MAP ( + -- Transceiver PLL reference clock + tr_ref_clk_156 => SA_CLK, + tr_ref_rst_156 => sa_rst, + + -- Calibration & reconfig clock + cal_rec_clk => mm_clk, + + -- MM interface + mm_rst => mm_rst, + mm_clk => mm_clk, + + reg_mac_mosi => reg_tr_10GbE_mosi, + reg_mac_miso => reg_tr_10GbE_miso, + + xaui_mosi => reg_tr_xaui_mosi, + xaui_miso => reg_tr_xaui_miso, + + mdio_mosi_arr => reg_mdio_mosi_arr(c_nof_10GbE_streams-1 DOWNTO 0), + mdio_miso_arr => reg_mdio_miso_arr(c_nof_10GbE_streams-1 DOWNTO 0), + + -- DP interface + dp_rst => dp_rst, + dp_clk => dp_clk, + + src_out_arr => dp_offload_rx_snk_in_arr, + src_in_arr => dp_offload_rx_snk_out_arr, + + -- Serial XAUI IO + xaui_tx_arr => xaui_tx_arr, + xaui_rx_arr => xaui_rx_arr, + + -- MDIO interface + mdio_rst => SI_FN_RSTN, + mdio_mdc_arr => mdio_mdc_arr, + mdio_mdat_in_arr => mdio_mdat_in_arr, + mdio_mdat_oen_arr => mdio_mdat_oen_arr + ); + + ----------------------------------------------------------------------------- + -- RX: dp_offload_rx + ----------------------------------------------------------------------------- + u_dp_offload_rx : ENTITY dp_lib.dp_offload_rx + GENERIC MAP ( + g_nof_streams => c_nof_10GbE_streams, + g_data_w => c_xgmii_data_w, + g_hdr_field_arr => c_apertif_udp_offload_hdr_field_arr, + g_remove_crc => FALSE, + g_crc_nof_words => 0 + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + + dp_rst => dp_rst, + dp_clk => dp_clk, + + reg_hdr_dat_mosi => reg_dp_offload_rx_hdr_dat_mosi, + reg_hdr_dat_miso => reg_dp_offload_rx_hdr_dat_miso, + + snk_in_arr => dp_offload_rx_snk_in_arr, + snk_out_arr => dp_offload_rx_snk_out_arr, + + src_out_arr => dp_offload_rx_src_out_arr, + src_in_arr => (OTHERS=>c_dp_siso_rdy), --dp_offload_rx_src_in_arr, + + hdr_fields_out_arr => hdr_fields_out_arr + ); + + gen_restore_bf_out_i : FOR i IN 0 TO c_nof_10GbE_streams-1 GENERATE + dp_offload_rx_restored_src_out_arr(i).sync <= sl(hdr_fields_out_arr(i)(field_hi(c_apertif_udp_offload_hdr_field_arr, "dp_sync") DOWNTO field_lo(c_apertif_udp_offload_hdr_field_arr, "dp_sync" ))); + dp_offload_rx_restored_src_out_arr(i).bsn <= RESIZE_UVEC(hdr_fields_out_arr(i)(field_hi(c_apertif_udp_offload_hdr_field_arr, "dp_bsn" ) DOWNTO field_lo(c_apertif_udp_offload_hdr_field_arr, "dp_bsn" )), c_dp_stream_bsn_w); + + dp_offload_rx_restored_src_out_arr(i).data <= dp_offload_rx_src_out_arr(i).data; + dp_offload_rx_restored_src_out_arr(i).valid <= dp_offload_rx_src_out_arr(i).valid; + dp_offload_rx_restored_src_out_arr(i).sop <= dp_offload_rx_src_out_arr(i).sop; + dp_offload_rx_restored_src_out_arr(i).eop <= dp_offload_rx_src_out_arr(i).eop; + dp_offload_rx_restored_src_out_arr(i).err <= dp_offload_rx_src_out_arr(i).err; + END GENERATE; + + ----------------------------------------------------------------------------- + -- Re-assign SOP and EOP + -- . We're receiving 176-word blocks (Actually the incoming blocksize doesn't matter) + -- . WPFB requires blocks of c_block_size(=128) words (2*64, interleaved) + ----------------------------------------------------------------------------- + gen_dp_block_gen : FOR I IN 0 TO c_nof_10GbE_streams-1 GENERATE + u_dp_block_gen : ENTITY dp_lib.dp_block_gen + GENERIC MAP( + g_use_src_in => FALSE, + g_nof_data => c_block_size + ) + PORT MAP( + rst => dp_rst, + clk => dp_clk, + + snk_in => dp_offload_rx_restored_src_out_arr(I), + src_out => dp_block_gen_src_out_arr(I) + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- RX: BSN alignment + ----------------------------------------------------------------------------- + gen_dp_fifo_fill: FOR i IN 0 TO c_nof_10GbE_streams-1 GENERATE + u_dp_fifo_fill : ENTITY dp_lib.dp_fifo_fill + GENERIC MAP ( + g_data_w => c_xgmii_data_w, + g_bsn_w => c_dp_stream_bsn_w, + g_channel_w => c_dp_stream_channel_w, -- FIXME: Is there really the need for the channel fields? + g_use_bsn => TRUE, + g_use_channel => TRUE, + g_use_error => TRUE, + g_use_sync => TRUE, + g_fifo_fill => c_dp_fifo_fill, + g_fifo_size => c_dp_fifo_size + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + +-- snk_out => dp_offload_rx_src_in_arr(i), + snk_in => dp_block_gen_src_out_arr(i), + + src_in => dp_fifo_fill_src_in_arr(i), + src_out => dp_fifo_fill_src_out_arr(i) + ); + END GENERATE; + + u_dp_bsn_align : ENTITY dp_lib.dp_bsn_align + GENERIC MAP ( + g_block_size => c_block_size, + g_block_period => c_block_period, --FIXME: NOT EVEN USED INTERNALLY!!! + g_nof_input => c_nof_10GbE_streams, + g_xoff_timeout => c_bsn_align_xoff_timeout, + g_sop_timeout => c_bsn_align_sop_timeout, + g_bsn_latency => c_bsn_align_latency, + g_bsn_request_pipeline => 2 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_out_arr => dp_fifo_fill_src_in_arr, + snk_in_arr => dp_fifo_fill_src_out_arr, + + src_in_arr => dp_bsn_align_src_in_arr, + src_out_arr => dp_bsn_align_src_out_arr + ); + + ----------------------------------------------------------------------------- + -- Rewire: for each input stream, extract the 4 concatenated BF output streams + -- and assign them to the interleaved array. + ----------------------------------------------------------------------------- + p_extract_bf_streams : PROCESS(dp_bsn_align_src_out_arr) + BEGIN + FOR i IN 0 TO c_nof_10GbE_streams-1 LOOP + FOR j IN 0 TO c_nof_bf_modules-1 LOOP + data_sosi_arr(i*c_nof_bf_modules + j) <= dp_bsn_align_src_out_arr(i); -- SOSI ctrl + data_sosi_arr(i*c_nof_bf_modules + j).data <= (OTHERS=>'0'); + data_sosi_arr(i*c_nof_bf_modules + j).im <= RESIZE_DP_DSP_DATA(dp_bsn_align_src_out_arr(i).data( (c_nof_complex*j+1)*c_compl_dat_w+c_compl_dat_w-1 DOWNTO c_nof_complex*j*c_compl_dat_w+c_compl_dat_w)); + data_sosi_arr(i*c_nof_bf_modules + j).re <= RESIZE_DP_DSP_DATA(dp_bsn_align_src_out_arr(i).data( (c_nof_complex*j+1)*c_compl_dat_w-1 DOWNTO c_nof_complex*j*c_compl_dat_w)); + END LOOP; + END LOOP; + END PROCESS; + END GENERATE; + + ----------------------------------------------------------------------------- + -- RX: Data buffers + ----------------------------------------------------------------------------- + gen_databuffer : IF g_use_db = TRUE GENERATE + + diag_data_buf_snk_in_arr <= data_sosi_arr; + + u_diag_data_buffer : ENTITY diag_lib.mms_diag_data_buffer + GENERIC MAP ( + g_nof_streams => c_nof_interleaved_streams, -- 12 + g_data_w => g_usr_data_w, -- 16b (complex, 2*8b) + g_buf_nof_data => c_db_nof_data_words, -- 256 + g_buf_use_sync => TRUE, + g_data_type => e_complex + ) + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + + ram_data_buf_mosi => ram_diag_data_buf_mosi, + ram_data_buf_miso => ram_diag_data_buf_miso, + reg_data_buf_mosi => reg_diag_data_buf_mosi, --FIXME address space is wrong (1 bit) + reg_data_buf_miso => reg_diag_data_buf_miso, + + in_sync => diag_data_buf_snk_in_arr(0).sync, + in_sosi_arr => diag_data_buf_snk_in_arr + ); + END GENERATE; + ----------------------------------------------------------------------------- + -- Beamlet routing from 10GbE inputs T2..T0 to unfolder correlator inputs 23..0: ***48 VISIBILITY VERSION*** + -- . Beamlet indices between parentheses () + -- . Stream indices between brackets [] + -- + -- T2(B6,B7)--[11]--deinter-[1]--(T2,B7)--[23] [23]--(T2,B7)--[1]-reinter-[11]--(T1,B7),(T2,B7)--unfold-[1]--(T2,B7)-->[23] + -- \[0]--(T2,B6)--[22] [15]--(T1,B7)--[0]/ \[0]--(T1,B7)-->[22] + -- (B4,B5)--[10]--deinter-[1]--(T2,B5)--[21] [07]--(T0,B7)--[1]-reinter-[10]--(T2,B6),(T0,B7)--unfold-[1]--(T0,B7)-->[21] + -- \[0]--(T2,B4)--[20] [22]--(T2,B6)--[0]/ \[0]--(T2,B6)-->[20] + -- (B2,B3)--[09]--deinter-[1]--(T2,B3)--[19] [14]--(T1,B6)--[1]-reinter-[09]--(T0,B6),(T1,B6)--unfold-[1]--(T1,B6)-->[19] + -- \[0]--(T2,B2)--[18] [06]--(T0,B6)--[0]/ \[0]--(T0,B6)-->[18] + -- (B0,B1)--[08]--deinter-[1]--(T2,B1)--[17] [21]--(T2,B5)--[1]-reinter-[08]--(T1,B5),(T2,B5)--unfold-[1]--(T2,B5)-->[17] + -- \[0]--(T2,B0)--[16] [13]--(T1,B5)--[0]/ \[0]--(T1,B5)-->[16] + -- T1(B6,B7)--[07]--deinter-[1]--(T1,B7)--[15] [05]--(T0,B5)--[1]-reinter-[07]--(T2,B4),(T0,B5)--unfold-[1]--(T0,B5)-->[15] + -- \[0]--(T1,B6)--[14] [20]--(T2,B4)--[0]/ \[0]--(T2,B4)-->[14] + -- (B4,B5)--[06]--deinter-[1]--(T1,B5)--[13] [12]--(T1,B4)--[1]-reinter-[06]--(T0,B4),(T1,B4)--unfold-[1]--(T1,B4)-->[13] + -- \[0]--(T1,B4)--[12]\/[04]--(T0,B4)--[0]/ \[0]--(T0,B4)-->[12] + -- (B2,B3)--[05]--deinter-[1]--(T1,B3)--[11]/\[19]--(T2,B3)--[1]-reinter-[05]--(T1,B3),(T2,B3)--unfold-[1]--(T2,B3)-->[11] + -- \[0]--(T1,B2)--[10] [11]--(T1,B3)--[0]/ \[0]--(T1,B3)-->[10] + -- (B0,B1)--[04]--deinter-[1]--(T1,B1)--[09] [03]--(T0,B3)--[1]-reinter-[04]--(T2,B2),(T0,B3)--unfold-[1]--(T0,B3)-->[09] + -- \[0]--(T1,B0)--[08] [18]--(T2,B2)--[0]/ \[0]--(T2,B2)-->[08] + -- T0(B6,B7)--[03]--deinter-[1]--(T0,B7)--[07] [10]--(T1,B2)--[1]-reinter-[03]--(T0,B2),(T1,B2)--unfold-[1]--(T1,B2)-->[07] + -- \[0]--(T0,B6)--[06] [02]--(T0,B2)--[0]/ \[0]--(T0,B2)-->[06] + -- (B4,B5)--[02]--deinter-[1]--(T0,B5)--[05] [17]--(T2,B1)--[1]-reinter-[02]--(T1,B1),(T2,B1)--unfold-[1]--(T2,B1)-->[05] + -- \[0]--(T0,B4)--[04] [09]--(T1,B1)--[0]/ \[0]--(T1,B1)-->[04] + -- (B2,B3)--[01]--deinter-[1]--(T0,B3)--[03] [01]--(T0,B1)--[1]-reinter-[01]--(T2,B0),(T0,B1)--unfold-[1]--(T0,B1)-->[03] + -- \[0]--(T0,B2)--[02] [16]--(T2,B0)--[0]/ \[0]--(T2,B0)-->[02] + -- (B0,B1)--[00]--deinter-[1]--(T0,B1)--[01] [08]--(T1,B0)--[1]-reinter-[00]--(T0,B0),(T1,B0)--unfold-[1]--(T1,B0)-->[01] + -- \[0]--(T0,B0)--[00] [00]--(T0,B0)--[0]/ \[0]--(T0,B0)-->[00] + -- ^ ^ ^ ^ ^ + -- interleaved_arr | reinterleave_in_arr | Unfolded correlator inputs + -- (data_sosi_arr) deinterleaved_arr reinterleave_out_arr,wpfb_out_arr,correlator_snk_in_arr + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Beamlet routing from 10GbE inputs T2..T0 to unfolder correlator inputs 23..0: ***FINAL MESH VERSION*** + -- . Beamlet indices between parentheses () The exact indices depend on FPGA index--FIXME + -- . Stream indices between brackets [] / To do: Also BSN align these 24 streams --FIXME + -- [<-----------/------------>] / + -- T2(B6,B7)--[11]--deinter-[1]--(T2,B7)--[23]--MESH_TX[3][2] MESH_RX[3][2]--[23]--(T23,B0)--[1]-reinter-[11]--(T22,B0),(T23,B0)--unfold-[1]--(T23,B0)-->[23] + -- \[0]--(T2,B6)--[22]--MESH_TX[3][1] MESH_RX[3][1]--[22]--(T22,B0)--[0]/ \[0]--(T22,B0)-->[22] + -- (B4,B5)--[10]--deinter-[1]--(T2,B5)--[21]--MESH_TX[3][0] MESH_RX[3][0]--[21]--(T21,B0)--[1]-reinter-[10]--(T20,B0),(T21,B0)--unfold-[1]--(T21,B0)-->[21] + -- \[0]--(T2,B4)--[20]--MESH_TX[2][2] MESH_RX[2][2]--[20]--(T10,B0)--[0]/ \[0]--(T20,B0)-->[20] + -- (B2,B3)--[09]--deinter-[1]--(T2,B3)--[19]--MESH_TX[2][1] MESH_RX[2][1]--[19]--(T19,B0)--[1]-reinter-[09]--(T18,B0),(T19,B0)--unfold-[1]--(T19,B0)-->[19] + -- \[0]--(T2,B2)--[18]--MESH_TX[2][0] MESH_RX[2][0]--[18]--(T18,B0)--[0]/ \[0]--(T18,B0)-->[18] + -- (B0,B1)--[08]--deinter-[1]--(T2,B1)--[17]--MESH_TX[1][2] MESH_RX[1][2]--[17]--(T17,B0)--[1]-reinter-[08]--(T16,B0),(T17,B0)--unfold-[1]--(T17,B0)-->[17] + -- \[0]--(T2,B0)--[16]--MESH_TX[1][1] MESH_RX[1][1]--[16]--(T16,B0)--[0]/ \[0]--(T16,B0)-->[16] + -- T1(B6,B7)--[07]--deinter-[1]--(T1,B7)--[15]--MESH_TX[1][0] MESH_RX[1][0]--[15]--(T15,B0)--[1]-reinter-[07]--(T14,B0),(T15,B0)--unfold-[1]--(T15,B0)-->[15] + -- \[0]--(T1,B6)--[14]--MESH_TX[0][2] MESH_RX[0][2]--[14]--(T14,B0)--[0]/ \[0]--(T14,B0)-->[14] + -- (B4,B5)--[06]--deinter-[1]--(T1,B5)--[13]--MESH_TX[0][1] MESH_RX[0][1]--[13]--(T13,B0)--[1]-reinter-[06]--(T12,B0),(T13,B0)--unfold-[1]--(T13,B0)-->[13] + -- \[0]--(T1,B4)--[12]--MESH_TX[0][0]\/MESH_RX[0][0]--[12]--(T12,B0)--[0]/ \[0]--(T12,B0)-->[12] + -- (B2,B3)--[05]--deinter-[1]--(T1,B3)--[11]--MESH_TX[3][2]/\MESH_RX[3][2]--[11]--(T11,B0)--[1]-reinter-[05]--(T10,B0),(T11,B0)--unfold-[1]--(T11,B0)-->[11] + -- \[0]--(T1,B2)--[10]--MESH_TX[3][1] MESH_RX[3][1]--[10]--(T10,B0)--[0]/ \[0]--(T10,B0)-->[10] + -- (B0,B1)--[04]--deinter-[1]--(T1,B1)--[09]--MESH_TX[3][0] MESH_RX[3][0]--[09]--(T09,B0)--[1]-reinter-[04]--(T08,B0),(T09,B0)--unfold-[1]--(T09,B0)-->[09] + -- \[0]--(T1,B0)--[08]--MESH_TX[2][2] MESH_RX[2][2]--[08]--(T08,B0)--[0]/ \[0]--(T08,B0)-->[08] + -- T0(B6,B7)--[03]--deinter-[1]--(T0,B7)--[07]--MESH_TX[2][1] MESH_RX[2][1]--[07]--(T07,B0)--[1]-reinter-[03]--(T06,B0),(T07,B0)--unfold-[1]--(T07,B0)-->[07] + -- \[0]--(T0,B6)--[06]--MESH_TX[2][0] MESH_RX[2][0]--[06]--(T06,B0)--[0]/ \[0]--(T06,B0)-->[06] + -- (B4,B5)--[02]--deinter-[1]--(T0,B5)--[05]--MESH_TX[1][2] MESH_RX[1][2]--[05]--(T05,B0)--[1]-reinter-[02]--(T04,B0),(T05,B0)--unfold-[1]--(T05,B0)-->[05] + -- \[0]--(T0,B4)--[04]--MESH_TX[1][1] MESH_RX[1][1]--[04]--(T04,B0)--[0]/ \[0]--(T04,B0)-->[04] + -- (B2,B3)--[01]--deinter-[1]--(T0,B3)--[03]--MESH_TX[1][0] MESH_RX[1][0]--[03]--(T03,B0)--[1]-reinter-[01]--(T02,B0),(T03,B0)--unfold-[1]--(T03,B0)-->[03] + -- \[0]--(T0,B2)--[02]--MESH_TX[0][2] MESH_RX[0][2]--[02]--(T02,B0)--[0]/ \[0]--(T02,B0)-->[02] + -- (B0,B1)--[00]--deinter-[1]--(T0,B1)--[01]--MESH_TX[0][1] MESH_RX[0][1]--[01]--(T01,B0)--[1]-reinter-[00]--(T00,B0),(T01,B0)--unfold-[1]--(T01,B0)-->[01] -- Note that we're also TX'ing the locally RX'ed telescope inputs T0..T2 as + -- \[0]--(T0,B0)--[00]--MESH_TX[0][0] MESH_RX[0][0]--[00]--(T00,B0)--[0]/ \[0]--(T00,B0)-->[00] -- it appears to be easier with the re-interleaving and BSN alignment. + -- ^ ^ ^ ^ ^ + -- interleaved_arr | mesh_tx_snk_in_2arr | Unfolded correlator inputs + -- (data_sosi_arr) deinterleaved_arr reinterleave_out_arr,wpfb_out_arr,correlator_snk_in_arr + ----------------------------------------------------------------------------- + + + ----------------------------------------------------------------------------- + -- Deinterleave the 12 interleaved streams to 24 de-interleaved streams. + ----------------------------------------------------------------------------- + gen_interleave : IF g_use_interleave = TRUE GENERATE + gen_deinterleave : FOR i IN 0 TO c_nof_interleaved_streams-1 GENERATE + u_deinterleave : ENTITY dp_lib.dp_deinterleave + GENERIC MAP ( + g_nof_out => 2, + g_block_size => 1, + g_dat_w => g_usr_data_w, -- 16b = 2x8b complex + g_use_ctrl => FALSE, + g_align_out => TRUE, + g_use_complex => c_use_complex + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_in => data_sosi_arr(i), + src_out_arr => deinterleaved_arr(2*i+1 DOWNTO 2*i) + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- Reorder the 24 de-interleaved streams. Combining the corresponding source + -- streams from the 3 input telescopes for destination node: + -- + -- OUTPUT | CONCATENATED INPUTS + -- | + -- 0 | 16 & 8 & 0 + -- 1 | 17 & 9 & 1 + -- 2 | 18 & 10 & 2 + -- 3 | 19 & 11 & 3 + -- 4 | 20 & 12 & 4 + -- 5 | 21 & 13 & 5 + -- 6 | 22 & 14 & 6 + -- 7 | 23 & 15 & 7 + ----------------------------------------------------------------------------- + p_reorder_and_concatenate_array : PROCESS(deinterleaved_arr) + BEGIN + FOR I IN 0 TO g_nof_output_streams-1 LOOP + data_src_out_arr(I) <= deinterleaved_arr(I); + FOR J IN 0 TO c_nof_10GbE_streams-1 LOOP + -- reinterleave_in_arr(I*c_nof_10GbE_streams + J) <= deinterleaved_arr(J*2*c_nof_bf_modules + I); + data_src_out_arr(I).data((J+1)*g_usr_data_w-1 DOWNTO J*g_usr_data_w) <= deinterleaved_arr(J*2*c_nof_bf_modules + I).im(c_compl_dat_w-1 DOWNTO 0) & + deinterleaved_arr(J*2*c_nof_bf_modules + I).re(c_compl_dat_w-1 DOWNTO 0); + END LOOP; + END LOOP; + END PROCESS; + END GENERATE; + + -- bypass + gen_no_interleave : IF g_use_interleave = FALSE GENERATE + gen_loop : FOR I IN 0 TO g_nof_output_streams-1 GENERATE + data_src_out_arr(I) <= data_sosi_arr(I); + END GENERATE; + END GENERATE; + +---------------------------------------------------------------------------------------------------- +-- To reduce the datapath from 48bit to 24bit we could insert a data_repack unit here at the output +---------------------------------------------------------------------------------------------------- + +-- u_st_ctrl_pipe : ENTITY dp_lib.dp_pipeline +-- GENERIC MAP( +-- g_pipeline => 3 -- 0 for wires, > 0 for registers, +-- ) +-- PORT MAP ( +-- rst => dp_rst, +-- clk => dp_clk, +-- +-- snk_in => dp_pipeline_snk_in, +-- src_out => dp_pipeline_src_out +-- ); +-- +-- p_add_st_ctrl : PROCESS(reinterleave_out_arr, dp_pipeline_src_out) +-- BEGIN +-- FOR i IN 0 TO c_nof_input_streams-1 LOOP +-- wpfb_snk_in_arr(i) <= dp_pipeline_src_out; -- SOSI ctrl +-- wpfb_snk_in_arr(i).data <= reinterleave_out_arr(i).data; +-- wpfb_snk_in_arr(i).im <= reinterleave_out_arr(i).im; +-- wpfb_snk_in_arr(i).re <= reinterleave_out_arr(i).re; +-- END LOOP; +-- END PROCESS; + +END str; + diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_mesh.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_mesh.vhd new file mode 100644 index 0000000000000000000000000000000000000000..835ca2532abf2ef16c70fe152d03aff7bb45d2ff --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_mesh.vhd @@ -0,0 +1,675 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2012 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +-- Purpose: This node takes care of the beamlet distribution using the mesh terminals. +-- For each node (FPGA) a unique distibution scheme is applied. +-- +-- Description: +-- +-- DATAPATH +-- There are two datapaths. The first datapath is the user data that enters and +-- leaves the entity via data_snk_in_arr and data_src_out. +-- The second datapath is the data that is transmitted and received via the mesh +-- terminals: tx_mesh_sosi_arr and rx_mesh_sosi_arr +-- +-- REWIRE +-- Both incoming datapaths are concatenated and fed to the reorder_rewire function: +-- +-- distr_input_sosi_arr <= rx_mesh_sosi_arr & data_snk_in_arr +-- +-- The rewire function changes the order of the incoming signals based on the +-- FPGA ID number. The reordering is different for each FPGA. +-- The output of the rewire united is then split into the data_src_out and tx_mesh_sosi_arr. +-- +-- BSN ALIGNER +-- A BSN Aligner is used to align the data that is send to the data_src_out output. A FIFO +-- is used to facilitate the aligner. +-- +-- +-- +-- +-- distr_input_sosi_arr +-- . +-- g_use_bg . distr_output_sosi_arr +-- . g_use_repack . . g_use_repack +-- . . . . . +-- +----+ +------+ . +------+ . +----+ +--------+ +------+ +-- data_snk_in_arr --->| BG +--->|REPACK|--->|REWIRE|--->|FIFO|--->|BSN |--->|REPACK|-----> data_src_out +-- +----+ +------+ | | +----+ |ALIGNER | +------+ | +-- | | +--------+ | +----+ +-- +----->| |-----+ +-->| DB | +-- tx_mesh_sosi_arr | +------+ | rx_mesh_sosi_arr +----+ +-- (tx_usr_sosi_2arr)| +----------+ |(rx_usr_sosi_2arr) . +-- +----| MESH |<--+ . +-- |TERMINALS | g_use_db +-- rx_serial_2arr ----------->| |------------> tx_serial_2arr +-- +----------+ +-- +-- +-- Remarks: +-- +-- +-- Some more remarks: + +LIBRARY IEEE, common_lib, dp_lib, unb1_board_lib, diag_lib, apertif_lib, reorder_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 dp_lib.dp_stream_pkg.ALL; +USE unb1_board_lib.unb1_board_pkg.ALL; +USE unb1_board_lib.unb1_board_peripherals_pkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE reorder_lib.reorder_pkg.ALL; + +ENTITY node_apertif_unb1_correlator_mesh IS + GENERIC( + g_sim : BOOLEAN := FALSE; + g_sim_level : NATURAL := 0; + g_sim_node_nr : NATURAL := 0; + g_node_type : t_e_unb1_board_node := e_any; -- or e_fn, or e_bn + -- User + g_use_bg : BOOLEAN := FALSE; + g_use_db : BOOLEAN := FALSE; + g_nof_input_streams : NATURAL := 8; + g_nof_output_streams : NATURAL := 8; + g_use_repack : BOOLEAN := TRUE; -- When True the in- and out-going stream is repacked and and unpacked. Set to TRUE when g_usr_data_w > 32 + g_usr_use_complex : BOOLEAN := TRUE; -- When TRUE transport sosi IM & RE fields via DP data, else transport sosi data via DP data + g_usr_data_w : NATURAL := 48; -- Specify the width of RE + IM in case g_usr_use_complex = TRUE + g_usr_frame_len : NATURAL := 128; + g_aux : t_c_unb1_board_aux := c_unb1_board_aux + ); + PORT( + -- System + chip_id : IN STD_LOGIC_VECTOR(g_aux.chip_id_w-1 DOWNTO 0); -- [2:0] + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; -- 50 MHz from xo_clk PLL in SOPC system + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; -- 200 MHz from CLK system clock + dp_pps : IN STD_LOGIC := '0'; + tr_mesh_clk : IN STD_LOGIC; -- 156.25 MHz from SB_CLK transceiver clock + cal_clk : IN STD_LOGIC; -- 40 MHz from xo_clk PLL in SOPC system + + -- Input array + data_snk_in_arr : IN t_dp_sosi_arr(g_nof_input_streams-1 DOWNTO 0); + data_snk_out_arr : OUT t_dp_siso_arr(g_nof_input_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rst); + + -- Output array + data_src_out_arr : OUT t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + data_src_in_arr : IN t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + + -- MM interface + -- . block generator + reg_diag_bg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_diag_bg_miso : OUT t_mem_miso; + ram_diag_bg_mosi : IN t_mem_mosi := c_mem_mosi_rst; + ram_diag_bg_miso : OUT t_mem_miso; + -- . tr_nonbonded + reg_tr_nonbonded_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_tr_nonbonded_miso : OUT t_mem_miso; + reg_diagnostics_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_diagnostics_miso : OUT t_mem_miso; + -- . diag_data_buffer + ram_diag_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; + ram_diag_data_buf_miso : OUT t_mem_miso; + reg_diag_data_buf_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_diag_data_buf_miso : OUT t_mem_miso; + -- . bsn_monitor + reg_bsn_monitor_mosi : IN t_mem_mosi := c_mem_mosi_rst; + reg_bsn_monitor_miso : OUT t_mem_miso; + + -- Mesh Serial I/O + FN_BN_0_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_0_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_1_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_1_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_2_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_2_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_3_TX : OUT STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0); + FN_BN_3_RX : IN STD_LOGIC_VECTOR(c_unb1_board_tr_mesh.bus_w-1 DOWNTO 0) + ); +END node_apertif_unb1_correlator_mesh; + +ARCHITECTURE str OF node_apertif_unb1_correlator_mesh IS + + CONSTANT c_sel_apertif_cor: t_sel_table := + ( + --FN0 FN1 FN2 FN3 BN0 BN1 BN2 BN3 + ( 19, 10, 13, 16, 8 , 8 , 8 , 8 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 0 + ( 10, 13, 16, 19, 11, 11, 11, 11, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 1 + ( 13, 16, 19, 10, 14, 14, 14, 14, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 2 + ( 16, 19, 10, 13, 17, 17, 17, 17, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 3 + ( 8 , 8 , 8 , 8 , 10, 19, 16, 13, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 4 + ( 11, 11, 11, 11, 13, 10, 19, 16, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 5 + ( 14, 14, 14, 14, 16, 13, 10, 19, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 6 + ( 17, 17, 17, 17, 19, 16, 13, 10, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Local processing output 7 + ( 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 0 + ( 2 , 0 , 6 , 4 , 1 , 3 , 5 , 7 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 1 + ( 9 , 12, 15, 18, 12, 15, 18, 9 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 2 + ( 3 , 3 , 3 , 3 , 2 , 2 , 2 , 2 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 3 + ( 4 , 2 , 0 , 6 , 7 , 1 , 3 , 5 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 4 + ( 12, 15, 18, 9 , 9 , 12, 15, 18, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 5 + ( 5 , 5 , 5 , 5 , 4 , 4 , 4 , 4 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 6 + ( 6 , 4 , 2 , 0 , 5 , 7 , 1 , 3 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 7 + ( 15, 18, 9 , 12, 18, 9 , 12, 15, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 8 + ( 7 , 7 , 7 , 7 , 6 , 6 , 6 , 6 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 9 + ( 0 , 6 , 4 , 2 , 3 , 5 , 7 , 1 , 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 10 + ( 18, 9 , 12, 15, 15, 18, 9 , 12, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), -- Mesh Transmit output 11 + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), + (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) + ); + + CONSTANT c_nof_nodes : NATURAL := 8; + + ----------------------------------------------------------------------------- + -- Block Generator + ----------------------------------------------------------------------------- + CONSTANT c_bg_nof_streams : NATURAL := g_nof_input_streams; + CONSTANT c_bg_dat_w : NATURAL := 16; + CONSTANT c_bg_addr_w : NATURAL := 7; + CONSTANT c_bg_file_name_prefix : STRING := "hex/node" & NATURAL'IMAGE(g_sim_node_nr) & "/bg_in_data"; + + ----------------------------------------------------------------------------- + -- Mesh Terminals + ----------------------------------------------------------------------------- + CONSTANT c_nof_bus : NATURAL := 4; -- one bus to each of the 4 nodes on the other side of the mesh + CONSTANT c_usr_data_w : NATURAL := sel_a_b(g_use_repack, 32, g_usr_data_w); + CONSTANT c_usr_nof_streams : NATURAL := 3; -- number of user streams per bus + -- Phy + CONSTANT c_phy_nof_serial : NATURAL := 3; -- up to 4 serial lanes per bus + CONSTANT c_phy_gx_mbps : NATURAL := 6250; + CONSTANT c_phy_rx_fifo_size : NATURAL := c_bram_m9k_fifo_depth; -- g_fifos=TRUE in mms_tr_nonbonded, choose to use full BRAM size = 256 for FIFO depth at output from PHY + CONSTANT c_phy_ena_reorder : BOOLEAN := TRUE; + -- Tx + CONSTANT c_use_tx : BOOLEAN := TRUE; + CONSTANT c_tx_input_use_fifo : BOOLEAN := TRUE; -- Tx input uses FIFO to create slack for inserting DP Packet and Uthernet frame headers + CONSTANT c_tx_input_fifo_size : NATURAL := c_bram_m9k_fifo_depth; -- g_tx_input_use_fifo=TRUE, choose to use full BRAM size = 256 for FIFO depth at input to uth_terminal_tx + CONSTANT c_tx_input_fifo_fill : NATURAL := 0; + -- Rx + CONSTANT c_use_rx : BOOLEAN := TRUE; + CONSTANT c_rx_output_use_fifo : BOOLEAN := TRUE; -- Rx output provides FIFOs to ensure that dp_distribute does not get blocked due to substantial backpressure on another output + CONSTANT c_rx_output_fifo_size : NATURAL := c_bram_m9k_fifo_depth; -- g_rx_output_use_fifo, choose to use full BRAM size = 256 for FIFO depth at output of uth_terminal_rx + CONSTANT c_rx_output_fifo_fill : NATURAL := 0; + CONSTANT c_rx_timeout_w : NATURAL := 0; -- when 0 then no timeout else when > 0 then flush pending rx payload after 2**g_timeout_w clk cylces of inactive uth_rx snk_in.valid + + ----------------------------------------------------------------------------- + -- Mesh Row Reorder + ----------------------------------------------------------------------------- + CONSTANT c_mesh_nof_streams : NATURAL := c_nof_bus * c_usr_nof_streams; -- 4x3=12 + + ----------------------------------------------------------------------------- + -- FIFO + ----------------------------------------------------------------------------- + CONSTANT c_packed_data_w : NATURAL := c_usr_data_w; + + ----------------------------------------------------------------------------- + -- BSN Aligner + ----------------------------------------------------------------------------- + CONSTANT c_block_size : NATURAL := g_usr_frame_len; --FIXME: current fn_beamformer output block size. + CONSTANT c_block_period : NATURAL := 192; + CONSTANT c_bsn_align_latency : NATURAL := 4; + CONSTANT c_bsn_align_xoff_timeout : NATURAL := c_bsn_align_latency * 2 * c_block_period; -- flush factor 2 longer than needed + CONSTANT c_bsn_align_sop_timeout : NATURAL := (c_bsn_align_latency + 1) * c_block_period; -- wait somewhat more than c_bsn_align_latency periods + + ----------------------------------------------------------------------------- + -- Databuffer + ----------------------------------------------------------------------------- + CONSTANT c_db_data_w : NATURAL := g_usr_data_w; -- 16 = 8b real + 8bit imaginary + CONSTANT c_db_nof_data : NATURAL := 8; + + ----------------------------------------------------------------------------- + -- BSN Monitor + ----------------------------------------------------------------------------- + CONSTANT c_nof_bsn_streams : NATURAL := 2; + + ----------------------------------------------------------------------------- + -- Reorder rewire + ----------------------------------------------------------------------------- + CONSTANT c_distr_nof_streams : NATURAL := g_nof_input_streams + c_mesh_nof_streams; + + --. Block generator + SIGNAL bg_src_in_arr : t_dp_siso_arr(g_nof_input_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL bg_src_out_arr : t_dp_sosi_arr(g_nof_input_streams-1 DOWNTO 0); + + --. Repack + SIGNAL repacked_siso_arr : t_dp_siso_arr(g_nof_input_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL repacked_sosi_arr : t_dp_sosi_arr(g_nof_input_streams-1 DOWNTO 0); + + -- 1d arrays for the mesh + SIGNAL rx_mesh_sosi_arr : t_dp_sosi_arr(c_mesh_nof_streams-1 DOWNTO 0); + SIGNAL rx_mesh_siso_arr : t_dp_siso_arr(c_mesh_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL tx_mesh_sosi_arr : t_dp_sosi_arr(c_mesh_nof_streams-1 DOWNTO 0); + SIGNAL tx_mesh_siso_arr : t_dp_siso_arr(c_mesh_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + + --. FIFO + SIGNAL fifo_snk_out_arr : t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL fifo_snk_in_arr : t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + + --. BSN Aligner + SIGNAL bsn_align_snk_in_arr : t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + SIGNAL bsn_align_snk_out_arr : t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL bsn_align_src_in_arr : t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL bsn_align_src_out_arr : t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + + --. BSN Monitor + SIGNAL bsn_sosi_arr : t_dp_sosi_arr(c_nof_bsn_streams-1 DOWNTO 0); + SIGNAL data_src_out_arr_i : t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + + --. Rewire + SIGNAL distr_input_sosi_arr : t_dp_sosi_arr(c_distr_nof_streams-1 DOWNTO 0); + SIGNAL distr_input_siso_arr : t_dp_siso_arr(c_distr_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + SIGNAL distr_output_sosi_arr : t_dp_sosi_arr(c_distr_nof_streams-1 DOWNTO 0); + SIGNAL distr_output_siso_arr : t_dp_siso_arr(c_distr_nof_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy); + + --. Mesh terminal + SIGNAL tx_serial_2arr : t_unb1_board_mesh_sl_2arr; + SIGNAL rx_serial_2arr : t_unb1_board_mesh_sl_2arr; + SIGNAL tx_usr_siso_2arr : t_unb1_board_mesh_siso_2arr; + SIGNAL tx_usr_sosi_2arr : t_unb1_board_mesh_sosi_2arr; + SIGNAL rx_usr_siso_2arr : t_unb1_board_mesh_siso_2arr; + SIGNAL rx_usr_sosi_2arr : t_unb1_board_mesh_sosi_2arr; + +BEGIN + + --------------------------------------------------------------------------------------- + -- Block Generator + --------------------------------------------------------------------------------------- + u_bg : ENTITY diag_lib.mms_diag_block_gen + GENERIC MAP( + -- Generate configurations + g_use_usr_input => NOT(g_use_bg), + g_use_bg => g_use_bg, + g_use_tx_seq => FALSE, + -- General + g_nof_streams => c_bg_nof_streams, + -- BG settings + g_use_bg_buffer_ram => TRUE, + g_buf_dat_w => c_bg_dat_w, + g_buf_addr_w => c_bg_addr_w, + g_file_name_prefix => c_bg_file_name_prefix, + -- User input multiplexer option + g_usr_bypass_xonoff => FALSE + ) + PORT MAP( + -- System + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + en_sync => dp_pps, + -- MM interface + reg_bg_ctrl_mosi => reg_diag_bg_mosi, + reg_bg_ctrl_miso => reg_diag_bg_miso, + ram_bg_data_mosi => ram_diag_bg_mosi, + ram_bg_data_miso => ram_diag_bg_miso, + + -- ST interface + usr_siso_arr => data_snk_out_arr, + usr_sosi_arr => data_snk_in_arr, + out_siso_arr => bg_src_in_arr, + out_sosi_arr => bg_src_out_arr + ); + + ----------------------------------------------------------------------------- + -- 48b -> 32b Make the data suitable for the terminals(max 32b) + ----------------------------------------------------------------------------- + gen_repack : IF g_use_repack = TRUE GENERATE + gen_repacks : FOR I IN 0 TO g_nof_input_streams-1 GENERATE + u_repack : ENTITY dp_lib.dp_repack_data + GENERIC MAP( + g_enable_repack_in => TRUE, --: BOOLEAN := TRUE; + g_enable_repack_out => TRUE, --: BOOLEAN := TRUE; + g_in_bypass => FALSE, --: BOOLEAN := FALSE; + g_in_dat_w => 48, --: NATURAL; + g_in_nof_words => 2, --: NATURAL; + g_in_symbol_w => 1, --: NATURAL := 1; -- default 1 for snk_in.empty in nof bits, else use power of 2 + g_out_bypass => FALSE, --: BOOLEAN := FALSE; + g_out_dat_w => 32, --: NATURAL; + g_out_nof_words => 3, --: NATURAL; + g_out_symbol_w => 1 --: NATURAL := 1 -- default 1 for src_out.empty in nof bits, else use power of 2 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_out => bg_src_in_arr(I), + snk_in => bg_src_out_arr(I), + + src_in => repacked_siso_arr(I), + src_out => repacked_sosi_arr(I) + ); + END GENERATE; + END GENERATE; + + --bypass + gen_no_repack : IF g_use_repack = FALSE GENERATE + repacked_sosi_arr <= bg_src_out_arr; + bg_src_in_arr <= repacked_siso_arr; + END GENERATE; + + --------------------------------------------------------------------------------------- + -- From 2d to 1d array. Receiver part of the Mesh. + --------------------------------------------------------------------------------------- + gen_i_rx : FOR I IN 0 TO c_nof_bus-1 GENERATE + gen_j_rx : FOR J IN 0 TO c_usr_nof_streams-1 GENERATE + rx_mesh_sosi_arr(I*c_usr_nof_streams + J) <= rx_usr_sosi_2arr(I)(J); + rx_usr_siso_2arr(I)(J) <= rx_mesh_siso_arr(I*c_usr_nof_streams + J); + END GENERATE; + END GENERATE; + + --------------------------------------------------------------------------------------- + -- From 1d to 2d array. Transmitter part of the Mesh. + --------------------------------------------------------------------------------------- + gen_i_tx : FOR I IN 0 TO c_nof_bus-1 GENERATE + gen_j_tx : FOR J IN 0 TO c_usr_nof_streams-1 GENERATE + + -- Create alternative mapping for hardware to have the proper order + gen_synth : IF g_sim = FALSE GENERATE + tx_usr_sosi_2arr(I)(c_usr_nof_streams-1-J)<= tx_mesh_sosi_arr(I*c_usr_nof_streams + J); + tx_mesh_siso_arr(I*c_usr_nof_streams + J) <= tx_usr_siso_2arr(I)(c_usr_nof_streams-1-J); + END GENERATE; + + -- Straight mapping in simulation + gen_sim : IF g_sim = TRUE GENERATE + tx_usr_sosi_2arr(I)(J) <= tx_mesh_sosi_arr(I*c_usr_nof_streams + J); + tx_mesh_siso_arr(I*c_usr_nof_streams + J) <= tx_usr_siso_2arr(I)(J); + END GENERATE; + + END GENERATE; + END GENERATE; + + --------------------------------------------------------------------------------------- + -- Concatenate inputs for rewire + --------------------------------------------------------------------------------------- + distr_input_sosi_arr(g_nof_input_streams-1 DOWNTO 0) <= repacked_sosi_arr; + distr_input_sosi_arr(g_nof_input_streams + c_mesh_nof_streams-1 DOWNTO g_nof_input_streams) <= rx_mesh_sosi_arr; + repacked_siso_arr <= distr_input_siso_arr(g_nof_input_streams-1 DOWNTO 0); + rx_mesh_siso_arr <= distr_input_siso_arr(g_nof_input_streams + c_mesh_nof_streams-1 DOWNTO g_nof_input_streams); + + --------------------------------------------------------------------------------------- + -- Rewire function + --------------------------------------------------------------------------------------- + u_rewire : ENTITY reorder_lib.reorder_rewire + GENERIC MAP( + g_select_table => c_sel_apertif_cor, + g_nof_configs => c_nof_nodes, + g_nof_streams => c_distr_nof_streams, + g_sel_in_w => ceil_log2(c_nof_nodes) + ) + PORT MAP( + -- System + sel_in => chip_id, + input_sosi_arr => distr_input_sosi_arr, + input_siso_arr => distr_input_siso_arr, + output_sosi_arr => distr_output_sosi_arr, + output_siso_arr => distr_output_siso_arr + ); + + --------------------------------------------------------------------------------------- + -- Extract output of rewire function to user output and terminal input + --------------------------------------------------------------------------------------- + fifo_snk_in_arr <= distr_output_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + tx_mesh_sosi_arr <= distr_output_sosi_arr(g_nof_output_streams + c_mesh_nof_streams-1 DOWNTO g_nof_output_streams); + distr_output_siso_arr(g_nof_output_streams-1 DOWNTO 0) <= fifo_snk_out_arr; + distr_output_siso_arr(g_nof_output_streams + c_mesh_nof_streams-1 DOWNTO g_nof_output_streams) <= tx_mesh_siso_arr; + + --------------------------------------------------------------------------------------- + -- Mesh Terminals + --------------------------------------------------------------------------------------- + u_mesh_terminal : ENTITY unb1_board_lib.unb1_board_terminals_mesh + GENERIC MAP( + g_sim => g_sim, + g_sim_level => g_sim_level, + -- System + g_node_type => g_node_type, + g_nof_bus => c_nof_bus, + -- User + g_usr_use_complex => g_usr_use_complex, + g_usr_data_w => c_usr_data_w, + g_usr_frame_len => g_usr_frame_len, + g_usr_nof_streams => c_usr_nof_streams, + -- Phy + g_phy_nof_serial => c_phy_nof_serial, + g_phy_gx_mbps => c_phy_gx_mbps, + g_phy_rx_fifo_size => c_phy_rx_fifo_size, + g_phy_ena_reorder => c_phy_ena_reorder, + -- Tx + g_use_tx => c_use_tx, + g_tx_input_use_fifo => c_tx_input_use_fifo, + g_tx_input_fifo_size => c_tx_input_fifo_size, + g_tx_input_fifo_fill => c_tx_input_fifo_fill, + -- Rx + g_use_rx => c_use_rx, + g_rx_output_use_fifo => c_rx_output_use_fifo, + g_rx_output_fifo_size => c_rx_output_fifo_size, + g_rx_output_fifo_fill => c_rx_output_fifo_fill, + g_rx_timeout_w => c_rx_timeout_w + ) + PORT MAP ( + chip_id => chip_id, + + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + dp_sync => dp_pps, + tr_clk => tr_mesh_clk, + cal_clk => cal_clk, + + -- User interface (4 nodes)(4 input streams) + tx_usr_siso_2arr => tx_usr_siso_2arr, + tx_usr_sosi_2arr => tx_usr_sosi_2arr, -- <== Data to the Mesh + rx_usr_siso_2arr => rx_usr_siso_2arr, + rx_usr_sosi_2arr => rx_usr_sosi_2arr, -- ==> Data from the Mesh + + -- Serial (tr_nonbonded) + tx_serial_2arr => tx_serial_2arr, + rx_serial_2arr => rx_serial_2arr, + + -- MM Control + -- . tr_nonbonded + reg_tr_nonbonded_mosi => reg_tr_nonbonded_mosi, + reg_tr_nonbonded_miso => reg_tr_nonbonded_miso, + reg_diagnostics_mosi => reg_diagnostics_mosi, + reg_diagnostics_miso => reg_diagnostics_miso, + + -- . monitor data buffer + ram_diag_data_buf_mosi => OPEN, + ram_diag_data_buf_miso => OPEN + ); + + u_unb1_board_mesh_io : ENTITY unb1_board_lib.unb1_board_mesh_io + PORT MAP ( + tx_serial_2arr => tx_serial_2arr, + rx_serial_2arr => rx_serial_2arr, + + -- Serial I/O + FN_BN_0_TX => FN_BN_0_TX, + FN_BN_0_RX => FN_BN_0_RX, + FN_BN_1_TX => FN_BN_1_TX, + FN_BN_1_RX => FN_BN_1_RX, + FN_BN_2_TX => FN_BN_2_TX, + FN_BN_2_RX => FN_BN_2_RX, + FN_BN_3_TX => FN_BN_3_TX, + FN_BN_3_RX => FN_BN_3_RX + ); + + --------------------------------------------------------------------------------------- + -- FIFOs to facilitate the BSN aligner + --------------------------------------------------------------------------------------- + gen_fifos : FOR I IN 0 TO g_nof_output_streams-1 GENERATE + u_fifo : ENTITY dp_lib.dp_fifo_sc + GENERIC MAP ( + g_data_w => c_packed_data_w, --: NATURAL := 16; -- Should be 2 times the c_complex_w if g_use_complex = TRUE + g_bsn_w => c_dp_stream_bsn_w, --: NATURAL := 1; + g_use_bsn => TRUE, --: BOOLEAN := FALSE; + g_use_sync => TRUE, --: BOOLEAN := FALSE; + g_use_ctrl => TRUE, --: BOOLEAN := TRUE; -- sop & eop + g_use_complex => g_usr_use_complex, --: BOOLEAN := FALSE; -- TRUE feeds the concatenated complex fields (im & re) through the FIFO instead of the data field. + g_fifo_size => 512 --: NATURAL := 512; -- (16+2) * 512 = 1 M9K, g_data_w+2 for sop and eop + ) + PORT MAP( + rst => dp_rst, + clk => dp_clk, + -- Monitor FIFO filling + wr_ful => OPEN, + usedw => OPEN, + rd_emp => OPEN, + -- ST sink + snk_out => fifo_snk_out_arr(I), + snk_in => fifo_snk_in_arr(I), + -- ST source + src_in => bsn_align_snk_out_arr(I), + src_out => bsn_align_snk_in_arr(I) + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- BSN ALIGNER for g_nof_output_streams streams + ----------------------------------------------------------------------------- + u_dp_bsn_align : ENTITY dp_lib.dp_bsn_align + GENERIC MAP ( + g_block_size => c_block_size, + g_block_period => c_block_period, + g_nof_input => g_nof_output_streams, + g_xoff_timeout => c_bsn_align_xoff_timeout, + g_sop_timeout => c_bsn_align_sop_timeout, + g_bsn_latency => c_bsn_align_latency, + g_bsn_request_pipeline => 2 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_out_arr => bsn_align_snk_out_arr, + snk_in_arr => bsn_align_snk_in_arr, + + src_in_arr => bsn_align_src_in_arr, + src_out_arr => bsn_align_src_out_arr + ); + + ----------------------------------------------------------------------------- + -- Unpack the data again + ----------------------------------------------------------------------------- + gen_unpack : IF g_use_repack = TRUE GENERATE + gen_unpacks : FOR I IN 0 TO g_nof_output_streams-1 GENERATE + u_unpack : ENTITY dp_lib.dp_repack_data + GENERIC MAP( + g_enable_repack_in => TRUE, --: BOOLEAN := TRUE; + g_enable_repack_out => TRUE, --: BOOLEAN := TRUE; + g_in_bypass => FALSE, --: BOOLEAN := FALSE; + g_in_dat_w => 32, --: NATURAL; + g_in_nof_words => 3, --: NATURAL; + g_in_symbol_w => 1, --: NATURAL := 1; -- default 1 for snk_in.empty in nof bits, else use power of 2 + g_out_bypass => FALSE, --: BOOLEAN := FALSE; + g_out_dat_w => 48, --: NATURAL; + g_out_nof_words => 2, --: NATURAL; + g_out_symbol_w => 1 --: NATURAL := 1 -- default 1 for src_out.empty in nof bits, else use power of 2 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_out => bsn_align_src_in_arr(I), + snk_in => bsn_align_src_out_arr(I), + + src_in => data_src_in_arr(I), + src_out => data_src_out_arr_i(I) + ); + END GENERATE; + END GENERATE; + + -- Bypass + gen_no_unpack : IF g_use_repack = FALSE GENERATE + data_src_out_arr_i <= bsn_align_src_out_arr; + END GENERATE; + + data_src_out_arr <= data_src_out_arr_i; + + ---------------------------------------------------------------------------- + -- Sink: data buffer + ---------------------------------------------------------------------------- + gen_databuffer : IF g_use_db = TRUE GENERATE + u_data_buf : ENTITY diag_lib.mms_diag_data_buffer + GENERIC MAP ( + g_nof_streams => g_nof_output_streams, + g_data_type => e_complex, + g_data_w => c_db_data_w, + g_buf_nof_data => c_db_nof_data, + g_buf_use_sync => FALSE + ) + PORT MAP ( + -- System + mm_rst => mm_rst, + mm_clk => mm_clk, + dp_rst => dp_rst, + dp_clk => dp_clk, + -- MM interface + ram_data_buf_mosi => ram_diag_data_buf_mosi, + ram_data_buf_miso => ram_diag_data_buf_miso, + reg_data_buf_mosi => reg_diag_data_buf_mosi, + reg_data_buf_miso => reg_diag_data_buf_miso, + -- ST interface + in_sync => data_src_out_arr_i(0).sync, + in_sosi_arr => data_src_out_arr_i + ); + END GENERATE; + + --------------------------------------------------------------------------------------- + -- BSN monitor + --------------------------------------------------------------------------------------- + u_bsn_monitor : ENTITY dp_lib.mms_dp_bsn_monitor + GENERIC MAP ( + g_nof_streams => c_nof_bsn_streams, -- Check one input and one output stream + g_cross_clock_domain => TRUE, + g_bsn_w => c_dp_stream_bsn_w, + g_cnt_sop_w => c_word_w, + g_cnt_valid_w => c_word_w, + g_log_first_bsn => TRUE + ) + PORT MAP ( + -- Memory-mapped clock domain + mm_rst => mm_rst, + mm_clk => mm_clk, + reg_mosi => reg_bsn_monitor_mosi, + reg_miso => reg_bsn_monitor_miso, + + -- Streaming clock domain + dp_rst => dp_rst, + dp_clk => dp_clk, + in_siso_arr => (OTHERS=>c_dp_siso_rdy), + in_sosi_arr => bsn_sosi_arr + ); + + bsn_sosi_arr(0) <= bsn_align_snk_in_arr(0); + bsn_sosi_arr(1) <= data_src_out_arr_i(0); + +END str; diff --git a/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_processing.vhd b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_processing.vhd new file mode 100644 index 0000000000000000000000000000000000000000..bf1e4e9b92769dc7c1168d1d88ce44d83238e26a --- /dev/null +++ b/applications/apertif/designs/apertif_unb1_correlator/src/vhdl/node_apertif_unb1_correlator_processing.vhd @@ -0,0 +1,559 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2014 +-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/> +-- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.nl/> +-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see <http://www.gnu.org/licenses/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib, unb1_board_lib, correlator_lib, filter_lib, fft_lib, rTwoSDF_lib, diag_lib, dp_lib, eth_lib, tech_tse_lib, tr_10GbE_lib, apertif_lib, wpfb_lib, bf_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 common_lib.common_field_pkg.ALL; +USE common_lib.common_network_layers_pkg.ALL; +USE common_lib.common_interface_layers_pkg.ALL; +USE common_lib.common_network_total_header_pkg.ALL; +USE unb1_board_lib.unb1_board_pkg.ALL; +USE filter_lib.fil_pkg.ALL; +USE fft_lib.fft_pkg.ALL; +USE rTwoSDF_lib.rTwoSDFPkg.ALL; +USE diag_lib.diag_pkg.ALL; +USE dp_lib.dp_stream_pkg.ALL; +USE eth_lib.eth_pkg.ALL; +USE tech_tse_lib.tech_tse_pkg.ALL; +USE tech_tse_lib.tb_tech_tse_pkg.ALL; +USE apertif_lib.apertif_udp_offload_pkg.ALL; +USE wpfb_lib.wpfb_pkg.ALL; +USE bf_lib.bf_pkg.ALL; + +-- Purpose: +-- . Calculate all cross- and autocorrelations of the incoming beamlets +-- Description: +-- . The incpoming beamlets (3x 10GbE from fn_beamformer) are distributed among the 8 FPGAs per board; each FPGA correlates +-- 1/8th of the beamlets. +-- Remarks: +-- . The BG version (g_use_bg=TRUE) functionally works. +-- . The 10G-input version (no BG) needs the DDR3 transpose in fn_beamformer to be in place. +-- . fn_beamformer now outputs 176/256 beamlets but this might be increased to 192/256 (9.6Gbps) again as its 10G issue is solved. +-- . URGENT: +-- . We need 9b filter coefficients before we can synthesize including the mesh terminals! --FIXME +-- . Note: the 18b coeffieciens *do* fit and meet timing with only BG (without 10G RX stage). +-- . Other: +-- . Synthesis incl. mesh terminals went OK but used 96% of the logic resources. +-- . Keep an eye on the FIXME marks. + +ENTITY apertif_unb1_correlator_processing IS + GENERIC ( + g_sim : BOOLEAN := FALSE; -- Overridden by TB + g_sim_fast : BOOLEAN := TRUE; -- TRUE = fast accumulator model and no inter-channel delay in the correlator output stream. + g_use_wpfb : BOOLEAN := TRUE; -- + g_usr_data_w : NATURAL := 16; -- Specifies the datawidth of Re + Im + g_nof_input_streams : NATURAL := 8; -- 8: Indicates the number of input streams, where each stream is coming from a unique node. + g_nof_output_streams : NATURAL := 1 -- 1: Indicates the number of 1G output streams. Currently 1. + + ); + PORT ( + -- System + mm_rst : IN STD_LOGIC; + mm_clk : IN STD_LOGIC; -- 50 MHz from xo_clk PLL in SOPC system + dp_rst : IN STD_LOGIC; + dp_clk : IN STD_LOGIC; -- 200 MHz from CLK system clock + + ID : IN STD_LOGIC_VECTOR(c_unb1_board_aux.id_w-1 DOWNTO 0); + + -- Input array + data_snk_in_arr : IN t_dp_sosi_arr(g_nof_input_streams-1 DOWNTO 0); + data_snk_out_arr : OUT t_dp_siso_arr(g_nof_input_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rst); + + -- Output array + data_src_out_arr : OUT t_dp_sosi_arr(g_nof_output_streams-1 DOWNTO 0); + data_src_in_arr : IN t_dp_siso_arr(g_nof_output_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rst); + + -- MM + --. Filterbank + ram_fil_coefs_mosi : IN t_mem_mosi; + ram_fil_coefs_miso : OUT t_mem_miso; + + --. 1GbE visibility offload TX + reg_dp_offload_tx_hdr_dat_mosi : IN t_mem_mosi; + reg_dp_offload_tx_hdr_dat_miso : OUT t_mem_miso + + ); +END apertif_unb1_correlator_processing; + + +ARCHITECTURE str OF apertif_unb1_correlator_processing IS + + -- General + CONSTANT c_nof_10GbE_streams : NATURAL := 3; -- The number of 10G input streams + CONSTANT c_nof_bf_modules : NATURAL := c_bf.nof_bf_units; -- We have 4 BF modules here because each sending fn_beamformer design has 4 bf units. + CONSTANT c_interleave_factor : NATURAL := 2; + CONSTANT c_nof_interleaved_streams : NATURAL := c_nof_10GbE_streams*c_nof_bf_modules; -- 12 + CONSTANT c_nof_deinterleaved_streams : NATURAL := c_interleave_factor*c_nof_interleaved_streams; -- 24 + CONSTANT c_compl_dat_w : NATURAL := g_usr_data_w/c_nof_complex; -- 16/2=8 + CONSTANT c_nof_blocks_per_sync : NATURAL := 800000; + + -- Re- and Deinterleaver + CONSTANT c_use_complex : BOOLEAN := TRUE; + + -- Correlator + CONSTANT c_nof_cor_inputs : NATURAL := c_nof_deinterleaved_streams; + CONSTANT c_nof_input_folds : NATURAL := 1; + CONSTANT c_nof_pre_mult_folds : NATURAL := 1; + CONSTANT c_conjugate : BOOLEAN := TRUE; --FIXME: Used for verification/validation (phase shifts) in first stages but should be set to FALSE for final version. + CONSTANT c_nof_channels : NATURAL := 64; + CONSTANT c_integration_period : NATURAL := c_nof_blocks_per_sync/c_nof_channels; --12207; + CONSTANT c_nof_visibilities : NATURAL := (c_nof_cor_inputs*(c_nof_cor_inputs+1))/2; + CONSTANT c_cor_in_dat_w : NATURAL := 9; -- 9-bit input data for the correlator: 9b -> mult -> 18b -> accu -> 32b at the corr output. + CONSTANT c_cor_out_dat_w : NATURAL := 32; -- 32-bit per accumulation register + + -- . Inter Channel Delay: + -- . With no inter channel output delay, channels are output back-to-back, creating a short full valid burst of 64 channels (12.8 Gbps burst, 158Mbps on average). + -- We need to set an appropriate number of inter-channel delay cycles for a constant visibility buffer output rate. + -- . The total accumulator output rate = (150 streams*200MHz / 12207) = 8192.021 channels/sec (157Mbps) + -- . 8192 channels/sec = 128 * 64 channels * 300 visibilities + -- . No inter channel delay: 128 * (19200 valid cycles + 1543300 invalid cycles =) 1562500 cycles/sec = 200M cycles/sec + -- . With inter channel delay: 128 * 64 channels * (300 valid cycles + 24114 invalid cycles =) 24414 cycles/sec = 199.999.488 cycles/sec (less than 200M so we're fast enough) + CONSTANT c_inter_channel_delay : NATURAL := sel_a_b(g_sim, sel_a_b(g_sim_fast, 0, 4400), 24114); -- ^^^^^--- 24414= 2*integration period. + -- 4400=~5.5x faster than 157Mbps = 860Mbps burst for sim (but still 157Mbps on average) + -- WPFB + CONSTANT c_wpfb_wb_factor : NATURAL := 1; -- = default 1, wideband factor + CONSTANT c_wpfb_nof_wb_streams : NATURAL := c_nof_interleaved_streams; -- = 1, the number of parallel wideband streams. The fi + CONSTANT c_wpfb_nof_chan : NATURAL := 1; -- = default 0, defines the number of channels (=time-m + CONSTANT c_wpfb_nof_points : NATURAL := 64; -- = 1024, N point FFT + CONSTANT c_wpfb_nof_taps : NATURAL := 8; -- = 8 nof taps n the filter + CONSTANT c_wpfb_coef_w : NATURAL := 16; --FIXME: 9b does not work; needs updated coefficient files. + CONSTANT c_wpfb_in_dat_w : NATURAL := 8; --FIXME: should be 6b at some point + CONSTANT c_wpfb_out_dat_w : NATURAL := 16; --FIXME: Could be wider but is currently 9b to avoid the need for quantization: 9b -> mult -> 18b -> accu -> 32b at the corr output. + CONSTANT c_wpfb_use_separate : BOOLEAN := FALSE; -- = false for complex input, true for two real inputs + CONSTANT c_wpfb_use_reorder : BOOLEAN := FALSE; + + CONSTANT c_wpfb : t_wpfb := (c_wpfb_wb_factor, c_wpfb_nof_points, c_wpfb_nof_chan, c_wpfb_nof_wb_streams, + c_wpfb_nof_taps, c_wpfb_in_dat_w, 16, c_wpfb_coef_w, + c_wpfb_use_reorder, c_wpfb_use_separate, 16, c_wpfb_out_dat_w, 18, 2, true, 56, 2, + c_fft_pipeline, c_fft_pipeline, c_fil_ppf_pipeline); +-- type t_wpfb is record +-- -- General parameters for the wideband poly phase filter +-- wb_factor : natural; -- = default 4, wideband factor +-- nof_points : natural; -- = 1024, N point FFT (Also the number of subbands for the filter part) +-- nof_chan : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan +-- nof_wb_streams : natural; -- = 1, the number of parallel wideband streams. The filter coefficients are shared on every wb-stream. +-- +-- -- Parameters for the poly phase filter +-- nof_taps : natural; -- = 16, the number of FIR taps per subband +-- fil_in_dat_w : natural; -- = 8, number of input bits +-- fil_out_dat_w : natural; -- = 16, number of output bits +-- coef_dat_w : natural; -- = 16, data width of the FIR coefficients +-- +-- -- Parameters for the FFT +-- use_reorder : boolean; -- = false for bit-reversed output, true for normal output +-- use_separate : boolean; -- = false for complex input, true for two real inputs +-- fft_in_dat_w : natural; -- = 16, number of input bits +-- fft_out_dat_w : natural; -- = 16, number of output bits >= (fil_in_dat_w=8) + log2(nof_points=1024)/2 = 13 +-- stage_dat_w : natural; -- = 18, number of bits that are used inter-stage +-- guard_w : natural; -- = 2 +-- guard_enable : boolean; -- = true +-- stat_data_w : positive; -- = 56 +-- stat_data_sz : positive; -- = 2 +-- +-- -- Pipeline parameters for both poly phase filter and FFT. These are heritaged from the filter and fft libraries. +-- pft_pipeline : t_fft_pipeline; -- Pipeline settings for the pipelined FFT +-- fft_pipeline : t_fft_pipeline; -- Pipeline settings for the parallel FFT +-- fil_pipeline : t_fil_ppf_pipeline; -- Pipeline settings for the filter units +-- +-- end record; + + CONSTANT c_wpfb_coefs_file_prefix : STRING := "mif/coefs_wide1_p64_t8"; + + -- De and Reinterleaver +-- SIGNAL dp_pipeline_snk_in : t_dp_sosi; +-- SIGNAL dp_pipeline_src_out : t_dp_sosi; +-- SIGNAL deinterleaved_arr : t_dp_sosi_arr(c_nof_inputs-1 DOWNTO 0); + SIGNAL reinterleave_in_arr : t_dp_sosi_arr(c_nof_cor_inputs-1 DOWNTO 0); + SIGNAL reinterleave_out_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + + -- Filterbank and Correlator + SIGNAL wpfb_snk_in_ctrl : t_dp_sosi; + SIGNAL wpfb_snk_in_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + SIGNAL wpfb_src_out_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + SIGNAL requantize_snk_in_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + SIGNAL correlator_snk_in_arr : t_dp_sosi_arr(c_nof_interleaved_streams-1 DOWNTO 0); + SIGNAL correlator_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0); + + -- 1GbE Visibility Offload + SIGNAL dp_fifo_sc_snk_in : t_dp_sosi; + SIGNAL dp_repack_data_snk_in : t_dp_sosi; + SIGNAL dp_repack_data_snk_out : t_dp_siso; + SIGNAL apertif_unb1_correlator_vis_offload_snk_in : t_dp_sosi; + SIGNAL apertif_unb1_correlator_vis_offload_snk_out : t_dp_siso; + SIGNAL dp_offload_tx_src_out_arr : t_dp_sosi_arr(1-1 DOWNTO 0); + SIGNAL dp_offload_tx_src_in_arr : t_dp_siso_arr(1-1 DOWNTO 0); + +BEGIN + + + + ----------------------------------------------------------------------------- + -- Beamlet routing from 10GbE inputs T2..T0 to unfolder correlator inputs 23..0: ***48 VISIBILITY VERSION*** + -- . Beamlet indices between parentheses () + -- . Stream indices between brackets [] + -- + -- T2(B6,B7)--[11]--deinter-[1]--(T2,B7)--[23] [23]--(T2,B7)--[1]-reinter-[11]--(T1,B7),(T2,B7)--unfold-[1]--(T2,B7)-->[23] + -- \[0]--(T2,B6)--[22] [15]--(T1,B7)--[0]/ \[0]--(T1,B7)-->[22] + -- (B4,B5)--[10]--deinter-[1]--(T2,B5)--[21] [07]--(T0,B7)--[1]-reinter-[10]--(T2,B6),(T0,B7)--unfold-[1]--(T0,B7)-->[21] + -- \[0]--(T2,B4)--[20] [22]--(T2,B6)--[0]/ \[0]--(T2,B6)-->[20] + -- (B2,B3)--[09]--deinter-[1]--(T2,B3)--[19] [14]--(T1,B6)--[1]-reinter-[09]--(T0,B6),(T1,B6)--unfold-[1]--(T1,B6)-->[19] + -- \[0]--(T2,B2)--[18] [06]--(T0,B6)--[0]/ \[0]--(T0,B6)-->[18] + -- (B0,B1)--[08]--deinter-[1]--(T2,B1)--[17] [21]--(T2,B5)--[1]-reinter-[08]--(T1,B5),(T2,B5)--unfold-[1]--(T2,B5)-->[17] + -- \[0]--(T2,B0)--[16] [13]--(T1,B5)--[0]/ \[0]--(T1,B5)-->[16] + -- T1(B6,B7)--[07]--deinter-[1]--(T1,B7)--[15] [05]--(T0,B5)--[1]-reinter-[07]--(T2,B4),(T0,B5)--unfold-[1]--(T0,B5)-->[15] + -- \[0]--(T1,B6)--[14] [20]--(T2,B4)--[0]/ \[0]--(T2,B4)-->[14] + -- (B4,B5)--[06]--deinter-[1]--(T1,B5)--[13] [12]--(T1,B4)--[1]-reinter-[06]--(T0,B4),(T1,B4)--unfold-[1]--(T1,B4)-->[13] + -- \[0]--(T1,B4)--[12]\/[04]--(T0,B4)--[0]/ \[0]--(T0,B4)-->[12] + -- (B2,B3)--[05]--deinter-[1]--(T1,B3)--[11]/\[19]--(T2,B3)--[1]-reinter-[05]--(T1,B3),(T2,B3)--unfold-[1]--(T2,B3)-->[11] + -- \[0]--(T1,B2)--[10] [11]--(T1,B3)--[0]/ \[0]--(T1,B3)-->[10] + -- (B0,B1)--[04]--deinter-[1]--(T1,B1)--[09] [03]--(T0,B3)--[1]-reinter-[04]--(T2,B2),(T0,B3)--unfold-[1]--(T0,B3)-->[09] + -- \[0]--(T1,B0)--[08] [18]--(T2,B2)--[0]/ \[0]--(T2,B2)-->[08] + -- T0(B6,B7)--[03]--deinter-[1]--(T0,B7)--[07] [10]--(T1,B2)--[1]-reinter-[03]--(T0,B2),(T1,B2)--unfold-[1]--(T1,B2)-->[07] + -- \[0]--(T0,B6)--[06] [02]--(T0,B2)--[0]/ \[0]--(T0,B2)-->[06] + -- (B4,B5)--[02]--deinter-[1]--(T0,B5)--[05] [17]--(T2,B1)--[1]-reinter-[02]--(T1,B1),(T2,B1)--unfold-[1]--(T2,B1)-->[05] + -- \[0]--(T0,B4)--[04] [09]--(T1,B1)--[0]/ \[0]--(T1,B1)-->[04] + -- (B2,B3)--[01]--deinter-[1]--(T0,B3)--[03] [01]--(T0,B1)--[1]-reinter-[01]--(T2,B0),(T0,B1)--unfold-[1]--(T0,B1)-->[03] + -- \[0]--(T0,B2)--[02] [16]--(T2,B0)--[0]/ \[0]--(T2,B0)-->[02] + -- (B0,B1)--[00]--deinter-[1]--(T0,B1)--[01] [08]--(T1,B0)--[1]-reinter-[00]--(T0,B0),(T1,B0)--unfold-[1]--(T1,B0)-->[01] + -- \[0]--(T0,B0)--[00] [00]--(T0,B0)--[0]/ \[0]--(T0,B0)-->[00] + -- ^ ^ ^ ^ ^ + -- interleaved_arr | reinterleave_in_arr | Unfolded correlator inputs + -- deinterleaved_arr reinterleave_out_arr,wpfb_out_arr,correlator_snk_in_arr + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Beamlet routing from 10GbE inputs T2..T0 to unfolder correlator inputs 23..0: ***FINAL MESH VERSION*** + -- . Beamlet indices between parentheses () The exact indices depend on FPGA index--FIXME + -- . Stream indices between brackets [] / To do: Also BSN align these 24 streams --FIXME + -- [<-----------/------------>] / + -- T2(B6,B7)--[11]--deinter-[1]--(T2,B7)--[23]--MESH_TX[3][2] MESH_RX[3][2]--[23]--(T23,B0)--[1]-reinter-[11]--(T22,B0),(T23,B0)--unfold-[1]--(T23,B0)-->[23] + -- \[0]--(T2,B6)--[22]--MESH_TX[3][1] MESH_RX[3][1]--[22]--(T22,B0)--[0]/ \[0]--(T22,B0)-->[22] + -- (B4,B5)--[10]--deinter-[1]--(T2,B5)--[21]--MESH_TX[3][0] MESH_RX[3][0]--[21]--(T21,B0)--[1]-reinter-[10]--(T20,B0),(T21,B0)--unfold-[1]--(T21,B0)-->[21] + -- \[0]--(T2,B4)--[20]--MESH_TX[2][2] MESH_RX[2][2]--[20]--(T10,B0)--[0]/ \[0]--(T20,B0)-->[20] + -- (B2,B3)--[09]--deinter-[1]--(T2,B3)--[19]--MESH_TX[2][1] MESH_RX[2][1]--[19]--(T19,B0)--[1]-reinter-[09]--(T18,B0),(T19,B0)--unfold-[1]--(T19,B0)-->[19] + -- \[0]--(T2,B2)--[18]--MESH_TX[2][0] MESH_RX[2][0]--[18]--(T18,B0)--[0]/ \[0]--(T18,B0)-->[18] + -- (B0,B1)--[08]--deinter-[1]--(T2,B1)--[17]--MESH_TX[1][2] MESH_RX[1][2]--[17]--(T17,B0)--[1]-reinter-[08]--(T16,B0),(T17,B0)--unfold-[1]--(T17,B0)-->[17] + -- \[0]--(T2,B0)--[16]--MESH_TX[1][1] MESH_RX[1][1]--[16]--(T16,B0)--[0]/ \[0]--(T16,B0)-->[16] + -- T1(B6,B7)--[07]--deinter-[1]--(T1,B7)--[15]--MESH_TX[1][0] MESH_RX[1][0]--[15]--(T15,B0)--[1]-reinter-[07]--(T14,B0),(T15,B0)--unfold-[1]--(T15,B0)-->[15] + -- \[0]--(T1,B6)--[14]--MESH_TX[0][2] MESH_RX[0][2]--[14]--(T14,B0)--[0]/ \[0]--(T14,B0)-->[14] + -- (B4,B5)--[06]--deinter-[1]--(T1,B5)--[13]--MESH_TX[0][1] MESH_RX[0][1]--[13]--(T13,B0)--[1]-reinter-[06]--(T12,B0),(T13,B0)--unfold-[1]--(T13,B0)-->[13] + -- \[0]--(T1,B4)--[12]--MESH_TX[0][0]\/MESH_RX[0][0]--[12]--(T12,B0)--[0]/ \[0]--(T12,B0)-->[12] + -- (B2,B3)--[05]--deinter-[1]--(T1,B3)--[11]--MESH_TX[3][2]/\MESH_RX[3][2]--[11]--(T11,B0)--[1]-reinter-[05]--(T10,B0),(T11,B0)--unfold-[1]--(T11,B0)-->[11] + -- \[0]--(T1,B2)--[10]--MESH_TX[3][1] MESH_RX[3][1]--[10]--(T10,B0)--[0]/ \[0]--(T10,B0)-->[10] + -- (B0,B1)--[04]--deinter-[1]--(T1,B1)--[09]--MESH_TX[3][0] MESH_RX[3][0]--[09]--(T09,B0)--[1]-reinter-[04]--(T08,B0),(T09,B0)--unfold-[1]--(T09,B0)-->[09] + -- \[0]--(T1,B0)--[08]--MESH_TX[2][2] MESH_RX[2][2]--[08]--(T08,B0)--[0]/ \[0]--(T08,B0)-->[08] + -- T0(B6,B7)--[03]--deinter-[1]--(T0,B7)--[07]--MESH_TX[2][1] MESH_RX[2][1]--[07]--(T07,B0)--[1]-reinter-[03]--(T06,B0),(T07,B0)--unfold-[1]--(T07,B0)-->[07] + -- \[0]--(T0,B6)--[06]--MESH_TX[2][0] MESH_RX[2][0]--[06]--(T06,B0)--[0]/ \[0]--(T06,B0)-->[06] + -- (B4,B5)--[02]--deinter-[1]--(T0,B5)--[05]--MESH_TX[1][2] MESH_RX[1][2]--[05]--(T05,B0)--[1]-reinter-[02]--(T04,B0),(T05,B0)--unfold-[1]--(T05,B0)-->[05] + -- \[0]--(T0,B4)--[04]--MESH_TX[1][1] MESH_RX[1][1]--[04]--(T04,B0)--[0]/ \[0]--(T04,B0)-->[04] + -- (B2,B3)--[01]--deinter-[1]--(T0,B3)--[03]--MESH_TX[1][0] MESH_RX[1][0]--[03]--(T03,B0)--[1]-reinter-[01]--(T02,B0),(T03,B0)--unfold-[1]--(T03,B0)-->[03] + -- \[0]--(T0,B2)--[02]--MESH_TX[0][2] MESH_RX[0][2]--[02]--(T02,B0)--[0]/ \[0]--(T02,B0)-->[02] + -- (B0,B1)--[00]--deinter-[1]--(T0,B1)--[01]--MESH_TX[0][1] MESH_RX[0][1]--[01]--(T01,B0)--[1]-reinter-[00]--(T00,B0),(T01,B0)--unfold-[1]--(T01,B0)-->[01] -- Note that we're also TX'ing the locally RX'ed telescope inputs T0..T2 as + -- \[0]--(T0,B0)--[00]--MESH_TX[0][0] MESH_RX[0][0]--[00]--(T00,B0)--[0]/ \[0]--(T00,B0)-->[00] -- it appears to be easier with the re-interleaving and BSN alignment. + -- ^ ^ ^ ^ ^ + -- interleaved_arr | mesh_tx_snk_in_2arr | Unfolded correlator inputs + -- deinterleaved_arr reinterleave_out_arr,wpfb_out_arr,correlator_snk_in_arr + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + -- Unconcatenate(or split) the 8 input streams to 24 streams. + -- + -- INPUT CONCATENATED INPUTS + -- + -- 0 --> split to unconcatenate 0, 1 and 2 + -- 1 --> split to unconcatenate 3, 4 and 5 + -- 2 --> split to unconcatenate 6, 7 and 8 + -- 3 --> split to unconcatenate 9, 10 and 11 + -- 4 --> split to unconcatenate 12, 13 and 14 + -- 5 --> split to unconcatenate 15, 16 and 17 + -- 6 --> split to unconcatenate 18, 19 and 20 + -- 7 --> split to unconcatenate 21, 22 and 23 + ----------------------------------------------------------------------------- + p_unconcatenate_array : PROCESS(data_snk_in_arr) + BEGIN + FOR I IN 0 TO g_nof_input_streams-1 LOOP + FOR J IN 0 TO c_nof_10GbE_streams-1 LOOP + reinterleave_in_arr(I*c_nof_10GbE_streams + J) <= data_snk_in_arr(I); + reinterleave_in_arr(I*c_nof_10GbE_streams + J).re <= RESIZE_DP_DSP_DATA(data_snk_in_arr(I).data(J*g_usr_data_w + c_compl_dat_w-1 DOWNTO J*g_usr_data_w)); + reinterleave_in_arr(I*c_nof_10GbE_streams + J).im <= RESIZE_DP_DSP_DATA(data_snk_in_arr(I).data((J+1)*g_usr_data_w-1 DOWNTO J*g_usr_data_w + c_compl_dat_w)); + END LOOP; + END LOOP; + END PROCESS; + + ----------------------------------------------------------------------------- + -- Reinterleave the 24 streams to 12 interleaved streams for the WPFB + ----------------------------------------------------------------------------- + gen_reinterleave : FOR I IN 0 TO c_nof_interleaved_streams-1 GENERATE + u_reinterleave : ENTITY dp_lib.dp_reinterleave + GENERIC MAP ( + g_nof_in => c_interleave_factor, + g_deint_block_size => 1, + g_nof_out => 1, + g_inter_block_size => 1, + g_use_ctrl => FALSE, + g_dat_w => g_usr_data_w, + g_use_complex => c_use_complex, + g_align_out => TRUE + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + snk_in_arr => reinterleave_in_arr(c_interleave_factor*I+1 DOWNTO c_interleave_factor*I), + src_out_arr => reinterleave_out_arr(I DOWNTO I) + ); + END GENERATE; + + p_add_st_ctrl : PROCESS(reinterleave_out_arr) + BEGIN + FOR I IN 0 TO c_nof_interleaved_streams-1 LOOP + wpfb_snk_in_arr(I) <= reinterleave_out_arr(I); +-- wpfb_snk_in_arr(i) <= dp_pipeline_src_out; -- SOSI ctrl +-- wpfb_snk_in_arr(i).data <= reinterleave_out_arr(i).data; +-- wpfb_snk_in_arr(i).im <= reinterleave_out_arr(i).im; +-- wpfb_snk_in_arr(i).re <= reinterleave_out_arr(i).re; + END LOOP; + END PROCESS; + + ----------------------------------------------------------------------------- + -- WPFB + ----------------------------------------------------------------------------- + gen_wpfb : IF g_use_wpfb = TRUE GENERATE + u_wpfb_unit : ENTITY wpfb_lib.wpfb_unit + GENERIC MAP( + g_wpfb => c_wpfb, + g_stats_ena => FALSE, + g_use_bg => FALSE, + g_file_index_arr => array_init(0, 128, 1), + g_coefs_file_prefix => c_wpfb_coefs_file_prefix + ) + PORT MAP( + dp_rst => dp_rst, + dp_clk => dp_clk, + mm_rst => mm_rst, + mm_clk => mm_clk, + ram_fil_coefs_mosi => ram_fil_coefs_mosi, + ram_fil_coefs_miso => ram_fil_coefs_miso, + ram_st_sst_mosi => c_mem_mosi_rst, + ram_st_sst_miso => OPEN, + reg_bg_ctrl_mosi => c_mem_mosi_rst, + reg_bg_ctrl_miso => OPEN, + ram_bg_data_mosi => c_mem_mosi_rst, + ram_bg_data_miso => OPEN, + in_sosi_arr => wpfb_snk_in_arr, + out_sosi_arr => wpfb_src_out_arr + ); + END GENERATE; + + --Bypass + gen_no_wpfb : IF g_use_wpfb = FALSE GENERATE + wpfb_src_out_arr <= wpfb_snk_in_arr; + END GENERATE; + + ----------------------------------------------------------------------------- + -- Workaround for simulation: the first WPFB output block is not usable! --FIXME + -- Forward only blocks with BSN 5+ + ----------------------------------------------------------------------------- + p_bsn_filter : PROCESS(wpfb_src_out_arr) + BEGIN + requantize_snk_in_arr <= (OTHERS=>c_dp_sosi_rst); + IF TO_UINT(wpfb_src_out_arr(0).bsn)>=5 THEN + requantize_snk_in_arr <= wpfb_src_out_arr; + END IF; + END PROCESS; + + ----------------------------------------------------------------------------- + -- Stream recorder to record the WPFB output stream to a file + ----------------------------------------------------------------------------- + u_dp_stream_rec_play_wpfb_unit : ENTITY dp_lib.dp_stream_rec_play + GENERIC MAP ( + g_sim => TRUE, + g_pass_through => FALSE, + g_rec_not_play => TRUE, + g_rec_play_file => "../../../../applications/apertif/designs/apertif_unb1_correlator/tb/rec/wpfb_src_out_arr0.rec", + g_record_invalid => FALSE + ) + PORT MAP ( + dp_clk => dp_clk, + snk_in => wpfb_src_out_arr(0), + snk_out => OPEN, + src_out => OPEN, + src_in => c_dp_siso_rdy + ); + + ----------------------------------------------------------------------------- + -- Requantize output of wpfb for correlator input + ----------------------------------------------------------------------------- + gen_requantizer : FOR I IN 0 TO c_nof_interleaved_streams-1 GENERATE + u_dp_requantize_out : ENTITY dp_lib.dp_requantize + GENERIC MAP ( + g_complex => TRUE, + g_representation => "SIGNED", + g_lsb_w => c_wpfb_out_dat_w-c_cor_in_dat_w, + g_lsb_round => FALSE, + g_lsb_round_clip => FALSE, + g_msb_clip => FALSE, + g_msb_clip_symmetric => FALSE, + g_gain_w => 0, + g_pipeline_remove_lsb => 1, + g_pipeline_remove_msb => 0, + g_in_dat_w => c_wpfb_out_dat_w, + g_out_dat_w => c_cor_in_dat_w + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + snk_in => requantize_snk_in_arr(I), + src_out => correlator_snk_in_arr(I), + out_ovr => OPEN + ); + END GENERATE; + + ----------------------------------------------------------------------------- + -- Correlator + ----------------------------------------------------------------------------- + u_correlator : ENTITY correlator_lib.correlator + GENERIC MAP ( + g_sim => g_sim, + g_nof_input_streams => c_nof_interleaved_streams, -- 12 + g_input_unfold_factor => c_nof_input_folds, + g_nof_pre_mult_folds => c_nof_pre_mult_folds, + g_data_w => c_cor_in_dat_w, + g_conjugate => c_conjugate, + g_nof_channels => c_nof_channels, + g_integration_period => c_integration_period, + g_inter_channel_delay => c_inter_channel_delay, + g_sim_fast_acc_model => g_sim AND g_sim_fast + ) + PORT MAP ( + clk => dp_clk, + rst => dp_rst, + + snk_in_arr => correlator_snk_in_arr, + src_out_arr => correlator_src_out_arr + ); + + ----------------------------------------------------------------------------- + -- Wire complex fields into data field + -- . Real & imag. Real part is at the MS end so is put on the (1GbE) line first. + -- . For fast simulation, we output all channels back-to-back and write them to + -- a file (dp_stream_rec_play). In that case we don't want to use (and overload) + -- the visibility offload stage. + ----------------------------------------------------------------------------- + gen_wires_complex : IF g_sim=FALSE or g_sim_fast=FALSE GENERATE + p_wires_complex : PROCESS(correlator_src_out_arr) + BEGIN + dp_fifo_sc_snk_in <= correlator_src_out_arr(0); + dp_fifo_sc_snk_in.data(2*c_cor_out_dat_w-1 DOWNTO 0) <= correlator_src_out_arr(0).re(c_cor_out_dat_w-1 DOWNTO 0) & correlator_src_out_arr(0).im(c_cor_out_dat_w-1 DOWNTO 0); + END PROCESS; + END GENERATE; + + ----------------------------------------------------------------------------- + -- 64b -> 32b + ----------------------------------------------------------------------------- + u_dp_fifo_sc : ENTITY dp_lib.dp_fifo_sc + GENERIC MAP ( + g_data_w => c_nof_complex*c_cor_out_dat_w, + g_use_ctrl => TRUE, + g_use_bsn => TRUE, + g_use_channel => TRUE, + g_bsn_w => c_dp_stream_bsn_w, + g_channel_w => c_dp_stream_channel_w, -- FIX ME! Is the channel field required? + g_fifo_size => c_nof_visibilities + 20 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_in => dp_fifo_sc_snk_in, + + src_in => dp_repack_data_snk_out, + src_out => dp_repack_data_snk_in + ); + + u_dp_repack_data : ENTITY dp_lib.dp_repack_data + GENERIC MAP ( + g_in_dat_w => c_nof_complex*c_cor_out_dat_w, + g_in_nof_words => 1, + g_out_dat_w => c_cor_out_dat_w, + g_out_nof_words => 2 + ) + PORT MAP ( + rst => dp_rst, + clk => dp_clk, + + snk_out => dp_repack_data_snk_out, + snk_in => dp_repack_data_snk_in, + + src_in => apertif_unb1_correlator_vis_offload_snk_out, + src_out => apertif_unb1_correlator_vis_offload_snk_in + ); + + ----------------------------------------------------------------------------- + -- 1GbE visivility offload + ----------------------------------------------------------------------------- + u_apertif_unb1_correlator_vis_offload : ENTITY work.apertif_unb1_correlator_vis_offload + PORT MAP ( + mm_rst => mm_rst, + mm_clk => mm_clk, + + dp_rst => dp_rst, + dp_clk => dp_clk, + + reg_dp_offload_tx_hdr_dat_mosi => reg_dp_offload_tx_hdr_dat_mosi, + reg_dp_offload_tx_hdr_dat_miso => reg_dp_offload_tx_hdr_dat_miso, + + snk_in => apertif_unb1_correlator_vis_offload_snk_in, + snk_out => apertif_unb1_correlator_vis_offload_snk_out, + + src_out_arr => dp_offload_tx_src_out_arr, + src_in_arr => dp_offload_tx_src_in_arr, + + ID => ID + ); + + ----------------------------------------------------------------------------- + -- Stream recorder to record the correlator output stream to a file + -- . The data buffer can only take snapshots. + ----------------------------------------------------------------------------- + gen_dp_stream_rec_play_correlator : IF g_sim=TRUE GENERATE + u_dp_stream_rec_play_correlator : ENTITY dp_lib.dp_stream_rec_play + GENERIC MAP ( + g_sim => TRUE, + g_pass_through => FALSE, + g_rec_not_play => TRUE, + g_rec_play_file => "../../../../applications/apertif/designs/apertif_unb1_correlator/tb/rec/correlator_src_out_arr0.rec", + g_record_invalid => FALSE + ) + PORT MAP ( + dp_clk => dp_clk, + snk_in => correlator_src_out_arr(0), + snk_out => OPEN, + src_out => OPEN, + src_in => c_dp_siso_rdy + ); + END GENERATE; + +END str; +