Skip to content
Snippets Groups Projects
Select Git revision
  • d3cad66f902bf6bc44a2cdba54e1ffae7870b4dd
  • master default protected
  • L2SS-1914-fix_job_dispatch
  • TMSS-3170
  • TMSS-3167
  • TMSS-3161
  • TMSS-3158-Front-End-Only-Allow-Changing-Again
  • TMSS-3133
  • TMSS-3319-Fix-Templates
  • test-fix-deploy
  • TMSS-3134
  • TMSS-2872
  • defer-state
  • add-custom-monitoring-points
  • TMSS-3101-Front-End-Only
  • TMSS-984-choices
  • SDC-1400-Front-End-Only
  • TMSS-3079-PII
  • TMSS-2936
  • check-for-max-244-subbands
  • TMSS-2927---Front-End-Only-PXII
  • Before-Remove-TMSS
  • LOFAR-Release-4_4_318 protected
  • LOFAR-Release-4_4_317 protected
  • LOFAR-Release-4_4_316 protected
  • LOFAR-Release-4_4_315 protected
  • LOFAR-Release-4_4_314 protected
  • LOFAR-Release-4_4_313 protected
  • LOFAR-Release-4_4_312 protected
  • LOFAR-Release-4_4_311 protected
  • LOFAR-Release-4_4_310 protected
  • LOFAR-Release-4_4_309 protected
  • LOFAR-Release-4_4_308 protected
  • LOFAR-Release-4_4_307 protected
  • LOFAR-Release-4_4_306 protected
  • LOFAR-Release-4_4_304 protected
  • LOFAR-Release-4_4_303 protected
  • LOFAR-Release-4_4_302 protected
  • LOFAR-Release-4_4_301 protected
  • LOFAR-Release-4_4_300 protected
  • LOFAR-Release-4_4_299 protected
41 results

tPacketsToBuffer.sh

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    st_sst.vhd 13.17 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright (C) 2011
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
    --
    -- This program is free software: you can redistribute it and/or modify
    -- it under the terms of the GNU General Public License as published by
    -- the Free Software Foundation, either version 3 of the License, or
    -- (at your option) any later version.
    --
    -- This program is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -- GNU General Public License for more details.
    --
    -- You should have received a copy of the GNU General Public License
    -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
    --
    -------------------------------------------------------------------------------
    
    LIBRARY IEEE, common_lib, mm_lib, technology_lib, dp_lib;
    USE IEEE.std_logic_1164.ALL;
    USE IEEE.math_real.ALL;  -- for sim only
    USE common_lib.common_pkg.ALL;
    USE common_lib.common_mem_pkg.ALL;
    USE common_lib.common_field_pkg.ALL;
    USE dp_lib.dp_stream_pkg.ALL;
    USE technology_lib.technology_select_pkg.ALL;
    
    -- Purpose:
    --   Store the (auto)power statistics of a complex input stream with
    --   blocks of nof_stat multiplexed subbands into a MM register.
    -- Description:                                                          
    --
    --   When the treshold register is set to 0 the statistics will be auto-
    --   correlations.
    --   In case the treshold register is set to a non-zero value, it allows
    --   to create a sample & hold function for the a-input of the multiplier.
    --   The a-input of the multiplier is updated every "treshold" clockcycle.
    --   Thereby cross statistics can be created.  
    --  
    --   After each sync the MM register gets updated with the (auto) power statistics
    --   of the previous sync interval. The length of the sync interval determines
    --   the nof accumlations per statistic, hence the integration time. See st_calc
    --   for more details.
    --
    --   View wrdata_power and stat_bin in Wave window to see the stat power
    --   values series.
    --
    -- Remarks:
    -- . The in_sync is assumed to be a pulse an interpreted directly.
    -- . The MM register is single page RAM to save memory resources. Therefore
    --   just after the sync its contents is undefined when it gets written, but
    --   after that its contents remains stable for the rest of the sync interval.
    --   Therefore it is not necessary to use a dual page register that swaps at
    --   the sync. 
    -- . The minimum g_nof_stat = 8. Lower values lead to simulation errors. This is
    --   due to the read latency of 2 of the accumulation memory in the st_calc entity. 
    
    ENTITY st_sst IS
      GENERIC (
        g_technology    : NATURAL := c_tech_select_default;
        g_nof_stat      : NATURAL := 512;   -- total nof accumulators
        g_xst_enable    : BOOLEAN := FALSE; -- when set to true, an extra memory is instantiated to hold the imaginary part of the cross-correlation results
        g_in_data_w     : NATURAL := 18;    -- width o dth edata to be accumulated
        g_stat_data_w   : NATURAL := 54;    -- statistics accumulator width
        g_stat_data_sz  : NATURAL := 2;     -- statistics word width >= statistics accumulator width and fit in a power of 2 multiple 32b MM words
        g_stat_multiplex: NATURAL := 2      -- number of accumulators per stat_bin, for debug purposes with view in Wave window
      );
      PORT (            
        mm_rst          : IN  STD_LOGIC;
        mm_clk          : IN  STD_LOGIC;
        dp_rst          : IN  STD_LOGIC;
        dp_clk          : IN  STD_LOGIC;
                        
        -- Streaming    
        in_complex      : IN  t_dp_sosi;   -- Complex input data
        
        -- Memory Mapped
        ram_st_sst_mosi : IN  t_mem_mosi;  
        ram_st_sst_miso : OUT t_mem_miso;
        reg_st_sst_mosi : IN  t_mem_mosi := c_mem_mosi_rst;  
        reg_st_sst_miso : OUT t_mem_miso := c_mem_miso_rst
      );
    END st_sst;
    
    
    ARCHITECTURE str OF st_sst IS
      
      CONSTANT c_nof_stat_w   : NATURAL := ceil_log2(g_nof_stat);
      CONSTANT c_nof_word     : NATURAL := g_stat_data_sz*g_nof_stat;
      CONSTANT c_nof_word_w   : NATURAL := ceil_log2(c_nof_word);
      CONSTANT g_stat_word_w  : NATURAL := g_stat_data_sz*c_word_w;
      CONSTANT zeros          : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0) := (OTHERS => '0');
      
      -- Statistics register
      CONSTANT c_mm_ram       : t_c_mem := (latency  => 1,
                                            adr_w    => c_nof_word_w,
                                            dat_w    => c_word_w,
                                            nof_dat  => c_nof_word,
                                            init_sl  => '0');           -- MM side : sla_in, sla_out
      CONSTANT c_stat_ram     : t_c_mem := (latency  => 1,
                                            adr_w    => c_nof_stat_w,
                                            dat_w    => g_stat_word_w,
                                            nof_dat  => g_nof_stat,
                                            init_sl  => '0');           -- ST side : stat_mosi
      
      CONSTANT c_field_arr : t_common_field_arr(0 DOWNTO 0) := (0=> ( field_name_pad("treshold"), "RW", c_nof_stat_w, field_default(0) ));
    
      SIGNAL mm_fields_out : STD_LOGIC_VECTOR(field_slv_out_len(c_field_arr)-1 DOWNTO 0);
      SIGNAL treshold      : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
      
      TYPE reg_type IS RECORD
        in_sosi_reg : t_dp_sosi;  
        in_a_re     : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO 0);
        in_a_im     : STD_LOGIC_VECTOR(g_in_data_w -1 DOWNTO 0);
      END RECORD;
      
      SIGNAL r, rin       : reg_type;
      SIGNAL in_sync      : STD_LOGIC;  
    
      SIGNAL stat_data_re : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);
      SIGNAL stat_data_im : STD_LOGIC_VECTOR(g_stat_data_w-1 DOWNTO 0);  
      
      SIGNAL wrdata_re    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
      SIGNAL wrdata_im    : STD_LOGIC_VECTOR(c_mem_data_w-1 DOWNTO 0);
    
      -- Sim only signals for observing wrdata_power with indices in Wave window
      SIGNAL wrdata_power : REAL;
      SIGNAL stat_bin     : NATURAL;
    
      SIGNAL stat_mosi    : t_mem_mosi := c_mem_mosi_rst;
    
      SIGNAL treshold_count : STD_LOGIC_VECTOR(c_nof_stat_w-1 DOWNTO 0);
    
      SIGNAL ram_st_sst_mosi_arr : t_mem_mosi_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_mosi_rst);
      SIGNAL ram_st_sst_miso_arr : t_mem_miso_arr(c_nof_complex-1 DOWNTO 0) := (OTHERS => c_mem_miso_rst);
        
    BEGIN
    
      ------------------------------------------------------------------------------
      -- Register map for the treshold register
      ------------------------------------------------------------------------------
      register_map : ENTITY mm_lib.mm_fields
      GENERIC MAP(
        g_cross_clock_domain => TRUE, 
        g_field_arr          => c_field_arr
      )
      PORT MAP (
        mm_rst  => mm_rst,
        mm_clk  => mm_clk,
    
        mm_mosi => reg_st_sst_mosi, 
        mm_miso => reg_st_sst_miso, 
        
        slv_rst => dp_rst, 
        slv_clk => dp_clk, 
    
        slv_out => mm_fields_out
      );
    
      treshold <= mm_fields_out(field_hi(c_field_arr, "treshold") DOWNTO field_lo(c_field_arr, "treshold"));
      
      ------------------------------------------------------------------------------
      -- Input registers and preparation of the input data for the multiplier. 
      ------------------------------------------------------------------------------
      comb : PROCESS(r, dp_rst, in_complex, treshold_count, treshold)
        VARIABLE v : reg_type;
      BEGIN
        v               := r;
        v.in_sosi_reg   := in_complex; 
        
        IF treshold_count = zeros OR treshold = zeros THEN
          v.in_a_re  := in_complex.re(g_in_data_w-1 DOWNTO 0);
          v.in_a_im  := in_complex.im(g_in_data_w-1 DOWNTO 0);
        END IF;
       
        IF dp_rst = '1' THEN
          v.in_a_re := (OTHERS => '0');
          v.in_a_im := (OTHERS => '0');
        END IF;
          
        rin <= v;
      END PROCESS comb;
      
      regs : PROCESS(dp_clk)
      BEGIN 
        IF rising_edge(dp_clk) THEN 
          r <= rin; 
        END IF; 
      END PROCESS;  
    
      ------------------------------------------------------------------------------
      -- Counter used to detect when treshold is reached in order to load new
      -- input vlaues for the multiplier. 
      ------------------------------------------------------------------------------
      treshold_cnt : ENTITY common_lib.common_counter
      GENERIC MAP(
        g_latency   => 1,            
        g_init      => 0,            
        g_width     => c_nof_stat_w, 
        g_max       => 0,            
        g_step_size => 1            
      )
      PORT MAP (
        rst     => dp_rst,           
        clk     => dp_clk,           
        cnt_clr => in_complex.eop,   
        cnt_en  => in_complex.valid, 
        cnt_max => treshold,
        count   => treshold_count
      );
    
      in_sync <= in_complex.sync;
      
      st_calc : ENTITY work.st_calc
      GENERIC MAP (
        g_technology   => g_technology,
        g_nof_mux      => 1,
        g_nof_stat     => g_nof_stat,
        g_in_dat_w     => g_in_data_w,
        g_out_dat_w    => g_stat_data_w,
        g_out_adr_w    => c_nof_stat_w,
        g_complex      => g_xst_enable
      )
      PORT MAP (
        rst            => dp_rst,
        clk            => dp_clk,
        in_ar          => r.in_a_re,
        in_ai          => r.in_a_im,
        in_br          => r.in_sosi_reg.re(g_in_data_w-1 DOWNTO 0),
        in_bi          => r.in_sosi_reg.im(g_in_data_w-1 DOWNTO 0),
        in_val         => r.in_sosi_reg.valid,
        in_sync        => in_sync,
        out_adr        => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
        out_re         => stat_data_re,
        out_im         => stat_data_im,
        out_val        => stat_mosi.wr,
        out_val_m      => OPEN
      );
    
      -- Auto correlations are unsigned value, cross correlations are signed values
      wrdata_re <= RESIZE_MEM_UDATA(stat_data_re) WHEN g_xst_enable=FALSE ELSE RESIZE_MEM_SDATA(stat_data_re);
      wrdata_im <= RESIZE_MEM_UDATA(stat_data_im) WHEN g_xst_enable=FALSE ELSE RESIZE_MEM_SDATA(stat_data_im);
    
      -- synthesis translate_off
      -- View SST or XST power values in wave window (stat_data_im = 0 for SST)
      wrdata_power <= COMPLEX_RADIUS(TO_SREAL(stat_data_re), TO_SREAL(stat_data_im)) ** 2.0;
    
      stat_bin <= TO_UINT(stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0)) / g_stat_multiplex;
      -- synthesis translate_on
    
      -- For SST or for real part of XST
      stat_reg_re : ENTITY common_lib.common_ram_crw_crw_ratio
      GENERIC MAP (
        g_technology => g_technology,
        g_ram_a      => c_mm_ram,
        g_ram_b      => c_stat_ram,
        g_init_file  => "UNUSED"
      )
      PORT MAP (
        rst_a     => mm_rst,
        clk_a     => mm_clk,
        
        rst_b     => dp_rst,
        clk_b     => dp_clk,
        
        wr_en_a   => ram_st_sst_mosi_arr(0).wr,  -- only for diagnostic purposes, typically statistics are read only
        wr_dat_a  => ram_st_sst_mosi_arr(0).wrdata(c_mm_ram.dat_w-1 DOWNTO 0),
        adr_a     => ram_st_sst_mosi_arr(0).address(c_mm_ram.adr_w-1 DOWNTO 0),
        rd_en_a   => ram_st_sst_mosi_arr(0).rd,
        rd_dat_a  => ram_st_sst_miso_arr(0).rddata(c_mm_ram.dat_w-1 DOWNTO 0),
        rd_val_a  => ram_st_sst_miso_arr(0).rdval,
        
        wr_en_b   => stat_mosi.wr,
        wr_dat_b  => wrdata_re(c_stat_ram.dat_w-1 DOWNTO 0),
        adr_b     => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
        rd_en_b   => '0',
        rd_dat_b  => OPEN,
        rd_val_b  => OPEN
      );                                   
     
      gen_sst: IF g_xst_enable=FALSE GENERATE
        ram_st_sst_mosi_arr(0) <= ram_st_sst_mosi;
        ram_st_sst_miso        <= ram_st_sst_miso_arr(0);
      END GENERATE;
      
      gen_xst: IF g_xst_enable=TRUE GENERATE
        ---------------------------------------------------------------
        -- COMBINE MEMORY MAPPED INTERFACES
        ---------------------------------------------------------------
        -- Combine the internal array of mm interfaces for both real
        -- and imaginary part. 
        u_mem_mux_select : entity common_lib.common_mem_mux
        generic map (    
          g_nof_mosi    => c_nof_complex,
          g_mult_addr_w => c_nof_word_w
        )
        port map (
          mosi     => ram_st_sst_mosi,
          miso     => ram_st_sst_miso,
          mosi_arr => ram_st_sst_mosi_arr,
          miso_arr => ram_st_sst_miso_arr
        );
      
        -- For imaginary part of XST
        stat_reg_im : ENTITY common_lib.common_ram_crw_crw_ratio
        GENERIC MAP (
          g_technology => g_technology,
          g_ram_a      => c_mm_ram,
          g_ram_b      => c_stat_ram,
          g_init_file  => "UNUSED"
        )
        PORT MAP (
          rst_a     => mm_rst,
          clk_a     => mm_clk,
          
          rst_b     => dp_rst,
          clk_b     => dp_clk,
          
          wr_en_a   => ram_st_sst_mosi_arr(1).wr,  -- only for diagnostic purposes, typically statistics are read only
          wr_dat_a  => ram_st_sst_mosi_arr(1).wrdata(c_mm_ram.dat_w-1 DOWNTO 0),
          adr_a     => ram_st_sst_mosi_arr(1).address(c_mm_ram.adr_w-1 DOWNTO 0),
          rd_en_a   => ram_st_sst_mosi_arr(1).rd,
          rd_dat_a  => ram_st_sst_miso_arr(1).rddata(c_mm_ram.dat_w-1 DOWNTO 0),
          rd_val_a  => ram_st_sst_miso_arr(1).rdval,
          
          wr_en_b   => stat_mosi.wr,
          wr_dat_b  => wrdata_im(c_stat_ram.dat_w-1 DOWNTO 0),
          adr_b     => stat_mosi.address(c_stat_ram.adr_w-1 DOWNTO 0),
          rd_en_b   => '0',
          rd_dat_b  => OPEN,
          rd_val_b  => OPEN
        );
      END GENERATE;
      
    END str;