diff --git a/applications/lofar2/designs/lofar2_unb2c_sdp_station/lofar2_unb2c_sdp_station.fpga.yaml b/applications/lofar2/designs/lofar2_unb2c_sdp_station/lofar2_unb2c_sdp_station.fpga.yaml index 9a3ae249669c8d0dc3dfb22c799c8c9b8820ba7f..9ba55724965106a49d0e59c79719a844e75e0592 100644 --- a/applications/lofar2/designs/lofar2_unb2c_sdp_station/lofar2_unb2c_sdp_station.fpga.yaml +++ b/applications/lofar2/designs/lofar2_unb2c_sdp_station/lofar2_unb2c_sdp_station.fpga.yaml @@ -523,3 +523,11 @@ peripherals: - { name: g_nof_macs, value: 1 } mm_port_names: - REG_NW_10GBE_ETH10G + + ############################################################################# + # TBUF = Transient Buffer (from node_sdp_transient_buffer.vhd) + ############################################################################# + + - peripheral_name: sdp/sdp_tbuf_registers + mm_port_names: + - REG_SDP_TBUF diff --git a/applications/lofar2/libraries/sdp/hdllib.cfg b/applications/lofar2/libraries/sdp/hdllib.cfg index 155e1d076d43f449f2d139068ec3cfc551e73e9b..f3188e2b3a2d5b70950c5669153355966958566b 100644 --- a/applications/lofar2/libraries/sdp/hdllib.cfg +++ b/applications/lofar2/libraries/sdp/hdllib.cfg @@ -23,6 +23,8 @@ synth_files = src/vhdl/sdp_statistics_offload.vhd src/vhdl/sdp_crosslets_subband_select.vhd src/vhdl/sdp_crosslets_remote_v2.vhd + src/vhdl/sdp_tbuf_pkg.vhd + src/vhdl/sdp_tbuf_registers.vhd src/vhdl/node_sdp_adc_input_and_timing.vhd src/vhdl/node_sdp_filterbank.vhd src/vhdl/node_sdp_oversampled_filterbank.vhd diff --git a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml index e10ec55d9f3bfcf729fe9bdc9bc2a382c15a9d29..090847174d068331f480d5969b3822e24bfb5486 100644 --- a/applications/lofar2/libraries/sdp/sdp.peripheral.yaml +++ b/applications/lofar2/libraries/sdp/sdp.peripheral.yaml @@ -26,7 +26,6 @@ peripherals: - - { field_name: beam_repositioning_flag, mm_width: 1, access_mode: RW, address_offset: 0x4 } - - { field_name: block_period, mm_width: 16, access_mode: RO, address_offset: 0x0 } - - peripheral_name: sdp_crosslets_subband_select # pi_sdp_crosslets_info.py peripheral_description: "SDP crosslets info." mm_ports: @@ -102,7 +101,6 @@ peripherals: mm_width: 32 # = N_complex * W_sub_weight radix: cint16_ir - - peripheral_name: sdp_bf_weights # pi_sdp_bf_weights.py peripheral_description: "SDP Beamformer (BF) weights (= beamlet weights)." parameters: @@ -153,7 +151,6 @@ peripherals: mm_width: 32 # = N_complex * W_bf_weight radix: cint16_ir - - peripheral_name: sdp_bf_scale # pi_sdp_bf_scale.py peripheral_description: "SDP beamlet data output (BDO) scaling and requantization." parameters: @@ -189,7 +186,6 @@ peripherals: field_description: "Not used." address_offset: 0x4 - - peripheral_name: sdp_bdo_destinations peripheral_description: "SDP beamlet data output (BDO) destinations." parameters: @@ -216,7 +212,6 @@ peripherals: - - { field_name: nof_destinations_max, mm_width: 8, access_mode: RO, address_offset: 0x208 } # = 520 = 130 * 4 - - { field_name: nof_blocks_per_packet, mm_width: 8, access_mode: RO, address_offset: 0x20C } # = 524 = 131 * 4 - - peripheral_name: sdp_beamformer_output_hdr_dat # pi_dp_offload_tx_hdr_dat_lofar2_beamformer_output.py peripheral_description: "SDP beamlet data output (BDO) header." mm_ports: @@ -301,7 +296,6 @@ peripherals: - - { field_name: sdp_block_period, mm_width: 16, access_mode: RW, address_offset: 0x8 } - - { field_name: BSN, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x0 } - - peripheral_name: sdp_statistics_offload_hdr_dat_sst # pi_dp_offload_tx_hdr_dat_lofar2_sdp_statistics_offload.py peripheral_description: "SDP statistics offload header for the subband statistics (SST)." mm_ports: @@ -378,7 +372,6 @@ peripherals: - - { field_name: sdp_block_period, mm_width: 16, access_mode: RW, address_offset: 0x8 } - - { field_name: BSN, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x0 } - - peripheral_name: sdp_statistics_offload_hdr_dat_bst # pi_dp_offload_tx_hdr_dat_lofar2_sdp_statistics_offload.py peripheral_description: "SDP statistics offload header for the beamlet statistics (BST)." mm_ports: @@ -455,7 +448,6 @@ peripherals: - - { field_name: block_period, mm_width: 16, access_mode: RW, address_offset: 0x8 } - - { field_name: BSN, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x0 } - - peripheral_name: sdp_statistics_offload_hdr_dat_xst # pi_dp_offload_tx_hdr_dat_lofar2_sdp_statistics_offload.py peripheral_description: "SDP statistics offload header for the cross-subband statistics (XST)." mm_ports: @@ -534,3 +526,33 @@ peripherals: - - { field_name: nof_statistics_per_packet, mm_width: 16, access_mode: RW, address_offset: 0xC } - - { field_name: block_period, mm_width: 16, access_mode: RW, address_offset: 0x8 } - - { field_name: BSN, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x0 } + + - peripheral_name: sdp_tbuf_registers + peripheral_description: "SDP TBUF registers." + parameters: + # Parameters in sdp_pkg.vhd + - { name: A_pn, value: 6 } # A_pn = S_pn / N_pol = 12 / 2 = 6 + mm_ports: + # MM port for sdp_tbuf_registers.vhd + - mm_port_name: REG_SDP_TBUF + mm_port_type: REG + mm_port_span: 32 * MM_BUS_SIZE + mm_port_description: | + "The SDP transient buffer (TBUF) contains registers to control and monitor the recording and dumping." + fields: + - - { field_name: dump_done, mm_width: 1, access_mode: RO, address_offset: 0x48 } + - - { field_name: dump_enables, mm_width: A_pn, access_mode: RW, address_offset: 0x44 } + - - { field_name: dump_start_rsn, mm_width: 32, user_width: 64, radix: uint64, access_mode: RW, address_offset: 0x3C } + - - { field_name: dump_nof_pages, mm_width: 32, access_mode: RW, address_offset: 0x38 } + - - { field_name: dump_start_page, mm_width: 32, access_mode: RW, address_offset: 0x34 } + - - { field_name: dump_interpacket_gap, mm_width: 32, access_mode: RW, address_offset: 0x30 } + - - { field_name: recorded_last_rsn, mm_width: 32, user_width: 64, radix: uint64, access_mode: RO, address_offset: 0x28 } + - - { field_name: recorded_first_rsn, mm_width: 32, user_width: 64, radix: uint64, access_mode: RO, address_offset: 0x20 } + - - { field_name: recorded_nof_samples, mm_width: 32, access_mode: RO, address_offset: 0x1C } + - - { field_name: recorded_last_page, mm_width: 32, access_mode: RO, address_offset: 0x18 } + - - { field_name: recorded_first_page, mm_width: 32, access_mode: RO, address_offset: 0x14 } + - - { field_name: recorded_nof_pages, mm_width: 32, access_mode: RO, address_offset: 0x10 } + - - { field_name: record_enable, mm_width: 1, access_mode: RW, address_offset: 0xC } + - - { field_name: record_all, mm_width: 1, access_mode: RW, address_offset: 0x8 } + - - { field_name: nof_pages_in_buffer, mm_width: 32, access_mode: RO, address_offset: 0x4 } + - - { field_name: nof_samples_per_block, mm_width: 32, access_mode: RO, address_offset: 0x0 } diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd new file mode 100644 index 0000000000000000000000000000000000000000..29bd7d5a7007231b14853d174614eb8991acdd7c --- /dev/null +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_pkg.vhd @@ -0,0 +1,88 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2024 +-- 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 transient data buffer (TBUF) specific constants. +-- Description: See [1] +-- References: +-- . [1] https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Transient+buffer+raw+data +------------------------------------------------------------------------------- +library IEEE, common_lib; +use IEEE.std_logic_1164.all; +use common_lib.common_pkg.all; +use common_lib.common_field_pkg.all; +use work.sdp_pkg.all; + +package sdp_tbuf_pkg is + + ----------------------------------------------------------------------------- + -- TBUF registers + ----------------------------------------------------------------------------- + constant c_sdp_tbuf_registers_nof_hdr_fields : natural := 16; + + -- 'downto' order to fit mm_fields + constant c_sdp_tbuf_registers_field_arr : t_common_field_arr(c_sdp_tbuf_registers_nof_hdr_fields - 1 downto 0) := + -- The expected logic FF usage is 9 * 31 + 3 * 1 + 3 * 64 + 1 * 6 ~= 480 FF. + ( (field_name_pad("dump_done "), "RO", 1, field_default(0)), + (field_name_pad("dump_enables "), "RW", c_sdp_A_pn, field_default(0)), + (field_name_pad("dump_start_rsn "), "RW", 64, field_default(0)), + (field_name_pad("dump_nof_pages "), "RW", 32, field_default(0)), + (field_name_pad("dump_start_page "), "RW", 32, field_default(0)), + (field_name_pad("dump_interpacket_gap "), "RW", 32, field_default(0)), + (field_name_pad("recorded_last_rsn "), "RO", 64, field_default(0)), + (field_name_pad("recorded_first_rsn "), "RO", 64, field_default(0)), + (field_name_pad("recorded_nof_samples "), "RO", 32, field_default(0)), + (field_name_pad("recorded_last_page "), "RO", 32, field_default(0)), + (field_name_pad("recorded_first_page "), "RO", 32, field_default(0)), + (field_name_pad("recorded_nof_pages "), "RO", 32, field_default(0)), + (field_name_pad("record_enable "), "RW", 1, field_default(0)), + (field_name_pad("record_all "), "RW", 1, field_default(0)), + (field_name_pad("nof_pages_in_buffer "), "RO", 32, field_default(0)), + (field_name_pad("nof_samples_per_block"), "RO", 32, field_default(0)) + ); + + -- 'to' order as in document [1] to ease view in wave window + type t_sdp_tbuf_registers is record -- word index + nof_samples_per_block : natural; -- 0 + nof_pages_in_buffer : natural; -- 1 + record_all : std_logic; -- 2 + record_enable : std_logic; -- 3 + recorded_nof_pages : natural; -- 4 + recorded_first_page : natural; -- 5 + recorded_last_page : natural; -- 6 + recorded_nof_samples : natural; -- 7 + recorded_first_rsn : std_logic_vector(63 downto 0); -- 8 + recorded_last_rsn : std_logic_vector(63 downto 0); -- 10 + dump_interpacket_gap : natural; -- 12 + dump_start_page : natural; -- 13 + dump_nof_pages : natural; -- 14 + dump_start_rsn : std_logic_vector(63 downto 0); -- 15 + dump_enables : std_logic_vector(c_sdp_A_pn - 1 downto 0); -- 17 + dump_done : std_logic; -- 18 + end record; + + constant c_sdp_tbuf_registers_rst : t_sdp_tbuf_registers := + (0, 0, '0', '0', 0, 0, 0, 0, (others => '0'), (others => '0'), + 0, 0, 0, (others => '0'), (others => '0'), '0'); + +end sdp_tbuf_pkg; diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_registers.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_registers.vhd new file mode 100644 index 0000000000000000000000000000000000000000..241c4ac6d6dafb4eb8cc847c3aa0eef2602b70a2 --- /dev/null +++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_tbuf_registers.vhd @@ -0,0 +1,141 @@ +------------------------------------------------------------------------------- +-- +-- Copyright 2024 +-- 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: +-- . SDP beamlet data output (BDO) destinations register +-- Description: +-- _________ +-- |mm_fields| +-- | | +-- reg_copi -->| slv_out|------- _wr ---- +-- reg_cipo <--| | | +-- | | v +-- | slv_in|<--+--- _rd <--+<---- _ro +-- |_________| | +-- -----------------> output value +-- +-- where: +-- . _ro = actual nof_destinations, actual nof_blocks_per_packet +-- . output value = tbuf_registers +-- +-- References: +-- 1 https://support.astron.nl/confluence/display/L2M/L2+STAT+Decision%3A+SC+-+SDP+OPC-UA+interface +-- 2 https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Transient+buffer+raw+data +-- + +library IEEE, common_lib, mm_lib; + use IEEE.std_logic_1164.all; + use common_lib.common_pkg.all; + use common_lib.common_mem_pkg.all; + use common_lib.common_field_pkg.all; + use work.sdp_pkg.all; + use work.sdp_tbuf_pkg.all; + +entity sdp_tbuf_registers is + port ( + -- Clocks and reset + mm_clk : in std_logic; + mm_rst : in std_logic; + + dp_clk : in std_logic; + dp_rst : in std_logic; + + reg_copi : in t_mem_copi; + reg_cipo : out t_mem_cipo; + + -- read only (RO) values + tbuf_registers_ro : in t_sdp_tbuf_registers; + + -- write and RO values + tbuf_registers : out t_sdp_tbuf_registers + ); +end sdp_tbuf_registers; + +architecture str of sdp_tbuf_registers is + constant c_field_arr : t_common_field_arr(c_sdp_tbuf_registers_nof_hdr_fields - 1 downto 0) := c_sdp_tbuf_registers_field_arr; + + signal mm_fields_in : std_logic_vector(field_slv_in_len(c_field_arr) - 1 downto 0); + signal mm_fields_out : std_logic_vector(field_slv_out_len(c_field_arr) - 1 downto 0); + + signal tbuf_registers_rd : t_sdp_tbuf_registers := c_sdp_tbuf_registers_rst; + signal tbuf_registers_wr : t_sdp_tbuf_registers := c_sdp_tbuf_registers_rst; +begin + tbuf_registers <= tbuf_registers_rd; + + p_tbuf_registers_rd : process(tbuf_registers_wr, tbuf_registers_ro) + begin + -- default read what was written for read/write (RW) fields + tbuf_registers_rd <= tbuf_registers_wr; + + -- overrule read only (RO) fields + tbuf_registers_rd.nof_samples_per_block <= tbuf_registers_ro.nof_samples_per_block; + tbuf_registers_rd.nof_pages_in_buffer <= tbuf_registers_ro.nof_pages_in_buffer; + tbuf_registers_rd.recorded_nof_pages <= tbuf_registers_ro.recorded_nof_pages; + tbuf_registers_rd.recorded_first_page <= tbuf_registers_ro.recorded_first_page; + tbuf_registers_rd.recorded_last_page <= tbuf_registers_ro.recorded_last_page; + tbuf_registers_rd.recorded_nof_samples <= tbuf_registers_ro.recorded_nof_samples; + tbuf_registers_rd.recorded_first_rsn <= tbuf_registers_ro.recorded_first_rsn; + tbuf_registers_rd.recorded_last_rsn <= tbuf_registers_ro.recorded_last_rsn; + tbuf_registers_rd.dump_done <= tbuf_registers_ro.dump_done; + end process; + + u_mm_fields: entity mm_lib.mm_fields + generic map( + g_cross_clock_domain => true, + g_use_slv_in_val => false, -- use false to save logic when always slv_in_val='1' + g_field_arr => c_field_arr + ) + port map ( + mm_clk => mm_clk, + mm_rst => mm_rst, + + mm_mosi => reg_copi, + mm_miso => reg_cipo, + + slv_clk => dp_clk, + slv_rst => dp_rst, + + slv_in => mm_fields_in, + slv_in_val => '1', + + slv_out => mm_fields_out + ); + + -- add "RO" fields to mm_fields + mm_fields_in(field_hi(c_field_arr, "dump_done") downto field_lo(c_field_arr, "dump_done")) <= slv(tbuf_registers_rd.dump_done); -- 1 + mm_fields_in(field_hi(c_field_arr, "recorded_last_rsn") downto field_lo(c_field_arr, "recorded_last_rsn")) <= tbuf_registers_rd.recorded_last_rsn; -- 64 + mm_fields_in(field_hi(c_field_arr, "recorded_first_rsn") downto field_lo(c_field_arr, "recorded_first_rsn")) <= tbuf_registers_rd.recorded_first_rsn; -- 64 + mm_fields_in(field_hi(c_field_arr, "recorded_nof_samples") downto field_lo(c_field_arr, "recorded_nof_samples")) <= to_uvec(tbuf_registers_rd.recorded_nof_samples, 32); + mm_fields_in(field_hi(c_field_arr, "recorded_last_page") downto field_lo(c_field_arr, "recorded_last_page")) <= to_uvec(tbuf_registers_rd.recorded_last_page, 32); + mm_fields_in(field_hi(c_field_arr, "recorded_first_page") downto field_lo(c_field_arr, "recorded_first_page")) <= to_uvec(tbuf_registers_rd.recorded_first_page, 32); + mm_fields_in(field_hi(c_field_arr, "recorded_nof_pages") downto field_lo(c_field_arr, "recorded_nof_pages")) <= to_uvec(tbuf_registers_rd.recorded_nof_pages, 32); + mm_fields_in(field_hi(c_field_arr, "nof_pages_in_buffer") downto field_lo(c_field_arr, "nof_pages_in_buffer")) <= to_uvec(tbuf_registers_rd.nof_pages_in_buffer, 32); + mm_fields_in(field_hi(c_field_arr, "nof_samples_per_block") downto field_lo(c_field_arr, "nof_samples_per_block")) <= to_uvec(tbuf_registers_rd.nof_samples_per_block, 32); + + -- get "RW" fields from mm_fields + tbuf_registers_wr.dump_enables <= mm_fields_out(field_hi(c_field_arr, "dump_enables") downto field_lo(c_field_arr, "dump_enables")); + tbuf_registers_wr.dump_start_rsn <= mm_fields_out(field_hi(c_field_arr, "dump_start_rsn") downto field_lo(c_field_arr, "dump_start_rsn")); + tbuf_registers_wr.dump_nof_pages <= to_uint(mm_fields_out(field_hi(c_field_arr, "dump_nof_pages") downto field_lo(c_field_arr, "dump_nof_pages"))); + tbuf_registers_wr.dump_start_page <= to_uint(mm_fields_out(field_hi(c_field_arr, "dump_start_page") downto field_lo(c_field_arr, "dump_start_page"))); + tbuf_registers_wr.dump_interpacket_gap <= to_uint(mm_fields_out(field_hi(c_field_arr, "dump_interpacket_gap") downto field_lo(c_field_arr, "dump_interpacket_gap"))); + tbuf_registers_wr.record_enable <= sl(mm_fields_out(field_hi(c_field_arr, "record_enable") downto field_lo(c_field_arr, "record_enable"))); + tbuf_registers_wr.record_all <= sl(mm_fields_out(field_hi(c_field_arr, "record_all") downto field_lo(c_field_arr, "record_all"))); +end str;