From e8a9cafbe3999d8f2f5b55744e72db60027daa05 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Wed, 15 Feb 2023 16:15:26 +0100
Subject: [PATCH] Add sdp_subband_weights.vhd and support co pol and cross pol
 weigths.

---
 applications/lofar2/libraries/sdp/hdllib.cfg  |   3 +-
 .../sdp/src/vhdl/sdp_subband_weights.vhd      | 192 ++++++++++++++++++
 2 files changed, 194 insertions(+), 1 deletion(-)
 create mode 100644 applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_weights.vhd

diff --git a/applications/lofar2/libraries/sdp/hdllib.cfg b/applications/lofar2/libraries/sdp/hdllib.cfg
index e351f1ec06..bc0e30b248 100644
--- a/applications/lofar2/libraries/sdp/hdllib.cfg
+++ b/applications/lofar2/libraries/sdp/hdllib.cfg
@@ -7,7 +7,8 @@ hdl_lib_technology =
 synth_files = 
     src/vhdl/sdp_pkg.vhd 
     src/vhdl/sdp_scope.vhd
-    src/vhdl/sdp_subband_equalizer.vhd 
+    src/vhdl/sdp_subband_weights.vhd
+    src/vhdl/sdp_subband_equalizer.vhd
     src/vhdl/sdp_bf_weights.vhd 
     src/vhdl/sdp_beamformer_local.vhd 
     src/vhdl/sdp_beamformer_remote.vhd 
diff --git a/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_weights.vhd b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_weights.vhd
new file mode 100644
index 0000000000..8b9e5b81e1
--- /dev/null
+++ b/applications/lofar2/libraries/sdp/src/vhdl/sdp_subband_weights.vhd
@@ -0,0 +1,192 @@
+-------------------------------------------------------------------------------
+--
+-- Copyright 2020
+-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+--
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+--
+-- Author: R. van der Walle, E. Kooistra (added cross weights)
+-- Purpose: 
+-- . Implements the subband weighting part of the subband equalizer in the
+--   subband filterbank (Fsub) of the LOFAR2 SDPFW design.
+-- Description:
+-- . The sdp_subband_weights.vhd consists of mms_dp_gain_serial_arr.vhd and
+--   some address counter logic to select the address of the subband weight
+--   and a dp_requantize.vhd component.
+-- . There are subband_weights for co-polarization via ram_gains_mosi and
+--   for cross polarization via ram_gains_cross_mosi.
+-- . Default the co-polarization weights are read from g_gains_file_name and
+--   default the cross polarization weights are 0.
+-- . Subband widths:
+--   - raw_sosi   : g_raw_dat_w bits
+-- Remark:
+--
+-------------------------------------------------------------------------------
+
+LIBRARY IEEE, common_lib, dp_lib;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
+USE common_lib.common_mem_pkg.ALL;
+USE dp_lib.dp_stream_pkg.ALL;
+USE work.sdp_pkg.ALL;
+
+ENTITY sdp_subband_weights IS
+  GENERIC (
+    g_gains_file_name    : STRING := "UNUSED";   -- for co-polarization
+    g_nof_streams        : NATURAL := c_sdp_P_pfb;
+    -- Use no default raw width, to force instance to set it
+    g_raw_dat_w          : NATURAL  -- default: c_sdp_W_subband
+  );
+  PORT (
+    dp_clk : IN  STD_LOGIC;
+    dp_rst : IN  STD_LOGIC;
+
+    in_raw_sosi_arr       : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    in_cross_raw_sosi_arr : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+
+    weighted_raw_sosi_arr       : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+    weighted_cross_raw_sosi_arr : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
+
+    mm_rst : IN  STD_LOGIC;
+    mm_clk : IN  STD_LOGIC;
+
+    ram_gains_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
+    ram_gains_miso : OUT t_mem_miso;
+
+    ram_gains_cross_mosi : IN  t_mem_mosi := c_mem_mosi_rst;
+    ram_gains_cross_miso : OUT t_mem_miso
+  );
+END sdp_subband_weights;
+
+ARCHITECTURE str OF sdp_subband_weights IS
+
+  CONSTANT c_gain_addr_w : NATURAL := ceil_log2(c_sdp_Q_fft * c_sdp_N_sub);
+
+  -- Product width, do -1 to skip double sign bit in product
+  CONSTANT c_gain_out_dat_w : NATURAL := c_sdp_W_sub_weight + g_raw_dat_w - 1;
+
+  SIGNAL in_sosi : t_dp_sosi;
+  SIGNAL cnt : NATURAL RANGE 0 TO c_sdp_Q_fft * c_sdp_N_sub-1;
+  SIGNAL gains_rd_address : STD_LOGIC_VECTOR(c_gain_addr_w-1 DOWNTO 0);
+
+BEGIN
+
+  in_sosi <= in_raw_sosi_arr(0);  -- use ctrl from input [0]
+
+  -----------------------------------------------------------------------------
+  -- Counter
+  -----------------------------------------------------------------------------
+  -- The subband weigths per PN are stored as
+  -- (cint16)subband_weights[S_pn/Q_fft]_[Q_fft][N_sub], but have 
+  -- to be applied according the subband data order 
+  -- fsub[S_pn/Q_fft]_[N_sub][Q_fft]. Therefore the counter in 
+  -- sdp_subband_weights.vhd has to account for this difference in order.
+  p_cnt : PROCESS(dp_clk, dp_rst)
+    -- Use short index variables v_Q, v_SUB names in capitals, to ease
+    -- recognizing them as (loop) indices.
+    VARIABLE v_Q, v_SUB : NATURAL;
+  BEGIN
+    IF dp_rst = '1' THEN
+      cnt <= 0;
+      v_Q := 0;
+      v_SUB := 0;
+    ELSIF rising_edge(dp_clk) THEN
+      IF in_sosi.valid = '1' THEN
+        IF in_sosi.eop = '1' THEN
+          v_Q := 0;
+          v_SUB := 0;
+        ELSE
+          IF v_Q >= c_sdp_Q_fft-1 THEN
+            v_Q := 0;
+            IF v_SUB >= c_sdp_N_sub-1 THEN
+              v_SUB := 0;
+            ELSE
+              v_SUB := v_SUB + 1;
+            END IF;
+          ELSE
+            v_Q := v_Q + 1;
+          END IF;
+        END IF;
+        cnt <= v_Q * c_sdp_N_sub + v_SUB;
+      END IF;
+    END IF;
+  END PROCESS;
+  gains_rd_address <= TO_UVEC(cnt, c_gain_addr_w);
+
+  -----------------------------------------------------------------------------
+  -- Gain
+  -----------------------------------------------------------------------------
+  u_gains_co : ENTITY dp_lib.mms_dp_gain_serial_arr
+  GENERIC MAP (
+    g_nof_streams     => g_nof_streams,
+    g_nof_gains       => c_sdp_Q_fft * c_sdp_N_sub,
+    g_complex_data    => TRUE,
+    g_complex_gain    => TRUE,
+    g_gain_w          => c_sdp_W_sub_weight,
+    g_in_dat_w        => g_raw_dat_w,
+    g_out_dat_w       => c_gain_out_dat_w,
+    g_gains_file_name => g_gains_file_name
+  )
+  PORT MAP (
+    -- System
+    mm_rst            =>  mm_rst,
+    mm_clk            =>  mm_clk,
+    dp_rst            =>  dp_rst,
+    dp_clk            =>  dp_clk,
+
+    -- MM interface
+    ram_gains_mosi    =>  ram_gains_mosi,
+    ram_gains_miso    =>  ram_gains_miso,
+    
+    -- ST interface
+    gains_rd_address  =>  gains_rd_address,
+                                           
+    in_sosi_arr       =>  in_raw_sosi_arr,
+    out_sosi_arr      =>  weighted_raw_sosi_arr
+  );
+
+  u_gains_cross : ENTITY dp_lib.mms_dp_gain_serial_arr
+  GENERIC MAP (
+    g_nof_streams     => g_nof_streams,
+    g_nof_gains       => c_sdp_Q_fft * c_sdp_N_sub,
+    g_complex_data    => TRUE,
+    g_complex_gain    => TRUE,
+    g_gain_w          => c_sdp_W_sub_weight,
+    g_in_dat_w        => g_raw_dat_w,
+    g_out_dat_w       => c_gain_out_dat_w,
+    g_gains_file_name => "UNUSED"
+  )
+  PORT MAP (
+    -- System
+    mm_rst            =>  mm_rst,
+    mm_clk            =>  mm_clk,
+    dp_rst            =>  dp_rst,
+    dp_clk            =>  dp_clk,
+
+    -- MM interface
+    ram_gains_mosi    =>  ram_gains_cross_mosi,
+    ram_gains_miso    =>  ram_gains_cross_miso,
+
+    -- ST interface
+    gains_rd_address  =>  gains_rd_address,
+
+    in_sosi_arr       =>  in_cross_raw_sosi_arr,
+    out_sosi_arr      =>  weighted_cross_raw_sosi_arr
+  );
+
+END str;
-- 
GitLab