Skip to content
Snippets Groups Projects
Select Git revision
  • f0f64d7ad8570efae55b95d22830791f1559c50f
  • master default protected
  • optimize_workflow
  • poppy_integration_v50
  • poppy_integration
  • releases/v5.0 protected
  • use-versioned-releases
  • releases/v5.0rc2 protected
  • releases/v5.0rc1 protected
  • releases/ldv_v407_atdb protected
  • ldv_v407_debug
  • releases/ldv_v406_debug protected
  • releases/ldv_v405 protected
  • releases/ldv_v404 protected
  • v5.0
  • v5.0rc2
  • v5.0rc1
  • ldv_v406_debug
  • ldv_v405_debug
  • ldv_v404
  • ldv_v403
  • ldv_v402
  • v4.0
  • ldv_v401
  • ldv_v40
  • ldv_v031
  • ldv_v03
  • ldv_v01
28 results

prefactor_calibrator.cwl

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    dp_offload_tx_legacy.vhd 14.72 KiB
    -------------------------------------------------------------------------------
    --
    -- Copyright (C) 2012
    -- 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, work;
    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 work.dp_stream_pkg.ALL;
    
    ENTITY dp_offload_tx_legacy IS
      GENERIC (
        g_nof_streams             : NATURAL := 1;
        g_data_w                  : NATURAL;
        g_block_size              : NATURAL := 256;   -- The number of words per input block
        g_block_nof_sel_words     : NATURAL := 20;    -- The maximum number of words we select from each input block.
        g_nof_words_per_pkt       : NATURAL := 360;   -- The maximum number of words per output Tx packet
        g_hdr_nof_words           : NATURAL;          -- The number of words (of width g_data_w) to be added as header for each TX packet, e.g. c_eth_total_header_nof_words
        g_use_complex             : BOOLEAN := FALSE; -- TRUE uses re(0..g_data_w/2 -1) & im(0..g_data_w/2-1) as input instead of data(0..g_data_w-1).
        g_use_input_fifo          : BOOLEAN := FALSE; -- TRUE instantiates a shallow input FIFO, e.g. in case source has no flow control
        g_use_output_fifo         : BOOLEAN := TRUE;  -- TRUE to instantiate an output FIFO that buffers an entire packet
        g_input_fifo_bsn_w        : NATURAL := c_dp_stream_bsn_w;
        g_input_fifo_empty_w      : NATURAL := c_dp_stream_empty_w;
        g_input_fifo_channel_w    : NATURAL := c_dp_stream_channel_w;
        g_input_fifo_error_w      : NATURAL := c_dp_stream_error_w;
        g_input_fifo_use_bsn      : BOOLEAN := TRUE;
        g_input_fifo_use_empty    : BOOLEAN := TRUE;
        g_input_fifo_use_channel  : BOOLEAN := TRUE;
        g_input_fifo_use_error    : BOOLEAN := TRUE;
        g_input_fifo_use_sync     : BOOLEAN := TRUE
      ); 
      PORT (
        mm_rst                   : IN  STD_LOGIC;
        mm_clk                   : IN  STD_LOGIC; 
        
        st_rst                   : IN  STD_LOGIC;
        st_clk                   : IN  STD_LOGIC;  
    
        -- MM registers
        reg_hdr_insert_mosi      : IN  t_mem_mosi;
        ram_hdr_insert_mosi      : IN  t_mem_mosi;
    
        reg_dp_split_mosi        : IN  t_mem_mosi;
        reg_dp_split_miso        : OUT t_mem_miso;
    
        reg_dp_pkt_merge_mosi    : IN  t_mem_mosi;
        reg_dp_pkt_merge_miso    : OUT t_mem_miso;
    
        dp_sosi_arr              : IN  t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); 
        dp_siso_arr              : OUT t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);              
    
        tx_sosi_arr              : OUT t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); 
        tx_siso_arr              : IN  t_dp_siso_arr(g_nof_streams-1 DOWNTO 0)                             
      );
    END dp_offload_tx_legacy;
    
    
    ARCHITECTURE str OF dp_offload_tx_legacy IS 
    
      CONSTANT c_fifo_margin               : NATURAL := 10;
      CONSTANT c_dp_pkt_overhead_nof_words : NATURAL := 4+1;
    
      CONSTANT c_hdr_insert_reg_addr_w     : NATURAL := 1; -- Only 1 register used. A width of 1 still yields 2 addresses/instance though.
      CONSTANT c_hdr_insert_ram_addr_w     : NATURAL := ceil_log2( g_hdr_nof_words * (g_data_w/c_word_w) );
    
      -- In case of an uninterruptable stream, the dp_hdr_insert's ready deassertion (during header insertion)
      -- has to be compensated with this input FIFO buffer:
      CONSTANT c_input_fifo_size    : NATURAL := g_hdr_nof_words + c_dp_pkt_overhead_nof_words + c_fifo_margin;
    
      CONSTANT c_output_fifo_fill   : NATURAL := g_hdr_nof_words + c_dp_pkt_overhead_nof_words + g_nof_words_per_pkt;
      CONSTANT c_output_fifo_size   : NATURAL := c_output_fifo_fill + c_fifo_margin;
    
      SIGNAL dp_sel_sosi_arr              : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); 
     
      SIGNAL dp_to_split_sosi_arr         : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL dp_to_split_siso_arr         : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
     
      SIGNAL dp_from_split_sosi_2arr      : t_dp_sosi_2arr_2(g_nof_streams-1 DOWNTO 0);
      SIGNAL dp_from_split_siso_2arr      : t_dp_siso_2arr_2(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL dp_to_pkt_merge_sosi_arr     : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL dp_to_pkt_merge_siso_arr     : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL dp_merged_sosi_arr           : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL dp_merged_siso_arr           : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL udp_tx_pkt_sosi_arr          : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL udp_tx_pkt_siso_arr          : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL udp_tx_hdr_pkt_sosi_arr      : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL udp_tx_hdr_pkt_siso_arr      : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL udp_tx_hdr_pkt_fifo_sosi_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL udp_tx_hdr_pkt_fifo_siso_arr : t_dp_siso_arr(g_nof_streams-1 DOWNTO 0);
    
      SIGNAL reg_hdr_insert_mosi_arr      : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
      SIGNAL ram_hdr_insert_mosi_arr      : t_mem_mosi_arr(g_nof_streams-1 DOWNTO 0);
          
    BEGIN
    
      u_common_mem_mux_hdr_reg : ENTITY common_lib.common_mem_mux
      GENERIC MAP (    
        g_nof_mosi    => g_nof_streams,
        g_mult_addr_w => c_hdr_insert_reg_addr_w
      )
      PORT MAP (
        mosi     => reg_hdr_insert_mosi,
        mosi_arr => reg_hdr_insert_mosi_arr
      );
    
      u_common_mem_mux_hdr_ram : ENTITY common_lib.common_mem_mux
      GENERIC MAP (    
        g_nof_mosi    => g_nof_streams,
        g_mult_addr_w => c_hdr_insert_ram_addr_w
      )
      PORT MAP (
        mosi     => ram_hdr_insert_mosi,
        mosi_arr => ram_hdr_insert_mosi_arr
      );
    
      gen_nof_streams0: FOR i IN 0 TO g_nof_streams-1 GENERATE
    
        ---------------------------------------------------------------------------------------
        -- Select complex input if required
        ---------------------------------------------------------------------------------------
        gen_complex_in : IF g_use_complex = TRUE GENERATE
          p_connect : PROCESS(dp_sosi_arr(i))
          BEGIN
            dp_sel_sosi_arr(i) <= dp_sosi_arr(i);
            dp_sel_sosi_arr(i).data(g_data_w-1 DOWNTO 0) <= dp_sosi_arr(i).re(g_data_w/2-1 DOWNTO 0) & dp_sosi_arr(i).im(g_data_w/2-1 DOWNTO 0);
          END PROCESS;
        END GENERATE;
      
        gen_data_in : IF g_use_complex = FALSE GENERATE
          dp_sel_sosi_arr(i) <= dp_sosi_arr(i);
        END GENERATE;
      
        ---------------------------------------------------------------------------------------
        -- Use a FIFO to buffer only 1 word
        -- Required as dp_split needs to deassert its ready signal periodically
        ---------------------------------------------------------------------------------------
        gen_input_buffer : IF g_use_input_fifo = TRUE GENERATE
          u_buf : ENTITY work.dp_fifo_sc
          GENERIC MAP (
            g_data_w      => g_data_w,
            g_bsn_w       => g_input_fifo_bsn_w,
            g_empty_w     => g_input_fifo_empty_w,
            g_channel_w   => g_input_fifo_channel_w,
            g_error_w     => g_input_fifo_error_w,
            g_use_bsn     => g_input_fifo_use_bsn,
            g_use_empty   => g_input_fifo_use_empty,
            g_use_channel => g_input_fifo_use_channel,
            g_use_error   => g_input_fifo_use_error,
            g_use_sync    => g_input_fifo_use_sync,
            g_use_ctrl    => TRUE,
            g_fifo_size   => 10 -- Use 10 as there's a FIFO margin 
          )
          PORT MAP (
            rst         => st_rst,
            clk         => st_clk,
        
            snk_out     => dp_siso_arr(i),   
            snk_in      => dp_sel_sosi_arr(i),
        
            src_in      => dp_to_split_siso_arr(i),
            src_out     => dp_to_split_sosi_arr(i)
          );
        END GENERATE;
    
      END GENERATE;
      
      ---------------------------------------------------------------------------------------
      -- Throw away words 0..g_block_nof_sel_words-1 of block (0..g_block_size-1)
      ---------------------------------------------------------------------------------------
      u_mms_dp_split : ENTITY work.mms_dp_split
      GENERIC MAP (
        g_nof_streams     => g_nof_streams,
        g_data_w          => g_data_w,
        g_symbol_w        => g_data_w,
        g_nof_symbols_max => g_block_nof_sel_words * (g_data_w / c_byte_w) 
      )
      PORT MAP (
        mm_rst       => mm_rst, 
        mm_clk       => mm_clk,
    
        dp_rst       => st_rst,
        dp_clk       => st_clk,
    
        snk_out_arr  => dp_to_split_siso_arr,
        snk_in_arr   => dp_to_split_sosi_arr,
    
        src_in_2arr  => dp_from_split_siso_2arr,
        src_out_2arr => dp_from_split_sosi_2arr,
    
        reg_mosi     => reg_dp_split_mosi,
        reg_miso     => reg_dp_split_miso
      );
    
      gen_nof_streams1: FOR i IN 0 TO g_nof_streams-1 GENERATE
        dp_from_split_siso_2arr(i)(0) <= c_dp_siso_rdy;
      END GENERATE;
    
      gen_nof_streams2: FOR i IN 0 TO g_nof_streams-1 GENERATE
        ---------------------------------------------------------------------------------------
        -- Use a FIFO when source is uninterrupable: we need to buffer the input during packet 
        -- encoding and header insertion 
        ---------------------------------------------------------------------------------------
        gen_input_fifo : IF g_use_input_fifo = TRUE GENERATE
          u_input_fifo : ENTITY work.dp_fifo_sc
          GENERIC MAP (
            g_data_w      => g_data_w,
            g_bsn_w       => g_input_fifo_bsn_w,
            g_empty_w     => g_input_fifo_empty_w,
            g_channel_w   => g_input_fifo_channel_w,
            g_error_w     => g_input_fifo_error_w,
            g_use_bsn     => g_input_fifo_use_bsn,
            g_use_empty   => g_input_fifo_use_empty,
            g_use_channel => g_input_fifo_use_channel,
            g_use_error   => g_input_fifo_use_error,
            g_use_sync    => g_input_fifo_use_sync,
            g_use_ctrl    => TRUE,
            g_fifo_size   => c_input_fifo_size
          )
          PORT MAP (
            rst         => st_rst,
            clk         => st_clk,
        
            snk_out     => dp_from_split_siso_2arr(i)(1),   
            snk_in      => dp_from_split_sosi_2arr(i)(1),
        
            src_in      => dp_to_pkt_merge_siso_arr(i),
            src_out     => dp_to_pkt_merge_sosi_arr(i)
          );
        END GENERATE;
      
        no_input_fifo : IF g_use_input_fifo = FALSE GENERATE
          dp_to_pkt_merge_sosi_arr(i) <= dp_from_split_sosi_2arr(i)(1);
          dp_siso_arr(i)    <= dp_to_pkt_merge_siso_arr(i);
        END GENERATE;
    
      END GENERATE;
      
      ---------------------------------------------------------------------------------------
      -- The packet rate has to be brought down to what the targeted sink can handle.
      -- (e.g. PC; ~80k per second max.) 
      -- G_nof_pkt packets are merged into 1.
      ---------------------------------------------------------------------------------------
      u_dp_packet_merge : ENTITY work.mms_dp_packet_merge
      GENERIC MAP (
        g_nof_streams => g_nof_streams,
        g_nof_pkt     => g_nof_words_per_pkt -- Support merging 360*1 word
      )
      PORT MAP (
        mm_rst       => mm_rst, 
        mm_clk       => mm_clk,
    
        dp_rst       => st_rst,
        dp_clk       => st_clk,
    
        snk_out_arr  => dp_to_pkt_merge_siso_arr,
        snk_in_arr   => dp_to_pkt_merge_sosi_arr,
    
        src_in_arr   => dp_merged_siso_arr,
        src_out_arr  => dp_merged_sosi_arr,
    
        reg_mosi     => reg_dp_pkt_merge_mosi,
        reg_miso     => reg_dp_pkt_merge_miso
      );
     
      gen_nof_streams3: FOR i IN 0 TO g_nof_streams-1 GENERATE
        ---------------------------------------------------------------------------------------
        -- Convert DP to packetized DP
        ---------------------------------------------------------------------------------------
        u_dp_packet_enc : ENTITY work.dp_packet_enc
        GENERIC MAP (
          g_data_w => g_data_w
        )
        PORT MAP (
          rst       => st_rst,
          clk       => st_clk,
      
          snk_out   => dp_merged_siso_arr(i),
          snk_in    => dp_merged_sosi_arr(i),
      
          src_in    => udp_tx_pkt_siso_arr(i),
          src_out   => udp_tx_pkt_sosi_arr(i)
        );        
      
        ---------------------------------------------------------------------------------------
        -- Add header to DP packet
        ---------------------------------------------------------------------------------------
        u_hdr_insert : ENTITY work.dp_hdr_insert
        GENERIC MAP (
          g_data_w        => g_data_w,
          g_symbol_w      => c_byte_w,
          g_hdr_nof_words => g_hdr_nof_words
        )
        PORT MAP (
          mm_rst      => mm_rst,
          mm_clk      => mm_clk, 
                                 
          st_rst      => st_rst, 
          st_clk      => st_clk, 
      
          reg_mosi    => reg_hdr_insert_mosi_arr(i),  
          ram_mosi    => ram_hdr_insert_mosi_arr(i),                           
                                 
          snk_out     => udp_tx_pkt_siso_arr(i),
          snk_in      => udp_tx_pkt_sosi_arr(i),
                                 
          src_in      => udp_tx_hdr_pkt_siso_arr(i),
          src_out     => udp_tx_hdr_pkt_sosi_arr(i)
        );
      
        ---------------------------------------------------------------------------------------
        -- FIFO so we can deliver packets to the ETH module fast enough
        ---------------------------------------------------------------------------------------
        gen_output_fifo: IF g_use_output_fifo = TRUE GENERATE
          u_dp_fifo_fill : ENTITY work.dp_fifo_fill
          GENERIC MAP (
            g_data_w      => g_data_w,
            g_bsn_w       => 0,
            g_empty_w     => 0,
            g_channel_w   => 0,
            g_error_w     => 0,
            g_use_bsn     => FALSE, -- Don't forward these as all have been encoded by dp_packet_enc
            g_use_empty   => FALSE,
            g_use_channel => FALSE,
            g_use_error   => FALSE,
            g_use_sync    => FALSE,
            g_fifo_fill   => c_output_fifo_fill, --Release packet only when available
            g_fifo_size   => c_output_fifo_size,
            g_fifo_rl     => 1
          )
          PORT MAP (
            rst         => st_rst,
            clk         => st_clk,
      
            snk_out     => udp_tx_hdr_pkt_siso_arr(i),
            snk_in      => udp_tx_hdr_pkt_sosi_arr(i),
      
            src_in      => udp_tx_hdr_pkt_fifo_siso_arr(i),
            src_out     => udp_tx_hdr_pkt_fifo_sosi_arr(i)
          );
        
          udp_tx_hdr_pkt_fifo_siso_arr(i) <= tx_siso_arr(i);
          tx_sosi_arr(i) <= udp_tx_hdr_pkt_fifo_sosi_arr(i); 
        END GENERATE;
      
        gen_no_output_fifo: IF g_use_output_fifo = FALSE GENERATE
          udp_tx_hdr_pkt_siso_arr(i) <= tx_siso_arr(i);
          tx_sosi_arr(i) <= udp_tx_hdr_pkt_sosi_arr(i); 
        END GENERATE;
    
      END GENERATE;
      
    END str;