------------------------------------------------------------------------------- -- -- 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, technology_lib, tech_ddr_lib, common_lib, dp_lib; USE IEEE.STD_LOGIC_1164.ALL; USE common_lib.common_pkg.ALL; USE common_lib.common_mem_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 mms_io_ddr IS GENERIC( g_sim_model : BOOLEAN := FALSE; g_technology : NATURAL := c_tech_select_default; g_tech_ddr : t_c_tech_ddr; g_wr_data_w : NATURAL := 32; g_wr_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO, >=16 and independent of wr burst size, default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K g_rd_fifo_depth : NATURAL := 256; -- defined at DDR side of the FIFO, >=16 AND > max number of rd burst sizes (so > c_rd_fifo_af_margin), default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K g_rd_data_w : NATURAL := 32; g_wr_flush_mode : STRING := "VAL"; -- "VAL", "SOP", "SYN" g_wr_flush_use_channel : BOOLEAN := FALSE; g_wr_flush_start_channel : NATURAL := 0; g_wr_flush_nof_channels : POSITIVE := 1 ); PORT ( -- DDR reference clock ctlr_ref_clk : IN STD_LOGIC; ctlr_ref_rst : IN STD_LOGIC; -- DDR controller clock domain ctlr_clk_out : OUT STD_LOGIC; ctlr_rst_out : OUT STD_LOGIC; ctlr_clk_in : IN STD_LOGIC; -- connect ctlr_clk_out to ctlr_clk_in at top level to avoid potential delta-cycle differences between the same clock ctlr_rst_in : IN STD_LOGIC; -- connect ctlr_rst_out to ctlr_rst_in at top level -- MM clock + reset mm_rst : IN STD_LOGIC := '1'; mm_clk : IN STD_LOGIC := '0'; -- MM interface reg_io_ddr_mosi : IN t_mem_mosi := c_mem_mosi_rst; -- register for DDR controller status info reg_io_ddr_miso : OUT t_mem_miso; -- Write FIFO clock domain wr_clk : IN STD_LOGIC; wr_rst : IN STD_LOGIC; wr_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_wr_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_wr_data_w) )-1 DOWNTO 0); -- for monitoring purposes wr_sosi : IN t_dp_sosi; wr_siso : OUT t_dp_siso; -- Read FIFO clock domain rd_clk : IN STD_LOGIC; rd_rst : IN STD_LOGIC; rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_rd_data_w) )-1 DOWNTO 0); rd_sosi : OUT t_dp_sosi; rd_siso : IN t_dp_siso; -- DDR3 pass on termination control from master to slave controller term_ctrl_out : OUT t_tech_ddr3_phy_terminationcontrol; term_ctrl_in : IN t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst; -- DDR3 PHY external interface phy3_in : IN t_tech_ddr3_phy_in := c_tech_ddr3_phy_in_x; phy3_io : INOUT t_tech_ddr3_phy_io; phy3_ou : OUT t_tech_ddr3_phy_ou; -- DDR4 PHY external interface phy4_in : IN t_tech_ddr4_phy_in := c_tech_ddr4_phy_in_x; phy4_io : INOUT t_tech_ddr4_phy_io; phy4_ou : OUT t_tech_ddr4_phy_ou ); END mms_io_ddr; ARCHITECTURE str OF mms_io_ddr IS SIGNAL mm_dvr_miso : t_mem_ctlr_miso; SIGNAL mm_dvr_mosi : t_mem_ctlr_mosi; SIGNAL reg_io_ddr_mosi_arr : t_mem_mosi_arr(1 DOWNTO 0); SIGNAL reg_io_ddr_miso_arr : t_mem_miso_arr(1 DOWNTO 0); BEGIN -- Combine the reg map of io_ddr and io_ddr_reg u_common_mem_mux : ENTITY common_lib.common_mem_mux GENERIC MAP ( g_nof_mosi => 2, g_mult_addr_w => ceil_log2(8) ) PORT MAP ( mosi => reg_io_ddr_mosi, miso => reg_io_ddr_miso, mosi_arr => reg_io_ddr_mosi_arr, miso_arr => reg_io_ddr_miso_arr ); u_io_ddr : ENTITY work.io_ddr GENERIC MAP ( g_sim_model => g_sim_model, g_technology => g_technology, g_tech_ddr => g_tech_ddr, g_cross_domain_dvr_ctlr => TRUE, -- mm_dvr_mosi from io_ddr_reg is in mm_clk domain and needs be crossed to the ctlr_clk_in domain by io_ddr_cross_domain in io_ddr g_wr_data_w => g_wr_data_w, g_wr_fifo_depth => g_wr_fifo_depth, g_rd_fifo_depth => g_rd_fifo_depth, g_rd_data_w => g_rd_data_w, g_wr_flush_mode => g_wr_flush_mode, g_wr_flush_use_channel => FALSE, g_wr_flush_start_channel => 0, g_wr_flush_nof_channels => 1 ) PORT MAP ( -- DDR reference clock ctlr_ref_clk => ctlr_ref_clk, ctlr_ref_rst => ctlr_ref_rst, -- DDR controller clock domain ctlr_clk_out => ctlr_clk_out, -- output clock of the ddr controller is used as DP clk. ctlr_rst_out => ctlr_rst_out, ctlr_clk_in => ctlr_clk_in, ctlr_rst_in => ctlr_rst_in, -- MM clock + reset mm_rst => mm_rst, mm_clk => mm_clk, -- MM register map for DDR controller status info reg_io_ddr_mosi => reg_io_ddr_mosi_arr(0), reg_io_ddr_miso => reg_io_ddr_miso_arr(0), -- Driver clock domain dvr_clk => mm_clk, dvr_rst => mm_rst, dvr_miso => mm_dvr_miso, dvr_mosi => mm_dvr_mosi, -- Write FIFO clock domain wr_clk => wr_clk, wr_rst => wr_rst, wr_fifo_usedw => OPEN, wr_sosi => wr_sosi, wr_siso => wr_siso, -- Read FIFO clock domain rd_clk => rd_clk, rd_rst => rd_rst, rd_fifo_usedw => OPEN, rd_sosi => rd_sosi, rd_siso => rd_siso, term_ctrl_out => OPEN, term_ctrl_in => OPEN, phy3_in => phy3_in, phy3_io => phy3_io, phy3_ou => phy3_ou, phy4_in => phy4_in, phy4_io => phy4_io, phy4_ou => phy4_ou ); -- MM register map for DDR controller write and read access control via MM u_io_ddr_reg : ENTITY work.io_ddr_reg PORT MAP( -- Clocks and reset mm_rst => mm_rst, mm_clk => mm_clk, -- Memory Mapped Slave in mm_clk domain sla_in => reg_io_ddr_mosi_arr(1), sla_out => reg_io_ddr_miso_arr(1), -- MM registers in st_clk domain dvr_miso => mm_dvr_miso, dvr_mosi => mm_dvr_mosi ); END str;