Skip to content
Snippets Groups Projects
Select Git revision
  • 459c4417fa337da08eaa47335b814d4974d4dc29
  • 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

generateStationStreams.sh

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    reorder_sequencer.vhd 11.75 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/>.
    --
    -- Purpose: Providing address and control signals for external memory realizing a
    --          reordering of the data. Based on alternating read and writes. 
    --
    --
    -- Description: The values of generic g_reorder_seq determine the rhythm of the 
    --              sequencer. The sequencer is based on the use of a dualpage memory.
    --              While data is written in page 0, page 1 is read. The state machine 
    --              alternated between reads and writes: read periods and write periods.
    --              The number of accesses in a read and wrte period is determined by the 
    --              values of the generic.
    --              The generics are interpreted as addresses in the sosi clock-domain. If the 
    --              datarate and/or the datawidth of the memory interface is higher than the 
    --              sosi domain than the g_data_w_ratio generic can be used to specify the 
    --              that ratio. An example:
    --
    --                          SOSI DOMAIN    MEMORY DOMAIN (DDR3)
    --              Datawidth      64 bits       256 bits
    --              Clockrate     200 MHz        200 MHz
    --
    --              The g_data_w_ratio should be 4 to facilitate this transition 
    
    --              The meaning of the other generics is explained her: 
    --
    --              - wr_chunksize is the number of samples that are written during a write access.
    --                A write access always consists of 1 access. 
    --              - rd_chunksize is the number of samples that are read during a read access.
    --              - rd_nof_chunks is the number of read accesses performed during a read period
    --              - rd_interval defines the number of blocks in between two consecutive reads. 
    --              - gapsize is the address space to be skipped in between two consecutive write or
    --                read periods. Gapsize can be used to create byte-alignment in the memory.
    --              - nof_blocks determines the number of write and read periods before the page 
    --                swap takes place. 
    --               
    --              The example shows the following configuration: 
    --
    --              wr_chunksize    : POSITIVE := 8
    --              rd_chunksize    : POSITIVE := 4;  
    --              rd_nof_chunks   : POSITIVE := 2;  
    --              rd_interval     : POSITIVE := 2;            
    --              gapsize         : NATURAL  := 0;              
    --              nof_blocks      : POSITIVE := 5;              
    
    --                    WR             RD    
    --                 --------       --------
    --                 |0     |       |0,0   |   rd_chunksize  
    --   wr_chunksize  |      |       --------
    --                 |      |       |2,1   |
    --                 --------       --------
    --        gapsize  |      |       |      |
    --                 --------       --------
    --                 |1     |       |1,1   |
    --                 |      |       --------
    --                 |      |       |4,0   |
    --                 --------       --------
    --                 |      |       |      |
    --                 --------       --------
    --                 |2     |       |0,1   |  
    --                 |      |       --------
    --                 |      |       |3,0   |
    --                 --------       --------
    --                 |      |       |      |
    --                 --------       --------
    --                 |3     |       |2,0   |
    --                 |      |       --------
    --                 |      |       |4,1   |
    --                 --------       --------
    --                 |      |       |      |
    --                 --------       -------- 
    --                 |4     |       |1,0   | 
    --                 |      |       -------- 
    --                 |      |       |3,1   | 
    --                 --------       -------- 
    --                 |      |       |      | 
    --                 --------       -------- 
    --                  page 0         page 1
    --            
    --              The index in the write page indicate the write period(0-4)
    --              The first index in the read page indicates the read period(0-4)
    --              The second index in the read page indicates the chunknumber(0-1)  
    --              One can see the influence of rd_interval = 2in the fact there is a gap
    --              of 2 blocks in between two consecutive chunks that ar read. The first
    --              chunck (0,0) is read from the block 0. The second chunk (0,1) is read
    --              from block 2. The third chunk (1,0) is read from block 4. 
    --
    -- Remarks:     If the g_data_w_ratio is used, be sure that the generics wr_chunksize,
    --              rd_chunksize, rd_nof_chunks and gapsize are divisible by g_data_w_ratio.
    
    
    LIBRARY IEEE, common_lib;
    USE IEEE.STD_LOGIC_1164.ALL;
    USE common_lib.common_pkg.ALL;
    USE common_lib.common_mem_pkg.ALL;
    USE work.reorder_pkg.ALL;
    
    ENTITY reorder_sequencer IS
      GENERIC (
        g_reorder_seq   : t_reorder_seq := c_reorder_seq;
        g_data_w_ratio  : POSITIVE := 1                 -- (256/256) Ratio between datawidth of the memory controller and SOSI domain  
     );                                                 -- Used to determine the width of counters. 
      PORT (
        -- Clocks and reset
        dp_rst      : IN  STD_LOGIC;  -- reset synchronous with st_clk
        dp_clk      : IN  STD_LOGIC;  -- other clock domain clock
                    
        en_evt      : OUT STD_LOGIC;
        wr_not_rd   : OUT STD_LOGIC;
                    
        address     : OUT STD_LOGIC_VECTOR;
        burstsize   : OUT STD_LOGIC_VECTOR;
                    
        done        : IN  STD_LOGIC
       );
    END reorder_sequencer;
    
    
    ARCHITECTURE rtl OF reorder_sequencer IS
    
      -- Rescale to memory addressing  
      CONSTANT c_wr_chunksize       : POSITIVE := g_reorder_seq.wr_chunksize/g_data_w_ratio;
      CONSTANT c_rd_chunksize       : POSITIVE := g_reorder_seq.rd_chunksize/g_data_w_ratio;
      CONSTANT c_gapsize            : NATURAL  := g_reorder_seq.gapsize/g_data_w_ratio; 
      
      CONSTANT c_blocksize          : POSITIVE := c_wr_chunksize + c_gapsize;  
      CONSTANT c_page_size          : POSITIVE := c_blocksize * g_reorder_seq.nof_blocks;
      CONSTANT c_mem_size           : POSITIVE := 2*c_page_size;
      CONSTANT c_rd_block_increment : POSITIVE := c_blocksize * g_reorder_seq.rd_interval;
        
      TYPE   state_type is (s_idle, s_write, s_first_write, s_wait_wr, s_read, s_wait_rd);
    
      TYPE reg_type IS RECORD
        rd_page_offset   : NATURAL;
        wr_page_offset   : NATURAL;
        ddr3_en          : STD_LOGIC;
        wr_not_rd        : STD_LOGIC;
        rd_block_offset  : NATURAL;
        rd_chunks_offset : NATURAL;
        wr_block_offset  : NATURAL;
        switch_cnt       : NATURAL RANGE 0 TO g_reorder_seq.rd_nof_chunks; -- Counter that counts the write and read accesses to determine the switch between read and write phase. 
        page_cnt         : NATURAL RANGE 0 TO g_reorder_seq.nof_blocks;    -- Counter that counts the number of write accesses to determine the page-swap. 
        first_write      : STD_LOGIC;
        start_addr       : NATURAL RANGE 0 TO c_mem_size-1;
        burstsize        : NATURAL RANGE 0 TO sel_a_b(c_wr_chunksize > c_rd_chunksize, c_wr_chunksize, c_rd_chunksize);
        state            : state_type;  -- The state machine. 
      END RECORD;
    
      SIGNAL r, rin      : reg_type;
       
    BEGIN 
        
      ---------------------------------------------------------------
      -- CHECK IF PROVIDED GENERICS ARE ALLOWED. 
      ---------------------------------------------------------------
      ASSERT NOT(g_reorder_seq.wr_chunksize /= (g_reorder_seq.rd_nof_chunks*g_reorder_seq.rd_chunksize) AND rising_edge(dp_clk)) REPORT "Total write configuration is different from total read configuration!!!" SEVERITY FAILURE;
        
      p_comb : PROCESS(r, dp_rst, done)
        VARIABLE v : reg_type;
      BEGIN
       
        v         := r;
        v.ddr3_en := '0'; 
        
        CASE r.state IS
          WHEN s_idle => 
            IF(done = '1') THEN     
              v.first_write := '1';
              v.state       := s_first_write;  
            END IF;
    
          WHEN s_first_write =>  
            v.wr_not_rd  := '1'; 
            v.ddr3_en    := '1'; 
            v.start_addr := r.wr_page_offset + r.wr_block_offset;
            v.burstsize  := c_wr_chunksize;
            v.state      := s_wait_wr;
            
          WHEN s_write =>  
            IF(done = '1') THEN 
              v.wr_not_rd  := '1'; 
              v.ddr3_en    := '1';
              v.start_addr := r.wr_page_offset + r.wr_block_offset;                   
              v.burstsize  := c_wr_chunksize;
              v.state      := s_wait_wr; 
            END IF;
    
          WHEN s_wait_wr =>      
            v.wr_block_offset := r.wr_block_offset + c_blocksize;
            v.page_cnt        := r.page_cnt + 1;
            v.switch_cnt      := 0; 
            v.state           := s_read;
          
          WHEN s_read => 
            IF(done = '1') THEN 
              v.wr_not_rd := '0'; 
              IF( r.first_write = '0') THEN 
                v.ddr3_en := '1'; 
              END IF; 
              v.start_addr  := r.rd_page_offset + r.rd_block_offset + r.rd_chunks_offset; 
              v.burstsize   := c_rd_chunksize;
              v.switch_cnt  := r.switch_cnt + 1; 
              v.state       := s_wait_rd;
            END IF;
      
          WHEN s_wait_rd => 
    
            v.rd_block_offset := r.rd_block_offset + c_rd_block_increment;
            
            IF(r.rd_block_offset + c_rd_block_increment >= c_page_size) THEN
              v.rd_chunks_offset := r.rd_chunks_offset + c_rd_chunksize;   
              v.rd_block_offset  := r.rd_block_offset + c_rd_block_increment - c_page_size;     
            END IF;
    
            IF(r.switch_cnt = g_reorder_seq.rd_nof_chunks) THEN 
              v.switch_cnt := 0; 
              v.state      := s_write;
              IF(r.page_cnt = g_reorder_seq.nof_blocks) THEN 
                v.rd_page_offset   := r.wr_page_offset;
                v.wr_page_offset   := r.rd_page_offset;
                v.page_cnt         := 0;  
                v.first_write      := '0';
                v.rd_block_offset  := 0;
                v.rd_chunks_offset := 0;
                v.wr_block_offset  := 0;
              END IF; 
            ELSE
              v.state := s_read;
            END IF;  
            
          WHEN OTHERS =>
            v.state := s_idle;
    
        END CASE;
        
        IF(dp_rst = '1') THEN 
          v.rd_page_offset   := c_page_size;
          v.wr_page_offset   := 0;
          v.page_cnt         := 0;
          v.switch_cnt       := 0; 
          v.ddr3_en          := '0';
          v.wr_not_rd        := '0';
          v.wr_block_offset  := 0;
          v.rd_block_offset  := 0;
          v.rd_chunks_offset := 0;
          v.start_addr       := 0;
          v.burstsize        := 0;
          v.first_write      := '1';
          v.state            := s_idle;
        END IF;
    
        rin <= v;  
             
      END PROCESS;
      
      p_regs : PROCESS(dp_clk)
      BEGIN 
        IF RISING_EDGE(dp_clk) THEN 
          r <= rin; 
        END IF; 
      END PROCESS;
    
      en_evt      <= r.ddr3_en;
      wr_not_rd   <= r.wr_not_rd;
      address     <= TO_UVEC(r.start_addr, address'LENGTH);
      burstsize   <= TO_UVEC(r.burstsize,  burstsize'LENGTH);
    
    END rtl;