Skip to content
Snippets Groups Projects
Select Git revision
  • e010829a7313b8e66b540caf92ead44f00dbe865
  • master default protected
  • RTSD-375
  • L2SDP-1134
  • L2SDP-1137
  • L2SDP-LIFT
  • L2SDP-1113
  • HPR-158
8 results

sdp_subband_equalizer.vhd

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    sdp_subband_equalizer.vhd 7.84 KiB
    -------------------------------------------------------------------------------
    --
    -- 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
    -- Purpose: 
    -- . Implements the functionality of the subband equalizer in the subband 
    --   filterbank (Fsub) of the LOFAR2 SDPFW design.
    -- Description:
    -- . The sdp_subband_equalizer.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.
    -- . Subband widths:
    --   - raw_sosi   : g_raw_dat_w bits
    --   - quant_sosi : c_quant_dat_w = g_raw_dat_w - g_raw_fraction_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_equalizer IS
      GENERIC (
        g_gains_file_name    : STRING := "UNUSED";
        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;
        g_raw_fraction_w     : NATURAL   -- default: 0
      );
      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);
        out_raw_sosi_arr   : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
        out_quant_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
      );
    END sdp_subband_equalizer;
    
    ARCHITECTURE str OF sdp_subband_equalizer 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;
    
      CONSTANT c_quant_dat_w : NATURAL := g_raw_dat_w - g_raw_fraction_w;
      
      -- Pipeline requantization to easy timing closure
      CONSTANT c_pipeline_remove_lsb : NATURAL := 1;
      CONSTANT c_pipeline_remove_msb : NATURAL := 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);
      SIGNAL weighted_raw_sosi_arr : t_dp_sosi_arr(g_nof_streams-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_equalizer.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_mms_dp_gain_serial_arr : 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
      );
    
      -----------------------------------------------------------------------------
      -- Requantize 
      -----------------------------------------------------------------------------
    
      gen_dp_requantize : FOR I IN 0 TO g_nof_streams-1 GENERATE
        -- For raw output only round the c_sdp_W_sub_weight_fraction, and keep the
        -- g_raw_fraction_w, so that the output width remains the same as the input
        -- width g_raw_dat_w.
        u_dp_requantize_out_raw : ENTITY dp_lib.dp_requantize
        GENERIC MAP (
          g_complex             => TRUE,
          g_representation      => "SIGNED",
          g_lsb_w               => c_sdp_W_sub_weight_fraction,
          g_lsb_round           => TRUE,
          g_lsb_round_clip      => FALSE,
          g_msb_clip            => TRUE,  -- clip subband overflow
          g_msb_clip_symmetric  => FALSE,
          g_pipeline_remove_lsb => c_pipeline_remove_lsb,
          g_pipeline_remove_msb => c_pipeline_remove_msb,
          g_in_dat_w            => c_gain_out_dat_w,
          g_out_dat_w           => g_raw_dat_w
        )
        PORT MAP (
          rst          => dp_rst,
          clk          => dp_clk,
          -- ST sink
          snk_in       => weighted_raw_sosi_arr(I),
          -- ST source
          src_out      => out_raw_sosi_arr(I)
        );
    
        -- For quant output round the entire fraction, so that the output width
        -- becomes c_quant_dat_w.
        u_dp_requantize_out_quant : ENTITY dp_lib.dp_requantize
        GENERIC MAP (               
          g_complex             => TRUE,  
          g_representation      => "SIGNED",           
          g_lsb_w               => c_sdp_W_sub_weight_fraction + g_raw_fraction_w,
          g_lsb_round           => TRUE,       
          g_lsb_round_clip      => FALSE,      
          g_msb_clip            => TRUE,  -- clip subband overflow
          g_msb_clip_symmetric  => FALSE,      
          g_pipeline_remove_lsb => c_pipeline_remove_lsb,
          g_pipeline_remove_msb => c_pipeline_remove_msb,
          g_in_dat_w            => c_gain_out_dat_w,
          g_out_dat_w           => c_quant_dat_w
        )
        PORT MAP (
          rst          => dp_rst, 
          clk          => dp_clk,
          -- ST sink
          snk_in       => weighted_raw_sosi_arr(I),
          -- ST source
          src_out      => out_quant_sosi_arr(I)
        );
      END GENERATE;
    END str;