Skip to content
Snippets Groups Projects
Commit aa8e78a0 authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Use separate sdp_bdo_pkg.vhd for BDO multiple destinations.

parent 70d902c7
No related branches found
No related tags found
1 merge request!357Move func_sdp_bdo_cep_hdr_field_sel_dest() from sdp_bdo_pkg to...
...@@ -14,6 +14,7 @@ synth_files = ...@@ -14,6 +14,7 @@ synth_files =
src/vhdl/sdp_beamformer_remote.vhd src/vhdl/sdp_beamformer_remote.vhd
src/vhdl/sdp_info_reg.vhd src/vhdl/sdp_info_reg.vhd
src/vhdl/sdp_info.vhd src/vhdl/sdp_info.vhd
src/vhdl/sdp_bdo_pkg.vhd
src/vhdl/sdp_bdo_destinations_reg.vhd src/vhdl/sdp_bdo_destinations_reg.vhd
src/vhdl/sdp_beamformer_output.vhd src/vhdl/sdp_beamformer_output.vhd
src/vhdl/sdp_statistics_offload.vhd src/vhdl/sdp_statistics_offload.vhd
......
-------------------------------------------------------------------------------
--
-- Copyright 2023
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
--
-- Author: E. Kooistra
-- Purpose:
-- . This package contains sdp beamlet data output (BDO) specific constants.
-- Description: See [1]
-- References:
-- . [1] https://support.astron.nl/confluence/display/L2M/L4+SDPFW+Decision%3A+Multiple+beamlet+output+destinations
-------------------------------------------------------------------------------
library IEEE, common_lib;
use IEEE.std_logic_1164.all;
use common_lib.common_pkg.all;
use work.sdp_pkg.all;
package sdp_bdo_pkg is
-- Beamlet data output (BDO) for multiple destinations
constant c_sdp_bdo_nof_destinations_max : natural := 16;
constant c_sdp_bdo_reorder_nof_blocks_max : natural := largest(16, c_sdp_cep_nof_blocks_per_packet);
constant c_sdp_bdo_destinations_info_nof_hdr_fields : natural := c_sdp_bdo_nof_destinations_max * 3 + 3; -- = 52 fields
type t_sdp_bdo_destinations_info is record
eth_destination_mac_arr : t_slv_48_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
ip_destination_address_arr : t_slv_32_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
udp_destination_port_arr : t_slv_16_arr(c_sdp_bdo_nof_destinations_max - 1 downto 0);
nof_destinations : natural;
nof_destinations_act : natural;
nof_blocks_per_packet_act : natural;
end record;
constant t_sdp_bdo_destinations_info_rst : t_sdp_bdo_destinations_info :=
( (others => (others => '0')),
(others => (others => '0')),
(others => (others => '0')), 0, 0, 0 );
function func_sdp_bdo_parse_nof_destinations(nof_destinations : natural) return natural;
function func_sdp_bdo_nof_blocks_per_packet_look_up_table return t_natural_arr;
function func_sdp_nof_beamlets_per_block_look_up_table return t_natural_arr;
function func_sdp_nof_beamlets_per_block_look_up_matrix return t_natural_matrix;
end package sdp_bdo_pkg;
package body sdp_bdo_pkg is
function func_sdp_bdo_parse_nof_destinations(nof_destinations : natural) return natural is
begin
if nof_destinations = 0 then
return 1;
elsif nof_destinations > c_sdp_bdo_nof_destinations_max then
return c_sdp_bdo_nof_destinations_max;
else
return nof_destinations;
end if;
end func_sdp_bdo_parse_nof_destinations;
function func_sdp_bdo_nof_blocks_per_packet_look_up_table return t_natural_arr is
variable v_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
begin
-- Determine nof_blocks_per_packet as function of number of destinations D. Use
-- look up table to precalculate the values as constants.
-- . Use same number of nof_blocks_per_packet for each destination.
-- . In total there are maximum c_sdp_bdo_reorder_nof_blocks_max = 16 blocks to
-- distribute over D destinations, so floor(16 / D) per destination yields:
-- D = 1:16 --> 16, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
for D in 1 to c_sdp_bdo_nof_destinations_max loop
v_arr(D) := c_sdp_bdo_reorder_nof_blocks_max / D;
end loop;
-- . With 1 destination c_sdp_cep_nof_blocks_per_packet = 4 can fit in a jumbo frame.
-- . With D destinations D * c_sdp_cep_nof_blocks_per_packet can fit in a jumbo frame,
-- because the number of beamlets per destination reduces by D.
-- . Taking smallest yields the actual maximum number of blocks per packet
-- per destination, as function of number of destinations D:
-- D = 1:16 --> 4, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
for D in 1 to c_sdp_bdo_nof_destinations_max loop
v_arr(D) := smallest(v_arr(D), D * c_sdp_cep_nof_blocks_per_packet);
end loop;
return v_arr;
end func_sdp_bdo_nof_blocks_per_packet_look_up_table;
function func_sdp_nof_beamlets_per_block_look_up_table return t_natural_arr is
variable v_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max);
begin
-- Determine nof_beamlets_per_block as function of number of destinations D. Use
-- look up table to precalculate the values as constants.
-- . In total there are c_sdp_S_sub_bf = 488 dual polarization beamlets to
-- distribute over D destinations, so ceil(488 / D) per destination yields:
-- D = 1:16 --> 488, 244, 163, 122, 98, 82, 70, 61, 55, 49, 45, 41, 38, 35, 33, 31
for D in 1 to c_sdp_bdo_nof_destinations_max loop
v_arr(D) := ceil_div(c_sdp_S_sub_bf, D);
end loop;
return v_arr;
end func_sdp_nof_beamlets_per_block_look_up_table;
function func_sdp_nof_beamlets_per_block_look_up_matrix return t_natural_matrix is
constant c_arr : t_natural_arr(1 to c_sdp_bdo_nof_destinations_max) :=
func_sdp_nof_beamlets_per_block_look_up_table;
variable v_mat : t_natural_matrix(1 to c_sdp_bdo_nof_destinations_max,
1 to c_sdp_bdo_nof_destinations_max);
variable v_hi : natural;
variable v_lo : natural;
begin
-- Determine nof_beamlets_per_block as function of number of destinations DN and
-- destination index DI. Use look up table to precalculate the values as constants.
--
-- * vertical : nof_destinations DN
-- * horizontal : destination index DI
--
-- DI: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
-- DN:
-- 1 488, 0, .................................................................0
-- 2 244, 244, 0 .
-- 3 163, 163, 162, 0 .
-- 4 122, 122, 122, 122, 0 .
-- 5 98, 98, 98, 97, 97, 0 .
-- 6 82, 82, 81, 81, 81, 81, 0 .
-- 7 70, 70, 70, 70, 70, 69, 69, 0 .
-- 8 61, 61, 61, 61, 61, 61, 61, 61, 0 .
-- 9 55, 55, 57, 57, 57, 57, 57, 57, 57, 0 .
-- 10 49, 49, 49, 49, 49, 49, 49, 49, 48, 48, 0 .
-- 11 45, 45, 45, 45, 44, 44, 44, 44, 44, 44, 44, 0 .
-- 12 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 40, 40, 0 .
-- 13 38, 38, 38, 38, 38, 38, 38, 37, 37, 37, 37, 37, 37, 0 .
-- 14 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 34, 34, 0 .
-- 15 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, 32, 32, 0
-- 16 31, 31, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 30, 30, 30
for DN in 1 to c_sdp_bdo_nof_destinations_max loop
v_hi := c_arr(DN);
v_lo := v_hi - 1;
for DI in 1 to c_sdp_bdo_nof_destinations_max loop
-- Default initialize to zero for unused elements
v_mat(DN, DI) := 0;
-- Determine number of destinations in DN with v_hi value and with
-- v_lo value, to distribute in total c_sdp_S_sub_bf beamlets to DN
-- destinations.
if DI * v_hi + (DN - DI) * v_lo <= c_sdp_S_sub_bf then
-- Use v_hi for first destinations DI
v_mat(DN, DI) := v_hi;
else
-- Use v_lo for remaining destinations, if there are any remaining
v_mat(DN, DI) := v_lo;
end if;
end loop;
end loop;
return v_mat;
end func_sdp_nof_beamlets_per_block_look_up_matrix;
end sdp_bdo_pkg;
...@@ -113,8 +113,6 @@ package sdp_pkg is ...@@ -113,8 +113,6 @@ package sdp_pkg is
constant c_sdp_W_local_oscillator_fraction : natural := 15; -- = p in s(w, p) constant c_sdp_W_local_oscillator_fraction : natural := 15; -- = p in s(w, p)
constant c_sdp_W_local_oscillator_magnitude : natural := c_sdp_W_local_oscillator - c_sdp_W_local_oscillator_fraction - 1; -- = 0 constant c_sdp_W_local_oscillator_magnitude : natural := c_sdp_W_local_oscillator - c_sdp_W_local_oscillator_fraction - 1; -- = 0
constant c_sdp_N_ring_nof_mac10g : natural := 3; -- for sdp_station_xsub_ring design. constant c_sdp_N_ring_nof_mac10g : natural := 3; -- for sdp_station_xsub_ring design.
constant c_sdp_N_bdo_nof_destinations_max : natural := 16;
constant c_sdp_N_bdo_reorder_nof_blocks_max : natural := 16;
-- Derived constants -- Derived constants
constant c_sdp_FS_adc : natural := 2**(c_sdp_W_adc - 1); -- full scale FS corresponds to amplitude 1.0, will just cause clipping of +FS to +FS-1 constant c_sdp_FS_adc : natural := 2**(c_sdp_W_adc - 1); -- full scale FS corresponds to amplitude 1.0, will just cause clipping of +FS to +FS-1
...@@ -426,42 +424,6 @@ package sdp_pkg is ...@@ -426,42 +424,6 @@ package sdp_pkg is
constant c_sdp_cep_payload_nof_longwords : natural := c_sdp_cep_nof_beamlets_per_packet / c_sdp_nof_beamlets_per_longword; -- = 976 constant c_sdp_cep_payload_nof_longwords : natural := c_sdp_cep_nof_beamlets_per_packet / c_sdp_nof_beamlets_per_longword; -- = 976
constant c_sdp_cep_packet_nof_longwords : natural := ceil_div(c_sdp_cep_header_len, c_longword_sz) + c_sdp_cep_payload_nof_longwords; -- without tail CRC, the CRC is applied by 10GbE MAC constant c_sdp_cep_packet_nof_longwords : natural := ceil_div(c_sdp_cep_header_len, c_longword_sz) + c_sdp_cep_payload_nof_longwords; -- without tail CRC, the CRC is applied by 10GbE MAC
-- Beamlet data output (BDO) multiple destinations
constant c_sdp_bdo_destinations_info_nof_hdr_fields : natural := c_sdp_N_bdo_nof_destinations_max * 3 + 4; -- = 52 fields
type t_sdp_bdo_destinations_info is record
eth_destination_mac_arr : t_slv_48_arr(c_sdp_N_bdo_nof_destinations_max - 1 downto 0);
ip_destination_address_arr : t_slv_32_arr(c_sdp_N_bdo_nof_destinations_max - 1 downto 0);
udp_destination_port_arr : t_slv_16_arr(c_sdp_N_bdo_nof_destinations_max - 1 downto 0);
nof_destinations : natural;
nof_destinations_act : natural;
nof_blocks_per_packet : natural;
nof_blocks_per_packet_act : natural;
end record;
constant t_sdp_bdo_destinations_info_rst : t_sdp_bdo_destinations_info :=
( (others => (others => '0')),
(others => (others => '0')),
(others => (others => '0')), 0, 0, 0, 0 );
-- Determine maximum nof_blocks_per_packet as function of nof_destinations:
-- . Use same number of nof_blocks_per_packet for each destination.
-- . In total there are maximum c_sdp_N_bdo_reorder_nof_blocks_max = 16 blocks to
-- distribute over N destinations, so floor(16 / N) per destination yields:
-- N = 1:16 --> 16, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
-- . With 1 destination c_sdp_cep_nof_blocks_per_packet = 4 can fit in a jumbo frame.
-- . With N destinations N * c_sdp_cep_nof_blocks_per_packet can fit in a jumbo frame,
-- because the number of beamlets per destination reduces by N.
-- N = 1:16 --> 4 * [1, 2, 3, 4, 5 ,6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
-- . Taking smallest yields the actual maximum number of blocks per packet
-- per destination, as function of nof_destinations N:
-- N = 1:16 --> 4, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1
constant c_sdp_nof_blocks_per_packet_max_per_destination_arr : t_natural_arr(1 to c_sdp_N_bdo_nof_destinations_max) :=
(4, 8, 5, 4, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1);
function func_sdp_parse_nof_destinations(nof_destinations : natural) return natural;
function func_sdp_parse_nof_blocks_per_packet(nof_blocks_per_packet, nof_destinations : natural) return natural;
-- CEP packet header -- CEP packet header
constant c_sdp_cep_nof_hdr_fields : natural := 3 + 12 + 4 + 4 + 9 + 6 + 1; -- = 39 fields constant c_sdp_cep_nof_hdr_fields : natural := 3 + 12 + 4 + 4 + 9 + 6 + 1; -- = 39 fields
-- c_sdp_cep_header_len / c_longword_sz = 74 / 8 = 9.25 64b words = 592b -- c_sdp_cep_header_len / c_longword_sz = 74 / 8 = 9.25 64b words = 592b
...@@ -1044,28 +1006,4 @@ package body sdp_pkg is ...@@ -1044,28 +1006,4 @@ package body sdp_pkg is
end loop; end loop;
return v_info; return v_info;
end func_sdp_step_crosslets_info; end func_sdp_step_crosslets_info;
function func_sdp_parse_nof_destinations(nof_destinations : natural) return natural is
begin
if nof_destinations = 0 then
return 1;
elsif nof_destinations > c_sdp_N_bdo_nof_destinations_max then
return c_sdp_N_bdo_nof_destinations_max;
else
return nof_destinations;
end if;
end func_sdp_parse_nof_destinations;
function func_sdp_parse_nof_blocks_per_packet(nof_blocks_per_packet, nof_destinations : natural) return natural is
constant c_nof_blocks_per_packet_max : natural := c_sdp_nof_blocks_per_packet_max_per_destination_arr(nof_destinations);
begin
if nof_blocks_per_packet = 0 then
return 1;
elsif nof_blocks_per_packet > c_nof_blocks_per_packet_max then
return c_nof_blocks_per_packet_max;
else
return nof_blocks_per_packet;
end if;
end func_sdp_parse_nof_blocks_per_packet;
end sdp_pkg; end sdp_pkg;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment