Skip to content
Snippets Groups Projects
Select Git revision
  • d6fae7920d7906bcbb3f434067b305d7de001d0a
  • main default protected
  • L2SS-2357-expand-ruff
  • test-10rc4
  • L2SS-1730
  • L2SS-1650-allow-threads-during-io
  • play-with-merge-trains
  • v0.3.1
  • v0.3.0
  • v0.2.0
  • v0.1.0
11 results

attribute_wrapper.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    io_ddr_cross_domain.vhd 4.66 KiB
    --------------------------------------------------------------------------------
    --
    -- Copyright (C) 2014
    -- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
    -- JIVE (Joint Institute for VLBI in Europe) <http://www.jive.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: Cross clock domain between dvr_clk and ctlr_clk
    -- Description:
    --
    -- Remarks:
    -- . If the dvr_clk=ctlr_clk then the clock domain crossing logic defaults
    --   to wires. However dvr_clk could also be the dp_clk or the mm_clk and then 
    --   the clock domain crossing logic is needed.
    --   No need to cross dvr_start_address and dvr_nof_data, because these
    --   are stable when the dvr_en is stable.
            
    LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib;
    USE IEEE.STD_LOGIC_1164.ALL;
    USE common_lib.common_pkg.ALL;
    USE technology_lib.technology_select_pkg.ALL;
    USE technology_lib.technology_pkg.ALL;
    USE tech_ddr_lib.tech_ddr_pkg.ALL;
    USE dp_lib.dp_stream_pkg.ALL;
    
    ENTITY io_ddr_cross_domain IS
      GENERIC (
        g_cross_domain : BOOLEAN := TRUE;
        g_delay_len    : NATURAL := c_meta_delay_len
      );                      
      PORT (
        -- Driver clock domain
        dvr_clk                : IN  STD_LOGIC;
        dvr_rst                : IN  STD_LOGIC;
        
        dvr_done               : OUT STD_LOGIC;
        dvr_en                 : IN  STD_LOGIC;
        dvr_wr_not_rd          : IN  STD_LOGIC;
        dvr_start_address      : IN  STD_LOGIC_VECTOR;
        dvr_nof_data           : IN  STD_LOGIC_VECTOR;
        dvr_wr_flush_en        : IN  STD_LOGIC := '0';
        
        -- DDR controller clock domain
        ctlr_clk               : IN  STD_LOGIC;
        ctlr_rst               : IN  STD_LOGIC;
        
        ctlr_dvr_done          : IN  STD_LOGIC;
        ctlr_dvr_en            : OUT STD_LOGIC;
        ctlr_dvr_wr_not_rd     : OUT STD_LOGIC;
        ctlr_dvr_start_address : OUT STD_LOGIC_VECTOR;
        ctlr_dvr_nof_data      : OUT STD_LOGIC_VECTOR;
        ctlr_dvr_wr_flush_en   : OUT STD_LOGIC := '0'
      );
    END io_ddr_cross_domain;
    
    
    ARCHITECTURE str OF io_ddr_cross_domain IS
    
      SIGNAL dvr_en_busy  : STD_LOGIC;
      SIGNAL new_dvr_done : STD_LOGIC;
      
    BEGIN 
    
      no_cross : IF g_cross_domain=FALSE GENERATE
        -- dvr_clk --> ctlr_clk
        ctlr_dvr_en            <= dvr_en;
        ctlr_dvr_wr_not_rd     <= dvr_wr_not_rd;
        ctlr_dvr_start_address <= dvr_start_address;
        ctlr_dvr_nof_data      <= dvr_nof_data;
        ctlr_dvr_wr_flush_en   <= dvr_wr_flush_en;
        
        -- ctlr_clk --> dvr_clk
        dvr_done               <= ctlr_dvr_done;
      END GENERATE;
      
      gen_cross : IF g_cross_domain=TRUE GENERATE
        -- dvr_clk --> ctlr_clk
        u_common_spulse_ctlr_dvr_en : ENTITY common_lib.common_spulse
        GENERIC MAP (
          g_delay_len => g_delay_len
        )
        PORT MAP (
          in_rst    => dvr_rst,
          in_clk    => dvr_clk,
          in_pulse  => dvr_en,
          in_busy   => dvr_en_busy,
          out_rst   => ctlr_rst,
          out_clk   => ctlr_clk,
          out_pulse => ctlr_dvr_en
        );
        
        -- Only register into the other clock domain
        ctlr_dvr_wr_not_rd     <= dvr_wr_not_rd     WHEN rising_edge(ctlr_clk);
        ctlr_dvr_start_address <= dvr_start_address WHEN rising_edge(ctlr_clk);
        ctlr_dvr_nof_data      <= dvr_nof_data      WHEN rising_edge(ctlr_clk);
        
        u_common_spulse_ctlr_dvr_wr_flush_en : ENTITY common_lib.common_spulse
        GENERIC MAP (
          g_delay_len => g_delay_len
        )
        PORT MAP (
          in_rst    => dvr_rst,
          in_clk    => dvr_clk,
          in_pulse  => dvr_wr_flush_en,
          out_rst   => ctlr_rst,
          out_clk   => ctlr_clk,
          out_pulse => ctlr_dvr_wr_flush_en
        );
        
        -- ctlr_clk --> dvr_clk
        u_common_async_dvr_done : ENTITY common_lib.common_async
        GENERIC MAP (
          g_rst_level => '0',
          g_delay_len => g_delay_len
        )
        PORT MAP (
          rst  => dvr_rst,
          clk  => dvr_clk,
          din  => ctlr_dvr_done,
          dout => new_dvr_done
        );
        
        -- Ensure previous dvr_done goes low after new dvr_en
        dvr_done <= new_dvr_done AND NOT dvr_en_busy;
          
      END GENERATE;
      
    END str;