Skip to content
Snippets Groups Projects
Select Git revision
  • a884b16da1f5549f10f40c32e777a2b977ea6e84
  • MCCS-163 default
  • main
  • sar-277-update-docs-with-examples-for-lrc
  • st-946-automate
  • sar_302-log-fix
  • sar-287_subarray_commands_to_lrc
  • sar_302-POC_await_sub_device_state
  • sat_302_fix_pipelines
  • sar-286_lrc_one_subarry_command
  • sar-286_lrc_improvements
  • sar-288-async-controller
  • sar-276-combine-tango-queue
  • sar-255_remove_nexus_reference
  • sar-275-add-LRC
  • sar-273-add-lrc-attributes
  • sar-272
  • sp-1106-marvin-1230525148-ska-tango-base
  • sp-1106-marvin-813091765-ska-tango-base
  • sar-255/Publish-package-to-CAR
  • mccs-661-device-under-test-fixture
  • mccs-659-pep257-docstring-linting
  • 0.11.3
  • 0.11.2
  • 0.11.1
  • 0.11.0
  • 0.10.1
  • 0.10.0
  • 0.9.1
  • 0.9.0
  • 0.8.1
  • 0.8.0
  • 0.7.2
  • 0.7.1
  • 0.7.0
  • 0.6.6
  • 0.6.5
  • 0.6.4
  • 0.6.3
  • 0.6.2
  • 0.6.1
  • 0.6.0
42 results

SKAMaster_test.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    fft_wide_unit_control.vhd 12.62 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright (C) 2009
    -- 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/>.
    --
    -------------------------------------------------------------------------------
    -- Purpose: Composition of the SOSI output streams for the fft_wide_unit. 
    --
    -- Description: This unit monitors the in_val signal. Based on the assertion of the 
    --              in_val signal it will compose the output sosi streams. The packet-
    --              size equals g_fft.nof_points/g_fft.wb_factor. 
    --              Both the incoming bsn and err fields are written to a fifo. When 
    --              the output is composed the bsn and err field will be read from the 
    --              fifo's. 
    --              Incoming syncs will be detected and the bsn that accompanies the sync
    --              will be stored. When the bsn that is read from the fifo is the same 
    --              as the stored one, the sync will be asserted to the output. 
    --
    -- Remarks:    .The sync interval must be larger that the total amount of pipeline
    --              stages in the FFT. In other words: the fft_wide_unit_control unit 
    --              is not capable of handling more than one sync pulse at a time. 
    --              
    --
    
    library IEEE, common_lib, dp_lib;
    use IEEE.std_logic_1164.ALL;
    use IEEE.numeric_std.ALL;
    use common_lib.common_pkg.ALL; 
    use common_lib.common_mem_pkg.ALL;  
    use dp_lib.dp_stream_pkg.ALL; 
    use work.fft_pkg.ALL;
    
    entity fft_wide_unit_control is
      generic ( 
        g_fft      : t_fft   := c_fft;
        g_nof_ffts : natural := 1
      );
      port (                                     
        rst          : in  std_logic := '0';
        clk          : in  std_logic; 
        in_re_arr    : in  t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0);     
        in_im_arr    : in  t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0);   
        in_val       : in  std_logic;
        ctrl_sosi    : in  t_dp_sosi;                                            -- Inputrecord for tapping off the sync, bsn and err.              
        out_sosi_arr : out t_dp_sosi_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0)  -- Streaming output interface    
      );
    end fft_wide_unit_control;
    
    architecture rtl of fft_wide_unit_control is
    
      constant c_pipe_data       : natural := 3;                                -- Delay depth for the data 
      constant c_pipe_ctrl       : natural := c_pipe_data-1;                    -- Delay depth for the control signals
      constant c_packet_size     : natural := (2**g_fft.nof_chan)*g_fft.nof_points/g_fft.wb_factor; -- Definition of the packet size
      constant c_ctrl_fifo_depth : natural := 16;                               -- Depth of the bsn and err fifo.  
      
      type t_fft_slv_arr2 is array (integer range <>) of t_fft_slv_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0); 
      type state_type     is (s_idle, s_run, s_hold);
      
      type reg_type is record
        out_sosi_arr   : t_dp_sosi_arr(g_nof_ffts*g_fft.wb_factor-1 downto 0); -- Register that holds the streaming interface          
        in_re_arr2_dly : t_fft_slv_arr2(c_pipe_data              -1 downto 0); -- Input registers for the real data 
        in_im_arr2_dly : t_fft_slv_arr2(c_pipe_data              -1 downto 0); -- Input registers for the imag data  
        val_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the valid signal
        sop_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the sop signal
        eop_dly        : std_logic_vector(c_pipe_ctrl            -1 downto 0); -- Delay-register for the eop signal
        sync_detected  : std_logic;                                            -- Register used to detect and pass the sync pulse.
        packet_cnt     : integer;                                              -- Counter to create the packets. 
        state          : state_type;                                           -- The state machine. 
      end record;
    
      signal r, rin   : reg_type;   
      signal bsn      : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
      signal sync_bsn : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
      signal err      : std_logic_vector(c_dp_stream_error_w-1 downto 0);
      signal rd_req   : std_logic; 
      signal rd_req_i : std_logic;
      signal rd_dat_i : std_logic_vector(c_dp_stream_bsn_w  -1 downto 0);
      signal rd_val_i : std_logic;
       
    begin 
      
      ---------------------------------------------------------------
      -- INPUT FIFO FOR BSN
      ---------------------------------------------------------------
      u_bsn_fifo : entity common_lib.common_fifo_sc 
      generic map (
        g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
        g_reset     => FALSE,
        g_init      => FALSE,
        g_dat_w     => c_dp_stream_bsn_w,
        g_nof_words => c_ctrl_fifo_depth
      )
      port map (
        rst     => rst,
        clk     => clk,
        wr_dat  => ctrl_sosi.bsn,
        wr_req  => ctrl_sosi.sop,
        wr_ful  => open ,
        rd_dat  => bsn,
        rd_req  => r.sop_dly(0), 
        rd_emp  => open ,
        rd_val  => open , 
        usedw   => open
      );
    
      ---------------------------------------------------------------
      -- INPUT FIFO FOR ERR
      ---------------------------------------------------------------
      u_error_fifo : entity common_lib.common_fifo_sc 
      generic map (
        g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
        g_reset     => FALSE,
        g_init      => FALSE,
        g_dat_w     => c_dp_stream_error_w,
        g_nof_words => c_ctrl_fifo_depth
      )
      port map (
        rst     => rst,
        clk     => clk,
        wr_dat  => ctrl_sosi.err,
        wr_req  => ctrl_sosi.sop,
        wr_ful  => open ,
        rd_dat  => err,
        rd_req  => r.sop_dly(1), 
        rd_emp  => open ,
        rd_val  => open , 
        usedw   => open
      ); 
      
      ---------------------------------------------------------------
      -- FIFO FOR SYNC-BSN
      ---------------------------------------------------------------
      u_sync_bsn_fifo : entity common_lib.common_fifo_sc 
      generic map (
        g_use_lut   => TRUE,   -- Make this FIFO in logic, since it's only 4 words deep. 
        g_reset     => FALSE,
        g_init      => FALSE,
        g_dat_w     => c_dp_stream_bsn_w,
        g_nof_words => 2
      )
      port map (
        rst     => rst,
        clk     => clk,
        wr_dat  => ctrl_sosi.bsn,
        wr_req  => ctrl_sosi.sync,
        wr_ful  => open ,
        rd_dat  => rd_dat_i,
        rd_req  => rd_req_i,
        rd_emp  => open,
        rd_val  => rd_val_i, 
        usedw   => open
      );  
      
      ---------------------------------------------------------------
      -- CREATE READ-AHEAD FIFO INTERFACE FOR SYNC-BSN
      ---------------------------------------------------------------
      u_fifo_adapter : entity common_lib.common_fifo_rd
      generic map (
        g_dat_w => c_dp_stream_bsn_w
      )
      port map(
        rst        => rst, 
        clk        => clk, 
        -- ST sink: RL = 1
        fifo_req   => rd_req_i,
        fifo_dat   => rd_dat_i,
        fifo_val   => rd_val_i,
        -- ST source: RL = 0
        rd_req     => rd_req,
        rd_dat     => sync_bsn,
        rd_val     => open
      );
    
      rd_req <= r.out_sosi_arr(0).sync; --  (r.sync_detected and not(rd_emp)) or r.rd_first; 
                
      ---------------------------------------------------------------
      -- PROCESS THAT COMPOSES THE SOSI OUTPUT ARRAYS
      ---------------------------------------------------------------
      comb : process(r, rst, ctrl_sosi, in_re_arr, in_im_arr, in_val, sync_bsn, bsn, err)
        variable v : reg_type;
      begin
      
        v := r; 
        
        v.val_dly(0)  := '0';              -- Some defaults, before entering the state machine.              
        v.sop_dly(0)  := '0';                                                              
        v.eop_dly(0)  := '0';                                                              
        
        for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 loop
          v.out_sosi_arr(I).sync  := '0';                                                                  
        end loop; 
                                      
        v.in_re_arr2_dly(0) := in_re_arr;  -- Latch the data into the input registers. 
        v.in_im_arr2_dly(0) := in_im_arr;  -- Latch the data into the input registers. 
        
        v.in_re_arr2_dly(c_pipe_data-1 downto 1) := r.in_re_arr2_dly(c_pipe_data-2 downto 0); -- Shift the delay registers
        v.in_im_arr2_dly(c_pipe_data-1 downto 1) := r.in_im_arr2_dly(c_pipe_data-2 downto 0); -- Shift the delay registers
        v.val_dly(c_pipe_ctrl-1 downto 1)        := r.val_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
        v.sop_dly(c_pipe_ctrl-1 downto 1)        := r.sop_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
        v.eop_dly(c_pipe_ctrl-1 downto 1)        := r.eop_dly(c_pipe_ctrl-2 downto 0);        -- Shift the delay registers
        
        for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 loop
          v.out_sosi_arr(I).sop   := r.sop_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
          v.out_sosi_arr(I).eop   := r.eop_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
          v.out_sosi_arr(I).valid := r.val_dly(c_pipe_ctrl-1);  -- Assign the output of the shiftregisters to the "real" signals
          v.out_sosi_arr(I).bsn   := bsn;                       -- The bsn is read from the FIFO
          v.out_sosi_arr(I).err   := err;                       -- The err is read from the FIFO
          v.out_sosi_arr(I).re    := RESIZE_SVEC(r.in_re_arr2_dly(c_pipe_data-1)(I), c_dp_stream_dsp_data_w); -- Data input is latched-in 
          v.out_sosi_arr(I).im    := RESIZE_SVEC(r.in_im_arr2_dly(c_pipe_data-1)(I), c_dp_stream_dsp_data_w); -- Data input is latched-in 
        end loop; 
        
        if(ctrl_sosi.sync = '1') then                           -- Check which bsn accompanies the sync
          v.sync_detected := '1';
        end if; 
        
        if(sync_bsn = bsn and r.sop_dly(1) = '1' and r.sync_detected = '1') then -- When the next bsn equals the stored bsn 
          for I in g_fft.wb_factor-1 downto 0 loop                                 -- a sync pulse will be generated that 
            v.out_sosi_arr(I).sync  := '1';                                        -- preceeds the sop
          end loop; 
          v.sync_detected := '0';
        end if; 
          
        case r.state is
    	    when s_idle => 
    	    	if(in_val = '1') then                       -- Wait for the first data to arrive
    	    	  v.packet_cnt := 0;                        -- Reset the packet counter
    	    		v.state      := s_run;        
    	    	end if;
    	    	
    	    when s_run =>
    	      v.val_dly(0) := '1';                        -- Assert the valid signal (Stream starts)
    	      v.packet_cnt := r.packet_cnt + 1;           -- Increment the packet-counter when in s_run-state
              
            if(r.packet_cnt = 0) then                   -- First sample marks
              v.sop_dly(0) :='1';                       -- the start of a packet
            elsif(r.packet_cnt = c_packet_size-1) then  -- Last address marks  
              v.eop_dly(0) :='1';                       -- the end of a packet
              v.packet_cnt := 0;                        -- Reset the counter
            end if;     
            
            if(in_val = '0') then                       -- If there is no more data:
              v.state := s_hold;                        -- go wait in the s_hold state
            end if;            
              
          when s_hold =>                                
            if(in_val = '1') then                       -- Wait until new valid data arrives
              v.state := s_run;            
            end if;            
              
    	    when others =>
    	      v.state := s_idle;
    
    	  end case;
        
        if(rst = '1') then 
          v.out_sosi_arr  := (others => c_dp_sosi_rst);  
          v.val_dly       := (others => '0');
          v.sop_dly       := (others => '0');
          v.eop_dly       := (others => '0');
          v.sync_detected := '0'; 
          v.packet_cnt    := 0;
          v.state         := s_idle; 
        end if;
    
        rin <= v;  
     	    	
      end process comb;
      
      regs : process(clk)
      begin 
        if rising_edge(clk) then 
          r <= rin; 
        end if; 
      end process;
      
      -- Connect to the outside world  
      gen_output : for I in g_nof_ffts*g_fft.wb_factor-1 downto 0 generate
        out_sosi_arr(I) <= r.out_sosi_arr(I);
      end generate; 
        
    end rtl;