Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
sdp_station.vhd 47.20 KiB
-------------------------------------------------------------------------------
--
-- Copyright 2021
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
-- Author : R vd Walle
-- Purpose:  
--   Core design for Lofar2 SDP station
-- Description:
--   Combines sdp nodes. Contains the UniBoard2 HW version independent LOFAR2 SDP application code.
-------------------------------------------------------------------------------

LIBRARY IEEE, common_lib, technology_lib, diag_lib, dp_lib, tech_jesd204b_lib, wpfb_lib, tech_pll_lib, tr_10gbe_lib, nw_10gbe_lib, eth_lib, ring_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_network_layers_pkg.ALL;
USE common_lib.common_field_pkg.ALL;
USE technology_lib.technology_pkg.ALL;
USE diag_lib.diag_pkg.ALL;
USE dp_lib.dp_stream_pkg.ALL;
USE wpfb_lib.wpfb_pkg.ALL;
USE work.sdp_pkg.ALL;
USE eth_lib.eth_pkg.ALL;
USE ring_lib.ring_pkg.ALL;

ENTITY sdp_station IS
  GENERIC (
    g_technology             : NATURAL := c_tech_arria10_e1sg;
    g_sim                    : BOOLEAN := FALSE; -- Overridden by TB
    g_sim_sdp                : t_sdp_sim := c_sdp_sim;  -- Used when g_sim = TRUE, otherwise use HW defaults
    g_sim_sync_timeout       : NATURAL := 1024;
    g_wpfb                   : t_wpfb  := c_sdp_wpfb_subbands;
    g_bsn_nof_clk_per_sync   : NATURAL := c_sdp_N_clk_per_sync;  -- Default 200M, overide for short simulation
    g_scope_selected_subband : NATURAL := 0;
    g_use_fsub               : BOOLEAN := TRUE;
    g_use_xsub               : BOOLEAN := TRUE;
    g_use_bf                 : BOOLEAN := TRUE;
    g_use_ring               : BOOLEAN := TRUE;
    g_P_sq                   : NATURAL := 1
  );
  PORT (
    -- System
    mm_clk        : IN STD_LOGIC;
    mm_rst        : IN STD_LOGIC := '0';
    
    dp_pps        : IN STD_LOGIC;
    dp_rst        : IN STD_LOGIC;
    dp_clk        : IN STD_LOGIC;

    -- ID
    gn_id         : IN STD_LOGIC_VECTOR(c_sdp_W_gn_id-1 DOWNTO 0);
    this_bck_id   : IN STD_LOGIC_VECTOR(6-1 DOWNTO 0);
    this_chip_id  : IN STD_LOGIC_VECTOR(2-1 DOWNTO 0);

    -- Transceiver clocks
    SA_CLK        : IN    STD_LOGIC := '0'; -- Clock 10GbE front (qsfp) and ring lines

     -- back transceivers (Note: numbered from 0)
    JESD204B_SERIAL_DATA       : IN    STD_LOGIC_VECTOR(c_sdp_S_pn-1 downto 0); 
                                                  -- Connect to the BCK_RX pins in the top wrapper
    JESD204B_REFCLK            : IN    STD_LOGIC; -- Connect to BCK_REF_CLK pin in the top level wrapper
 
    -- jesd204b syncronization signals
    JESD204B_SYSREF            : IN    STD_LOGIC;
    JESD204B_SYNC_N            : OUT   STD_LOGIC_VECTOR(c_sdp_N_sync_jesd -1 DOWNTO 0);


    ----------------------------------------------
    -- UDP Offload
    ----------------------------------------------
    udp_tx_sosi_arr            : OUT t_dp_sosi_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
    udp_tx_siso_arr            : IN  t_dp_siso_arr(c_eth_nof_udp_ports-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);  

    ----------------------------------------------
    -- 10 GbE 
    ----------------------------------------------
    reg_nw_10GbE_mac_mosi      : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_nw_10GbE_mac_miso      : OUT t_mem_miso := c_mem_miso_rst;

    reg_nw_10GbE_eth10g_mosi   : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_nw_10GbE_eth10g_miso   : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- AIT 
    ----------------------------------------------
    -- JESD
    jesd204b_mosi              : IN  t_mem_mosi := c_mem_mosi_rst;
    jesd204b_miso              : OUT t_mem_miso := c_mem_miso_rst;

    -- JESD control
    jesd_ctrl_mosi             : IN  t_mem_mosi := c_mem_mosi_rst;
    jesd_ctrl_miso             : OUT t_mem_miso := c_mem_miso_rst;

    -- Shiftram (applies per-antenna delay)
    reg_dp_shiftram_mosi       : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_dp_shiftram_miso       : OUT t_mem_miso := c_mem_miso_rst;

    -- bsn source
    reg_bsn_source_v2_mosi     : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_bsn_source_v2_miso     : OUT t_mem_miso := c_mem_miso_rst;

    -- bsn scheduler
    reg_bsn_scheduler_wg_mosi  : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_bsn_scheduler_wg_miso  : OUT t_mem_miso := c_mem_miso_rst;

    -- WG
    reg_wg_mosi                : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_wg_miso                : OUT t_mem_miso := c_mem_miso_rst;
    ram_wg_mosi                : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_wg_miso                : OUT t_mem_miso := c_mem_miso_rst;

    -- BSN MONITOR
    reg_bsn_monitor_input_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_bsn_monitor_input_miso : OUT t_mem_miso := c_mem_miso_rst;

    -- Data buffer bsn
    ram_diag_data_buf_bsn_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_diag_data_buf_bsn_miso : OUT t_mem_miso := c_mem_miso_rst;
    reg_diag_data_buf_bsn_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_diag_data_buf_bsn_miso : OUT t_mem_miso := c_mem_miso_rst;

    -- ST Histogram
    ram_st_histogram_mosi      : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_st_histogram_miso      : OUT t_mem_miso := c_mem_miso_rst;

    -- Aduh statistics monitor
    reg_aduh_monitor_mosi      : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_aduh_monitor_miso      : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- FSUB 
    ----------------------------------------------
    -- Subband statistics
    ram_st_sst_mosi            : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_st_sst_miso            : OUT t_mem_miso := c_mem_miso_rst;

    -- Spectral Inversion
    reg_si_mosi                : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_si_miso                : OUT t_mem_miso := c_mem_miso_rst;

    -- Filter coefficients
    ram_fil_coefs_mosi         : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_fil_coefs_miso         : OUT t_mem_miso := c_mem_miso_rst;

    -- Equalizer gains
    ram_equalizer_gains_mosi   : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_equalizer_gains_miso   : OUT t_mem_miso := c_mem_miso_rst;

    -- DP Selector
    reg_dp_selector_mosi       : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_dp_selector_miso       : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- SDP Info 
    ----------------------------------------------
    reg_sdp_info_mosi          : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_sdp_info_miso          : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- RING Info 
    ----------------------------------------------
    reg_ring_info_copi          : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_ring_info_cipo          : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- XSUB 
    ----------------------------------------------
    -- crosslets_info
    reg_crosslets_info_mosi          : IN  t_mem_mosi := c_mem_mosi_rst; 
    reg_crosslets_info_miso          : OUT t_mem_miso := c_mem_miso_rst;
 
    -- nof_crosslets
    reg_nof_crosslets_mosi           : IN  t_mem_mosi := c_mem_mosi_rst; 
    reg_nof_crosslets_miso           : OUT t_mem_miso := c_mem_miso_rst; 

    -- bsn_scheduler_xsub
    reg_bsn_sync_scheduler_xsub_mosi : IN  t_mem_mosi := c_mem_mosi_rst; 
    reg_bsn_sync_scheduler_xsub_miso : OUT t_mem_miso := c_mem_miso_rst; 

    -- st_xsq
    ram_st_xsq_mosi                  : IN  t_mem_mosi := c_mem_mosi_rst; 
    ram_st_xsq_miso                  : OUT t_mem_miso := c_mem_miso_rst; 

    ----------------------------------------------
    -- BF 
    ----------------------------------------------
    -- Beamlet Subband Select
    ram_ss_ss_wide_mosi        : IN  t_mem_mosi := c_mem_mosi_rst;       
    ram_ss_ss_wide_miso        : OUT t_mem_miso := c_mem_miso_rst;

    -- Local BF bf weights
    ram_bf_weights_mosi        : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_bf_weights_miso        : OUT t_mem_miso := c_mem_miso_rst;

    -- mms_dp_scale Scale Beamlets
    reg_bf_scale_mosi          : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_bf_scale_miso          : OUT t_mem_miso := c_mem_miso_rst;

    -- Beamlet Data Output header fields
    reg_hdr_dat_mosi           : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_hdr_dat_miso           : OUT t_mem_miso := c_mem_miso_rst;

    -- Beamlet Data Output xonoff
    reg_dp_xonoff_mosi         : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_dp_xonoff_miso         : OUT t_mem_miso := c_mem_miso_rst;

    -- Beamlet Statistics (BST)
    ram_st_bst_mosi            : IN  t_mem_mosi := c_mem_mosi_rst;
    ram_st_bst_miso            : OUT t_mem_miso := c_mem_miso_rst;

    ----------------------------------------------
    -- SST 
    ----------------------------------------------
    -- Statistics Enable
    reg_stat_enable_sst_mosi       : IN  t_mem_mosi;
    reg_stat_enable_sst_miso       : OUT t_mem_miso;
    
    -- Statistics header info  
    reg_stat_hdr_dat_sst_mosi      : IN  t_mem_mosi;
    reg_stat_hdr_dat_sst_miso      : OUT t_mem_miso;

    ----------------------------------------------
    -- XST 
    ----------------------------------------------
    -- Statistics Enable
    reg_stat_enable_xst_mosi                    : IN  t_mem_mosi;
    reg_stat_enable_xst_miso                    : OUT t_mem_miso;
    
    -- Statistics header info  
    reg_stat_hdr_dat_xst_mosi                   : IN  t_mem_mosi;
    reg_stat_hdr_dat_xst_miso                   : OUT t_mem_miso;

    -- XST bsn aligner_v2
    reg_bsn_align_copi                          : IN  t_mem_mosi;
    reg_bsn_align_cipo                          : OUT t_mem_miso;
   
    -- XST bsn aligner_v2 bsn monitors
    reg_bsn_monitor_v2_bsn_align_input_copi     : IN  t_mem_mosi;
    reg_bsn_monitor_v2_bsn_align_input_cipo     : OUT t_mem_miso;
    reg_bsn_monitor_v2_bsn_align_output_copi    : IN  t_mem_mosi;
    reg_bsn_monitor_v2_bsn_align_output_cipo    : OUT t_mem_miso;

    -- XST UDP offload bsn monitor
    reg_xst_udp_monitor_copi                    : IN  t_mem_mosi;
    reg_xst_udp_monitor_cipo                    : OUT t_mem_miso;

    -- XST ring lane info
    reg_ring_lane_info_xst_copi                 : IN  t_mem_mosi;
    reg_ring_lane_info_xst_cipo                 : OUT t_mem_miso;

    -- XST ring bsn monitor rx 
    reg_bsn_monitor_v2_ring_rx_xst_copi         : IN  t_mem_mosi;
    reg_bsn_monitor_v2_ring_rx_xst_cipo         : OUT t_mem_miso;

    -- XST ring bsn monitor tx 
    reg_bsn_monitor_v2_ring_tx_xst_copi         : IN  t_mem_mosi;
    reg_bsn_monitor_v2_ring_tx_xst_cipo         : OUT t_mem_miso;

    -- XST ring validate err 
    reg_dp_block_validate_err_xst_copi          : IN  t_mem_mosi;
    reg_dp_block_validate_err_xst_cipo          : OUT t_mem_miso;
    -- XST ring bsn at sync 
    reg_dp_block_validate_bsn_at_sync_xst_copi  : IN  t_mem_mosi;
    reg_dp_block_validate_bsn_at_sync_xst_cipo  : OUT t_mem_miso;

    -- XST ring MAC 
    reg_tr_10GbE_mac_copi                       : IN  t_mem_mosi;
    reg_tr_10GbE_mac_cipo                       : OUT t_mem_miso;
                             
    -- XST ring ETH 
    reg_tr_10GbE_eth10g_copi                    : IN  t_mem_mosi;
    reg_tr_10GbE_eth10g_cipo                    : OUT t_mem_miso;


    ----------------------------------------------
    -- BST 
    ----------------------------------------------
    -- Statistics Enable
    reg_stat_enable_bst_mosi      : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_stat_enable_bst_miso      : OUT t_mem_miso := c_mem_miso_rst;
    
    -- Statistics header info 
    reg_stat_hdr_dat_bst_mosi     : IN  t_mem_mosi := c_mem_mosi_rst;
    reg_stat_hdr_dat_bst_miso     : OUT t_mem_miso := c_mem_miso_rst;

    -- RING_0 serial
    RING_0_TX: OUT STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
    RING_0_RX: IN  STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');

    -- RING_1 serial
    RING_1_TX : OUT STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');
    RING_1_RX : IN  STD_LOGIC_VECTOR( c_quad - 1 DOWNTO 0) := (OTHERS => '0');

    -- QSFP serial
    unb2_board_front_io_serial_tx_arr : OUT STD_LOGIC_VECTOR(6 * c_quad-1 DOWNTO 0) := (OTHERS => '0');
    unb2_board_front_io_serial_rx_arr : IN  STD_LOGIC_VECTOR(6 * c_quad-1 DOWNTO 0) := (OTHERS => '0');

    -- QSFP LEDS
    unb2_board_qsfp_leds_tx_sosi_arr : OUT t_dp_sosi_arr(6 * c_quad-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
    unb2_board_qsfp_leds_tx_siso_arr : OUT t_dp_siso_arr(6 * c_quad-1 DOWNTO 0) := (OTHERS => c_dp_siso_rst);
    unb2_board_qsfp_leds_rx_sosi_arr : OUT t_dp_sosi_arr(6 * c_quad-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst)
  );
END sdp_station;


ARCHITECTURE str OF sdp_station IS

  -- 10 GbE Interface
  CONSTANT c_nof_10GbE_offload_streams     : NATURAL := 1;
  CONSTANT c_nof_blocks_per_packet         : NATURAL := 4;
  CONSTANT c_nof_beamlets_per_block        : NATURAL := c_sdp_N_pol * c_sdp_S_sub_bf; 
  CONSTANT c_10GbE_block_size              : NATURAL := c_nof_blocks_per_packet * c_nof_beamlets_per_block / 4; -- 4 beamlets fit in 1 64bit longword 
  CONSTANT c_fifo_tx_fill                  : NATURAL := c_10GbE_block_size; 
  CONSTANT c_fifo_tx_size                  : NATURAL := c_fifo_tx_fill + 11; -- Make fifo size large enough for adding header.
 
  -- Address widths of a single MM instance
  CONSTANT c_addr_w_ram_ss_ss_wide : NATURAL := ceil_log2(c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); 
  CONSTANT c_addr_w_ram_bf_weights : NATURAL := ceil_log2(c_sdp_N_pol * c_sdp_P_pfb * c_sdp_S_sub_bf * c_sdp_Q_fft); 
  CONSTANT c_addr_w_reg_bf_scale   : NATURAL := 1; 
  CONSTANT c_addr_w_reg_hdr_dat    : NATURAL := ceil_log2(field_nof_words(c_sdp_cep_hdr_field_arr, c_word_w)); 
  CONSTANT c_addr_w_reg_dp_xonoff  : NATURAL := 1; 
  CONSTANT c_addr_w_ram_st_bst     : NATURAL := ceil_log2(c_sdp_S_sub_bf*c_sdp_N_pol*(c_longword_sz/c_word_sz));
  
  -- Read only sdp_info values
  CONSTANT c_f_adc     : STD_LOGIC := '1'; -- '0' => 160M, '1' => 200M
  CONSTANT c_fsub_type : STD_LOGIC := '0'; -- '0' => critical sampled PFB, '1' => oversampled PFB
 
  CONSTANT c_use_dp_layer              : BOOLEAN := TRUE; 
  CONSTANT c_lane_packet_length        : NATURAL := c_sdp_N_crosslets_max * c_sdp_S_pn / 2; -- = crosslet subband select block size devided by 2 as it is repacked from 32b to 64b.
  CONSTANT c_err_bi                    : NATURAL := 0; 
  CONSTANT c_nof_err_counts            : NATURAL := 8; 
  CONSTANT c_bsn_at_sync_check_channel : NATURAL := 1; 
  CONSTANT c_validate_channel          : BOOLEAN := TRUE; 
  CONSTANT c_validate_channel_mode     : STRING  := "=";
  CONSTANT c_sync_timeout              : NATURAL := sel_a_b(g_sim, g_sim_sync_timeout, c_sdp_N_clk_sync_timeout );
  CONSTANT c_xsub_fifo_tx_fill         : NATURAL := c_lane_packet_length + sel_a_b(c_use_dp_layer, c_ring_dp_hdr_field_size, c_ring_eth_hdr_field_size); --total packet length
  CONSTANT c_xsub_fifo_tx_size         : NATURAL := 2 * c_lane_packet_length;

  CONSTANT c_nof_if                    : NATURAL := 3; -- 3 different interfaces, QSFP, RING_0 and RING_1
  CONSTANT c_qsfp_if_offset            : NATURAL := 0; -- QSFP signals are indexed at c_nof_if * I.
  CONSTANT c_ring_0_if_offset          : NATURAL := 1; -- RING_0 signals are indexed at c_nof_if * I + 1. 
  CONSTANT c_ring_1_if_offset          : NATURAL := 2; -- RING_1 signals are indexed at c_nof_if * I + 2.
  CONSTANT c_nof_mac                   : NATURAL := 3; -- must match one of the MAC IP variations, e.g. 1, 3, 4, 12, 24, 48

  SIGNAL gn_index : NATURAL := 0;
  SIGNAL this_rn  : STD_LOGIC_VECTOR(c_byte_w-1 DOWNTO 0);  
  ----------------------------------------------
  -- BF 
  ----------------------------------------------
  -- Beamlet Subband Select
  SIGNAL ram_ss_ss_wide_mosi_arr    : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);       
  SIGNAL ram_ss_ss_wide_miso_arr    : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  -- Local BF bf weights
  SIGNAL ram_bf_weights_mosi_arr    : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL ram_bf_weights_miso_arr    : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  -- mms_dp_scale Scale Beamlets
  SIGNAL reg_bf_scale_mosi_arr      : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL reg_bf_scale_miso_arr      : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  -- Beamlet Data Output header fields
  SIGNAL reg_hdr_dat_mosi_arr       : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL reg_hdr_dat_miso_arr       : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  -- Beamlet Data Output xonoff
  SIGNAL reg_dp_xonoff_mosi_arr     : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL reg_dp_xonoff_miso_arr     : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  -- Beamlet Statistics (BST)
  SIGNAL ram_st_bst_mosi_arr        : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL ram_st_bst_miso_arr        : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);

  ----------------------------------------------
  -- BST 
  ----------------------------------------------
  -- Statistics Enable
  SIGNAL reg_stat_enable_bst_mosi_arr  : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL reg_stat_enable_bst_miso_arr  : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
  
  -- Statistics header info 
  SIGNAL reg_stat_hdr_dat_bst_mosi_arr : t_mem_mosi_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
  SIGNAL reg_stat_hdr_dat_bst_miso_arr : t_mem_miso_arr(c_sdp_N_beamsets-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
  ----------------------------------------------

  SIGNAL ait_sosi_arr                      : t_dp_sosi_arr(c_sdp_S_pn-1 DOWNTO 0);         
  SIGNAL pfb_sosi_arr                      : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);         
  SIGNAL fsub_sosi_arr                     : t_dp_sosi_arr(c_sdp_P_pfb-1 DOWNTO 0);        
  SIGNAL bs_sosi                           : t_dp_sosi;        
 
  SIGNAL xst_from_ri_sosi                  : t_dp_sosi;        
  SIGNAL xst_to_ri_sosi                    : t_dp_sosi;        
  SIGNAL lane_rx_cable_sosi_arr            : t_dp_sosi_arr(2 DOWNTO 0); -- 3 as, a total of 3 lanes will be used. 
  SIGNAL lane_tx_cable_sosi_arr            : t_dp_sosi_arr(2 DOWNTO 0); -- 3 as, a total of 3 lanes will be used.       
  SIGNAL lane_rx_board_sosi_arr            : t_dp_sosi_arr(2 DOWNTO 0); -- 3 as, a total of 3 lanes will be used.       
  SIGNAL lane_tx_board_sosi_arr            : t_dp_sosi_arr(2 DOWNTO 0); -- 3 as, a total of 3 lanes will be used.       
 
  SIGNAL dp_bsn_source_restart             : STD_LOGIC;
 
  SIGNAL bf_udp_sosi_arr                   : t_dp_sosi_arr(c_sdp_N_beamsets-1 DOWNTO 0);         
  SIGNAL bf_udp_siso_arr                   : t_dp_siso_arr(c_sdp_N_beamsets-1 DOWNTO 0);    
  SIGNAL bf_10GbE_hdr_fields_out_arr       : t_slv_1024_arr(c_sdp_N_beamsets-1 DOWNTO 0);

  -- 10GbE
  SIGNAL tr_ref_clk_312                    : STD_LOGIC;
  SIGNAL tr_ref_clk_156                    : STD_LOGIC;
  SIGNAL tr_ref_rst_156                    : STD_LOGIC;

  SIGNAL tr_10gbe_serial_tx_arr            : STD_LOGIC_VECTOR(c_nof_mac-1 DOWNTO 0) := (OTHERS => '0');
  SIGNAL tr_10gbe_serial_rx_arr            : STD_LOGIC_VECTOR(c_nof_mac-1 DOWNTO 0) := (OTHERS => '0');

  SIGNAL nw_10gbe_snk_in_arr               : t_dp_sosi_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
  SIGNAL nw_10gbe_snk_out_arr              : t_dp_siso_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);
  SIGNAL nw_10gbe_src_out_arr              : t_dp_sosi_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);
  SIGNAL nw_10gbe_src_in_arr               : t_dp_siso_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);

  SIGNAL nw_10GbE_hdr_fields_in_arr        : t_slv_1024_arr(c_nof_10GbE_offload_streams-1 DOWNTO 0);
          
  SIGNAL tr_10gbe_src_out_arr              : t_dp_sosi_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);         
  SIGNAL tr_10gbe_snk_in_arr               : t_dp_sosi_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_sosi_rst);      
  SIGNAL tr_10gbe_src_in_arr               : t_dp_siso_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);   
  SIGNAL tr_10gbe_snk_out_arr              : t_dp_siso_arr(c_nof_mac-1 DOWNTO 0) := (OTHERS => c_dp_siso_rdy);  

  SIGNAL cep_eth_src_mac                   : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
  SIGNAL cep_ip_src_addr                   : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0);
  SIGNAL cep_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
  SIGNAL stat_eth_src_mac                  : STD_LOGIC_VECTOR(c_network_eth_mac_addr_w-1 DOWNTO 0);
  SIGNAL stat_ip_src_addr                  : STD_LOGIC_VECTOR(c_network_ip_addr_w-1 DOWNTO 0);
  SIGNAL sst_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
  SIGNAL bst_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);
  SIGNAL xst_udp_src_port                  : STD_LOGIC_VECTOR(c_network_udp_port_w-1 DOWNTO 0);

  SIGNAL sdp_info                          : t_sdp_info := c_sdp_info_rst;
  SIGNAL ring_info                         : t_ring_info;


BEGIN

  -----------------------------------------------------------------------------
  -- SDP Info register
  -----------------------------------------------------------------------------
  gn_index <= TO_UINT(gn_id);
  -- derive MAC, IP and UDP Port 
  cep_eth_src_mac  <= c_sdp_cep_eth_src_mac_47_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & RESIZE_UVEC(this_chip_id, c_byte_w); -- Simply use chip_id since we only use 1 of the 6*4 = 24 10GbE port.
  cep_ip_src_addr  <= c_sdp_cep_ip_src_addr_31_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & INCR_UVEC(RESIZE_UVEC(this_chip_id, c_byte_w), 1); -- +1 to avoid IP = *.*.*.0
  cep_udp_src_port <= c_sdp_cep_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w);
  
  stat_eth_src_mac <= c_sdp_stat_eth_src_mac_47_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & RESIZE_UVEC(this_chip_id, c_byte_w); -- Simply use chip_id since we only use 1 of the 6*4 = 24 10GbE port.
  stat_ip_src_addr <= c_sdp_stat_ip_src_addr_31_16 & RESIZE_UVEC(this_bck_id, c_byte_w) & INCR_UVEC(RESIZE_UVEC(this_chip_id, c_byte_w), 1); -- +1 to avoid IP = *.*.*.0
  sst_udp_src_port <= c_sdp_sst_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w);
  bst_udp_src_port <= c_sdp_bst_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w);
  xst_udp_src_port <= c_sdp_xst_udp_src_port_15_8 & RESIZE_UVEC(gn_id, c_byte_w);

  u_sdp_info : ENTITY work.sdp_info
  PORT MAP(
    -- Clocks and reset
    mm_rst    => mm_rst,  -- reset synchronous with mm_clk
    mm_clk    => mm_clk,  -- memory-mapped bus clock

    dp_clk    => dp_clk,
    dp_rst    => dp_rst,

    reg_mosi  => reg_sdp_info_mosi,
    reg_miso  => reg_sdp_info_miso,

    -- inputs from other blocks
    gn_index  => gn_index, 
    f_adc     => c_f_adc, 
    fsub_type => c_fsub_type, 

    -- sdp info
    sdp_info => sdp_info 
  ); 

  -----------------------------------------------------------------------------
  -- Ring info
  -----------------------------------------------------------------------------
  u_ring_info : ENTITY ring_lib.ring_info
  PORT MAP (
    mm_rst => mm_rst,
    mm_clk => mm_clk,

    dp_clk => dp_clk,
    dp_rst => dp_rst,

    reg_copi => reg_ring_info_copi,
    reg_cipo => reg_ring_info_cipo,

    ring_info => ring_info
  );

  this_rn <= TO_UVEC(gn_index - TO_UINT(ring_info.O_rn), c_byte_w) WHEN rising_edge(dp_clk); -- Using register to ease timing closure.

  -----------------------------------------------------------------------------
  -- node_adc_input_and_timing (AIT)
  --   .Contains JESD receiver, bsn source and associated data buffers, diagnostics and statistics
  -----------------------------------------------------------------------------
  u_ait: ENTITY work.node_sdp_adc_input_and_timing
  GENERIC MAP(
    g_technology                => g_technology,
    g_sim                       => g_sim,
    g_bsn_nof_clk_per_sync      => g_bsn_nof_clk_per_sync                
  )
  PORT MAP(
    -- clocks and resets
    mm_clk                      => mm_clk,           
    mm_rst                      => mm_rst,           
    dp_clk                      => dp_clk,           
    dp_rst                      => dp_rst,           
 
    -- mm control buses
    jesd_ctrl_mosi              => jesd_ctrl_mosi, 
    jesd_ctrl_miso              => jesd_ctrl_miso, 
    jesd204b_mosi               => jesd204b_mosi,         
    jesd204b_miso               => jesd204b_miso,         
    reg_dp_shiftram_mosi        => reg_dp_shiftram_mosi,
    reg_dp_shiftram_miso        => reg_dp_shiftram_miso,
    reg_bsn_source_v2_mosi      => reg_bsn_source_v2_mosi,
    reg_bsn_source_v2_miso      => reg_bsn_source_v2_miso,
    reg_bsn_scheduler_wg_mosi   => reg_bsn_scheduler_wg_mosi,
    reg_bsn_scheduler_wg_miso   => reg_bsn_scheduler_wg_miso,
    reg_wg_mosi                 => reg_wg_mosi,
    reg_wg_miso                 => reg_wg_miso,
    ram_wg_mosi                 => ram_wg_mosi,
    ram_wg_miso                 => ram_wg_miso,
    reg_bsn_monitor_input_mosi  => reg_bsn_monitor_input_mosi,
    reg_bsn_monitor_input_miso  => reg_bsn_monitor_input_miso,
    ram_diag_data_buf_bsn_mosi  => ram_diag_data_buf_bsn_mosi,
    ram_diag_data_buf_bsn_miso  => ram_diag_data_buf_bsn_miso,
    reg_diag_data_buf_bsn_mosi  => reg_diag_data_buf_bsn_mosi,
    reg_diag_data_buf_bsn_miso  => reg_diag_data_buf_bsn_miso,
    ram_st_histogram_mosi       => ram_st_histogram_mosi,
    ram_st_histogram_miso       => ram_st_histogram_miso,
    reg_aduh_monitor_mosi       => reg_aduh_monitor_mosi,
    reg_aduh_monitor_miso       => reg_aduh_monitor_miso,
  
     -- Jesd external IOs
    jesd204b_serial_data       => JESD204B_SERIAL_DATA,
    jesd204b_refclk            => JESD204B_REFCLK,   
    jesd204b_sysref            => JESD204B_SYSREF,   
    jesd204b_sync_n            => JESD204B_SYNC_N,   
 
    -- Streaming data output
    out_sosi_arr               => ait_sosi_arr,
    dp_bsn_source_restart      => dp_bsn_source_restart        
  );

  -----------------------------------------------------------------------------
  -- node_sdp_filterbank (FSUB)
  -----------------------------------------------------------------------------
  gen_use_fsub : IF g_use_fsub GENERATE
    u_fsub : ENTITY work.node_sdp_filterbank 
    GENERIC MAP(
      g_sim                    => g_sim,
      g_sim_sdp                => g_sim_sdp,
      g_wpfb                   => g_wpfb,
      g_scope_selected_subband => g_scope_selected_subband
    )
    PORT MAP(
      dp_clk                => dp_clk, 
      dp_rst                => dp_rst, 
                                                 
      in_sosi_arr           => ait_sosi_arr,    
      pfb_sosi_arr          => pfb_sosi_arr,
      fsub_sosi_arr         => fsub_sosi_arr,
      dp_bsn_source_restart => dp_bsn_source_restart,

      sst_udp_sosi          => udp_tx_sosi_arr(0),
      sst_udp_siso          => udp_tx_siso_arr(0),
                                                 
      mm_rst                => mm_rst, 
      mm_clk                => mm_clk, 
                                                 
      reg_si_mosi           => reg_si_mosi, 
      reg_si_miso           => reg_si_miso, 
      ram_st_sst_mosi       => ram_st_sst_mosi,  
      ram_st_sst_miso       => ram_st_sst_miso, 
      ram_fil_coefs_mosi    => ram_fil_coefs_mosi,  
      ram_fil_coefs_miso    => ram_fil_coefs_miso,
      ram_gains_mosi        => ram_equalizer_gains_mosi,     
      ram_gains_miso        => ram_equalizer_gains_miso,     
      reg_selector_mosi     => reg_dp_selector_mosi,  
      reg_selector_miso     => reg_dp_selector_miso,

      reg_enable_mosi       => reg_stat_enable_sst_mosi,
      reg_enable_miso       => reg_stat_enable_sst_miso,
      reg_hdr_dat_mosi      => reg_stat_hdr_dat_sst_mosi,
      reg_hdr_dat_miso      => reg_stat_hdr_dat_sst_miso,
  
      sdp_info              => sdp_info,
      gn_id                 => gn_id,
      eth_src_mac           => stat_eth_src_mac,
      ip_src_addr           => stat_ip_src_addr,
      udp_src_port          => sst_udp_src_port
    );
  END GENERATE;


  -----------------------------------------------------------------------------
  -- node_sdp_correlator (XSUB)
  -----------------------------------------------------------------------------
  gen_use_xsub : IF g_use_xsub GENERATE
    u_xsub : ENTITY work.node_sdp_correlator 
    GENERIC MAP(
      g_sim     => g_sim,
      g_sim_sdp => g_sim_sdp,
      g_P_sq    => g_P_sq
    )
    PORT MAP(
      dp_clk                                   => dp_clk, 
      dp_rst                                   => dp_rst, 
                                                                    
      in_sosi_arr                              => fsub_sosi_arr,    

      xst_udp_sosi                             => udp_tx_sosi_arr(1),
      xst_udp_siso                             => udp_tx_siso_arr(1), 
        
      from_ri_sosi                             => xst_from_ri_sosi, 
      to_ri_sosi                               => xst_to_ri_sosi,     

      bs_sosi                                  => bs_sosi,
                                                       
      mm_rst                                   => mm_rst, 
      mm_clk                                   => mm_clk, 
                                                           
      reg_crosslets_info_copi                  => reg_crosslets_info_mosi,     
      reg_crosslets_info_cipo                  => reg_crosslets_info_miso,  
      reg_nof_crosslets_copi                   => reg_nof_crosslets_mosi,     
      reg_nof_crosslets_cipo                   => reg_nof_crosslets_miso,      
      reg_bsn_sync_scheduler_xsub_copi         => reg_bsn_sync_scheduler_xsub_mosi, 
      reg_bsn_sync_scheduler_xsub_cipo         => reg_bsn_sync_scheduler_xsub_miso, 
      ram_st_xsq_copi                          => ram_st_xsq_mosi,             
      ram_st_xsq_cipo                          => ram_st_xsq_miso,

      reg_stat_enable_copi                     => reg_stat_enable_xst_mosi,
      reg_stat_enable_cipo                     => reg_stat_enable_xst_miso,
      reg_stat_hdr_dat_copi                    => reg_stat_hdr_dat_xst_mosi,
      reg_stat_hdr_dat_cipo                    => reg_stat_hdr_dat_xst_miso,

      reg_bsn_align_copi                       => reg_bsn_align_copi, 
      reg_bsn_align_cipo                       => reg_bsn_align_cipo,       
      reg_bsn_monitor_v2_bsn_align_input_copi  => reg_bsn_monitor_v2_bsn_align_input_copi,   
      reg_bsn_monitor_v2_bsn_align_input_cipo  => reg_bsn_monitor_v2_bsn_align_input_cipo,   
      reg_bsn_monitor_v2_bsn_align_output_copi => reg_bsn_monitor_v2_bsn_align_output_copi,  
      reg_bsn_monitor_v2_bsn_align_output_cipo => reg_bsn_monitor_v2_bsn_align_output_cipo,  
      reg_xst_udp_monitor_copi                 => reg_xst_udp_monitor_copi,
      reg_xst_udp_monitor_cipo                 => reg_xst_udp_monitor_cipo, 

      sdp_info                                 => sdp_info,
      ring_info                                => ring_info,
      gn_id                                    => gn_id,
      stat_eth_src_mac                         => stat_eth_src_mac,
      stat_ip_src_addr                         => stat_ip_src_addr,
      stat_udp_src_port                        => xst_udp_src_port
    );

    gen_use_xsub_ring : IF g_use_ring GENERATE
      u_ring_lane_xst : ENTITY ring_lib.ring_lane
      GENERIC MAP (
        g_lane_direction            => 1, -- transport in positive direction.
        g_lane_data_w               => c_longword_w,
        g_lane_packet_length        => c_lane_packet_length,
        g_use_dp_layer              => c_use_dp_layer,
        g_nof_rx_monitors           => c_sdp_N_pn_max,
        g_nof_tx_monitors           => c_sdp_N_pn_max,
        g_err_bi                    => c_err_bi,
        g_nof_err_counts            => c_nof_err_counts,
        g_bsn_at_sync_check_channel => c_bsn_at_sync_check_channel,
        g_validate_channel          => c_validate_channel,
        g_validate_channel_mode     => c_validate_channel_mode,
        g_sync_timeout              => c_sync_timeout    
      )
      PORT MAP (
        mm_rst => mm_rst,
        mm_clk => mm_clk,
        dp_clk => dp_clk,
        dp_rst => dp_rst,
  
        from_lane_sosi     => xst_from_ri_sosi,
        to_lane_sosi       => xst_to_ri_sosi,
        lane_rx_cable_sosi => lane_rx_cable_sosi_arr(0),
        lane_rx_board_sosi => lane_rx_board_sosi_arr(0),
        lane_tx_cable_sosi => lane_tx_cable_sosi_arr(0),
        lane_tx_board_sosi => lane_tx_board_sosi_arr(0),
        bs_sosi            => bs_sosi, 
        
        reg_ring_lane_info_copi                => reg_ring_lane_info_xst_copi,
        reg_ring_lane_info_cipo                => reg_ring_lane_info_xst_cipo,
        reg_bsn_monitor_v2_ring_rx_copi        => reg_bsn_monitor_v2_ring_rx_xst_copi,
        reg_bsn_monitor_v2_ring_rx_cipo        => reg_bsn_monitor_v2_ring_rx_xst_cipo,
        reg_bsn_monitor_v2_ring_tx_copi        => reg_bsn_monitor_v2_ring_tx_xst_copi,
        reg_bsn_monitor_v2_ring_tx_cipo        => reg_bsn_monitor_v2_ring_tx_xst_cipo,
        reg_dp_block_validate_err_copi         => reg_dp_block_validate_err_xst_copi,
        reg_dp_block_validate_err_cipo         => reg_dp_block_validate_err_xst_cipo,
        reg_dp_block_validate_bsn_at_sync_copi => reg_dp_block_validate_bsn_at_sync_xst_copi,
        reg_dp_block_validate_bsn_at_sync_cipo => reg_dp_block_validate_bsn_at_sync_xst_cipo, 
        
        this_rn   => this_rn,
        N_rn      => ring_info.N_rn,
        rx_select => ring_info.use_cable_to_previous_rn,
        tx_select => ring_info.use_cable_to_next_rn
      );

      -----------------------------------------------------------------------------
      -- Combine seperate signals into array for tr_10GbE
      -----------------------------------------------------------------------------  
      -- QSFP_RX
      lane_rx_cable_sosi_arr(0) <= tr_10gbe_src_out_arr(c_qsfp_if_offset) WHEN ring_info.use_cable_to_previous_rn = '1' ELSE c_dp_sosi_rst; -- use_cable_to_previous_rn=1 -> even lanes receive from cable
      -- QSFP_TX
      tr_10gbe_snk_in_arr(c_qsfp_if_offset) <= lane_tx_cable_sosi_arr(0) WHEN ring_info.use_cable_to_next_rn = '1'      ELSE c_dp_sosi_rst; -- use_cable_to_next_rn=1 -> even lanes transmit to cable
  
      -- RING_0_RX even lanes receive from RING_0 (from the left)
      lane_rx_board_sosi_arr(0) <= tr_10gbe_src_out_arr(c_ring_0_if_offset);
    
      -- RING_1_TX even lanes transmit to RING_1 (to the right)
      tr_10gbe_snk_in_arr(c_ring_1_if_offset) <= lane_tx_board_sosi_arr(0); 

      -----------------------------------------------------------------------------
      -- tr_10GbE
      -----------------------------------------------------------------------------
      u_tr_10GbE: ENTITY tr_10GbE_lib.tr_10GbE
      GENERIC MAP (
        g_sim           => g_sim,
        g_sim_level     => 1,
        g_nof_macs      => c_nof_mac,
        g_direction     => "TX_RX",
        g_tx_fifo_fill  => c_xsub_fifo_tx_fill,
        g_tx_fifo_size  => c_xsub_fifo_tx_size
      )
      PORT MAP (
        -- Transceiver PLL reference clock
        tr_ref_clk_644        => SA_CLK,
        tr_ref_clk_312        => tr_ref_clk_312,  
        tr_ref_clk_156        => tr_ref_clk_156,  
        tr_ref_rst_156        => tr_ref_rst_156,  

        -- MM interface
        mm_rst                => mm_rst,
        mm_clk                => mm_clk,

        reg_mac_mosi          => reg_tr_10GbE_mac_copi,
        reg_mac_miso          => reg_tr_10GbE_mac_cipo,

        reg_eth10g_mosi       => reg_tr_10GbE_eth10g_copi,
        reg_eth10g_miso       => reg_tr_10GbE_eth10g_cipo,

        -- DP interface
        dp_rst                => dp_rst,
        dp_clk                => dp_clk,

        src_out_arr           => tr_10gbe_src_out_arr,
        src_in_arr            => tr_10gbe_src_in_arr,

        snk_out_arr           => tr_10gbe_snk_out_arr,
        snk_in_arr            => tr_10gbe_snk_in_arr,

        -- Serial IO
        serial_tx_arr         => tr_10gbe_serial_tx_arr, 
        serial_rx_arr         => tr_10gbe_serial_rx_arr
      );


      -----------------------------------------------------------------------------
      -- Seperate serial tx/rx array 
      -----------------------------------------------------------------------------  
      -- Seperating the one large serial tx/rx array from tr_10GbE to the 3 port arrays:
      -- QSFP port, RING_0 port and RING_1 port.
      -- QSFP_TX
      unb2_board_front_io_serial_tx_arr(0) <= tr_10gbe_serial_tx_arr(c_qsfp_if_offset); 
      -- QSFP_RX
      tr_10gbe_serial_rx_arr(c_qsfp_if_offset) <= unb2_board_front_io_serial_rx_arr(0); 
    
      -- RING_0_TX 
      RING_0_TX(0) <= tr_10gbe_serial_tx_arr(c_ring_0_if_offset);
      -- RING_0_RX
      tr_10gbe_serial_rx_arr(c_ring_0_if_offset) <= RING_0_RX(0); 
    
      -- RING_1_TX
      RING_1_TX(0) <= tr_10gbe_serial_tx_arr(c_ring_1_if_offset);
      -- RING_1_RX
      tr_10gbe_serial_rx_arr(c_ring_1_if_offset) <= RING_1_RX(0); 
    END GENERATE;
  END GENERATE;

  -----------------------------------------------------------------------------
  -- nof beamsets node_sdp_beamformers (BF)
  -----------------------------------------------------------------------------
  gen_use_bf : IF g_use_bf GENERATE
    -- Beamformers
    gen_bf : FOR beamset_id IN 0 TO c_sdp_N_beamsets-1 GENERATE
      u_bf : ENTITY work.node_sdp_beamformer
      GENERIC MAP(
        g_sim                    => g_sim, 
        g_sim_sdp                => g_sim_sdp,
        g_beamset_id             => beamset_id,
        g_scope_selected_beamlet => g_scope_selected_subband 
      )
      PORT MAP(
        dp_clk                   => dp_clk,  
        dp_rst                   => dp_rst,  
      
        in_sosi_arr              => fsub_sosi_arr, 
        bf_udp_sosi              => bf_udp_sosi_arr(beamset_id),
        bf_udp_siso              => bf_udp_siso_arr(beamset_id),
        bst_udp_sosi             => udp_tx_sosi_arr(2+ beamset_id),  
        bst_udp_siso             => udp_tx_siso_arr(2+ beamset_id),  
      
        mm_rst                   => mm_rst,  
        mm_clk                   => mm_clk,  
      
        ram_ss_ss_wide_mosi      => ram_ss_ss_wide_mosi_arr(beamset_id),  
        ram_ss_ss_wide_miso      => ram_ss_ss_wide_miso_arr(beamset_id), 
        ram_bf_weights_mosi      => ram_bf_weights_mosi_arr(beamset_id), 
        ram_bf_weights_miso      => ram_bf_weights_miso_arr(beamset_id), 
        reg_bf_scale_mosi        => reg_bf_scale_mosi_arr(beamset_id), 
        reg_bf_scale_miso        => reg_bf_scale_miso_arr(beamset_id), 
        reg_hdr_dat_mosi         => reg_hdr_dat_mosi_arr(beamset_id), 
        reg_hdr_dat_miso         => reg_hdr_dat_miso_arr(beamset_id), 
        reg_dp_xonoff_mosi       => reg_dp_xonoff_mosi_arr(beamset_id), 
        reg_dp_xonoff_miso       => reg_dp_xonoff_miso_arr(beamset_id), 
        ram_st_bst_mosi          => ram_st_bst_mosi_arr(beamset_id), 
        ram_st_bst_miso          => ram_st_bst_miso_arr(beamset_id), 
        reg_stat_enable_mosi     => reg_stat_enable_bst_mosi_arr(beamset_id),
        reg_stat_enable_miso     => reg_stat_enable_bst_miso_arr(beamset_id),
        reg_stat_hdr_dat_mosi    => reg_stat_hdr_dat_bst_mosi_arr(beamset_id),
        reg_stat_hdr_dat_miso    => reg_stat_hdr_dat_bst_miso_arr(beamset_id),     
 
        sdp_info                 => sdp_info,
        gn_id                    => gn_id,

        bdo_eth_src_mac          => cep_eth_src_mac,
        bdo_ip_src_addr          => cep_ip_src_addr,
        bdo_udp_src_port         => cep_udp_src_port,
        bdo_hdr_fields_out       => bf_10GbE_hdr_fields_out_arr(beamset_id),

        stat_eth_src_mac         => stat_eth_src_mac,
        stat_ip_src_addr         => stat_ip_src_addr, 
        stat_udp_src_port        => bst_udp_src_port
      );
  
    END GENERATE;
  
    -- MM multiplexing
    u_mem_mux_ram_ss_ss_wide : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_ram_ss_ss_wide
    )
    PORT MAP (
      mosi     => ram_ss_ss_wide_mosi,
      miso     => ram_ss_ss_wide_miso,
      mosi_arr => ram_ss_ss_wide_mosi_arr,
      miso_arr => ram_ss_ss_wide_miso_arr
    );
  
    u_mem_mux_ram_bf_weights : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_ram_bf_weights
    )
    PORT MAP (
      mosi     => ram_bf_weights_mosi,
      miso     => ram_bf_weights_miso,
      mosi_arr => ram_bf_weights_mosi_arr,
      miso_arr => ram_bf_weights_miso_arr
    );
  
    u_mem_mux_reg_bf_scale : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_reg_bf_scale
    )
    PORT MAP (
      mosi     => reg_bf_scale_mosi,
      miso     => reg_bf_scale_miso,
      mosi_arr => reg_bf_scale_mosi_arr,
      miso_arr => reg_bf_scale_miso_arr
    );
  
    u_mem_mux_reg_hdr_dat : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_reg_hdr_dat
    )
    PORT MAP (
      mosi     => reg_hdr_dat_mosi,
      miso     => reg_hdr_dat_miso,
      mosi_arr => reg_hdr_dat_mosi_arr,
      miso_arr => reg_hdr_dat_miso_arr
    );
  
    u_mem_mux_reg_dp_xonoff : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_reg_dp_xonoff
    )
    PORT MAP (
      mosi     => reg_dp_xonoff_mosi,
      miso     => reg_dp_xonoff_miso,
      mosi_arr => reg_dp_xonoff_mosi_arr,
      miso_arr => reg_dp_xonoff_miso_arr
    );
  
    u_mem_mux_ram_st_bst : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_addr_w_ram_st_bst
    )
    PORT MAP (
      mosi     => ram_st_bst_mosi,
      miso     => ram_st_bst_miso,
      mosi_arr => ram_st_bst_mosi_arr,
      miso_arr => ram_st_bst_miso_arr
    );

    u_mem_mux_reg_stat_enable_bst : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_sdp_reg_stat_enable_addr_w
    )
    PORT MAP (
      mosi     => reg_stat_enable_bst_mosi,
      miso     => reg_stat_enable_bst_miso,
      mosi_arr => reg_stat_enable_bst_mosi_arr,
      miso_arr => reg_stat_enable_bst_miso_arr
    );
 
    u_mem_mux_reg_stat_hdr_dat_bst : ENTITY common_lib.common_mem_mux
    GENERIC MAP (
      g_nof_mosi    => c_sdp_N_beamsets,
      g_mult_addr_w => c_sdp_reg_stat_hdr_dat_addr_w
    )
    PORT MAP (
      mosi     => reg_stat_hdr_dat_bst_mosi,
      miso     => reg_stat_hdr_dat_bst_miso,
      mosi_arr => reg_stat_hdr_dat_bst_mosi_arr,
      miso_arr => reg_stat_hdr_dat_bst_miso_arr
    );
   
    -----------------------------------------------------------------------------
    -- DP MUX
    -----------------------------------------------------------------------------
    -- Assign hdr_fields to nw_10GbE for ARP/PING functionality. Only the fields: 
    -- eth_src_mac, ip_src_addr and ip_dst_addr are used. Which are identical for
    -- both beamsets.
    nw_10GbE_hdr_fields_in_arr(0) <= bf_10GbE_hdr_fields_out_arr(0);
  
    u_dp_mux : ENTITY dp_lib.dp_mux
    GENERIC MAP (
      g_nof_input => c_sdp_N_beamsets,
      g_sel_ctrl_invert => TRUE,
      g_fifo_size => array_init(0,c_sdp_N_beamsets), --no FIFO used but must match g_nof_input
      g_fifo_fill => array_init(0,c_sdp_N_beamsets) --no FIFO used but must match g_nof_input
    )
    PORT MAP (
      clk => dp_clk,
      rst => dp_rst,
  
      snk_in_arr  => bf_udp_sosi_arr,
      snk_out_arr => bf_udp_siso_arr,
    
      src_out => nw_10gbe_snk_in_arr(0),
      src_in  => nw_10gbe_snk_out_arr(0)
    );

    ---------------
    -- nw_10GbE
    ---------------
    u_nw_10GbE: ENTITY nw_10GbE_lib.nw_10GbE
    GENERIC MAP (
      g_technology    => g_technology,
      g_sim           => g_sim,
      g_sim_level     => 1,
      g_nof_macs      => c_nof_10GbE_offload_streams,
      g_direction     => "TX_RX",
      g_tx_fifo_fill  => c_fifo_tx_fill,
      g_tx_fifo_size  => c_fifo_tx_size,
      g_ip_hdr_field_arr => c_sdp_cep_hdr_field_arr
  
    )
    PORT MAP (
      -- Transceiver PLL reference clock
      tr_ref_clk_644        => SA_CLK,
      tr_ref_clk_312        => tr_ref_clk_312,  
      tr_ref_clk_156        => tr_ref_clk_156,  
      tr_ref_rst_156        => tr_ref_rst_156,  
  
      -- MM interface
      mm_rst                => mm_rst,
      mm_clk                => mm_clk,
  
      reg_mac_mosi          => reg_nw_10GbE_mac_mosi,
      reg_mac_miso          => reg_nw_10GbE_mac_miso,
  
      reg_eth10g_mosi       => reg_nw_10GbE_eth10g_mosi,
      reg_eth10g_miso       => reg_nw_10GbE_eth10g_miso,
  
      -- DP interface
      dp_rst                => dp_rst,
      dp_clk                => dp_clk,
      dp_pps                => dp_pps,
  
      src_out_arr           => nw_10gbe_src_out_arr,
      src_in_arr            => nw_10gbe_src_in_arr,
  
      snk_out_arr           => nw_10gbe_snk_out_arr,
      snk_in_arr            => nw_10gbe_snk_in_arr,
  
      -- Serial IO
      serial_tx_arr         => unb2_board_front_io_serial_tx_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad), 
      serial_rx_arr         => unb2_board_front_io_serial_rx_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad),
  
      hdr_fields_in_arr     => nw_10GbE_hdr_fields_in_arr 
    );
  END GENERATE;
  
  ---------
  -- PLL
  ---------
  u_tech_pll_xgmii_mac_clocks : ENTITY tech_pll_lib.tech_pll_xgmii_mac_clocks
  GENERIC MAP (
    g_technology => g_technology
  )
  PORT MAP (
    refclk_644 => SA_CLK,
    rst_in     => mm_rst,
    clk_156    => tr_ref_clk_156,
    clk_312    => tr_ref_clk_312,
    rst_156    => tr_ref_rst_156,
    rst_312    => OPEN
  );
  
  ------------
  -- LEDs
  ------------
  -- QSFP 1 - Beamlets 
  unb2_board_qsfp_leds_tx_siso_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_snk_out_arr;
  unb2_board_qsfp_leds_tx_sosi_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_snk_in_arr;
  unb2_board_qsfp_leds_rx_sosi_arr(c_nof_10GbE_offload_streams+c_quad-1 DOWNTO c_quad) <= nw_10gbe_src_out_arr;

  -- QSFP 0 - Ring
  unb2_board_qsfp_leds_tx_siso_arr(0 DOWNTO 0) <= tr_10gbe_snk_out_arr(0 DOWNTO 0);
  unb2_board_qsfp_leds_tx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_snk_in_arr(0 DOWNTO 0);
  unb2_board_qsfp_leds_rx_sosi_arr(0 DOWNTO 0) <= tr_10gbe_src_out_arr(0 DOWNTO 0);
END str;