Skip to content
Snippets Groups Projects
Commit 4e963835 authored by Jonathan Hargreaves's avatar Jonathan Hargreaves
Browse files

low level wrapper for DDR3 and DDR4 controller IP

parent 18bc4430
No related branches found
No related tags found
No related merge requests found
--------------------------------------------------------------------------------
--
-- Copyright (C) 2011
-- 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/>.
--
--------------------------------------------------------------------------------
LIBRARY IEEE, common_lib, dp_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE common_lib.common_pkg.ALL;
USE work.ddr3_pkg.ALL;
USE work.ddr_pkg.ALL; -- more general definitions for DDR3 and DDR4
USE dp_lib.dp_stream_pkg.ALL;
ENTITY ddr IS
GENERIC(
g_phy : NATURAL := 1; -- 0: ALTMEMPHY 1: UNIPHY_MASTER 2: UNIPHY_SLAVE 3: ARRIA 10 EMIF
g_ddr : t_c_ddr_phy; -- contains the width information for the DDR interface records
g_mts : NATURAL := 800; -- Megatransfers per second
g_wr_data_w : NATURAL := c_ddr3_ctlr_data_w;
g_wr_use_ctrl : BOOLEAN := FALSE; -- TRUE to allow filling the WR FIFO (by disabling flush) after an EOP
g_wr_fifo_depth : NATURAL := 128; -- >=16 AND >c_ddr3_ctlr_maxburstsize , defined at read side of write FIFO.
g_rd_fifo_depth : NATURAL := 256; -- >=16 AND >c_ddr3_ctlr_maxburstsize > c_ddr3_ctrl_nof_latent_reads, defined at write side of read FIFO.
g_rd_data_w : NATURAL := c_ddr3_ctlr_data_w;
g_flush_wr_fifo : BOOLEAN := FALSE; -- TRUE instantiates a dp_flush + controller to flush the write fifo when the driver is not ready to write
g_flush_sop : BOOLEAN := FALSE;
g_flush_sop_channel : BOOLEAN := FALSE;
g_flush_sop_start_channel : NATURAL := 0;
g_flush_nof_channels : NATURAL := 0
);
PORT (
ctlr_ref_clk : IN STD_LOGIC;
ctlr_rst : IN STD_LOGIC; -- asynchronous reset input to controller
ctlr_gen_clk : OUT STD_LOGIC; -- Controller generated clock
ctlr_gen_rst : OUT STD_LOGIC;
ctlr_gen_clk_2x : OUT STD_LOGIC; -- Controller generated double frequency clock
ctlr_gen_rst_2x : OUT STD_LOGIC; -- ctlr_gen_rst synchronized to ctlr_gen_clk_2x
ctlr_init_done : OUT STD_LOGIC;
ctlr_rdy : OUT STD_LOGIC;
dvr_start_addr : IN t_ddr3_addr;
dvr_end_addr : IN t_ddr3_addr;
dvr_en : IN STD_LOGIC;
dvr_wr_not_rd : IN STD_LOGIC;
dvr_done : OUT STD_LOGIC;
wr_clk : IN STD_LOGIC;
wr_rst : IN STD_LOGIC;
wr_sosi : IN t_dp_sosi;
wr_siso : OUT t_dp_siso;
rd_sosi : OUT t_dp_sosi;
rd_siso : IN t_dp_siso;
rd_clk : IN STD_LOGIC;
rd_rst : IN STD_LOGIC;
rd_fifo_usedw : OUT STD_LOGIC_VECTOR(ceil_log2(g_rd_fifo_depth * (c_ddr3_ctlr_data_w/g_rd_data_w) )-1 DOWNTO 0);
ser_term_ctrl_out : OUT STD_LOGIC_VECTOR(13 DOWNTO 0);
par_term_ctrl_out : OUT STD_LOGIC_VECTOR(13 DOWNTO 0);
ser_term_ctrl_in : IN STD_LOGIC_VECTOR(13 DOWNTO 0) := (OTHERS => '0');
par_term_ctrl_in : IN STD_LOGIC_VECTOR(13 DOWNTO 0) := (OTHERS => '0');
phy_in : IN t_ddr3_phy_in;
phy_io : INOUT t_ddr3_phy_io;
phy_ou : OUT t_ddr3_phy_ou
);
END ddr;
ARCHITECTURE str OF ddr IS
CONSTANT c_wr_fifo_depth : NATURAL := g_wr_fifo_depth * (c_ddr3_ctlr_data_w/g_wr_data_w); -- Multiply fifo depth by the fifo's rd/wr width ratio to get write side depth
CONSTANT c_latency : NATURAL := 1;
SIGNAL ctlr_burst : STD_LOGIC;
SIGNAL ctlr_burst_size : STD_LOGIC_VECTOR(c_ddr3_ctlr_maxburstsize_w-1 DOWNTO 0);
SIGNAL ctlr_address : STD_LOGIC_VECTOR(ceil_log2(g_ddr.cs_w-1) + g_ddr.ba_w + g_ddr.bg_w + g_ddr.a_w + g_ddr.a_col_w - c_ddr3_ctlr_rsl_w-1 DOWNTO 0); -- ceil_log2(..-1) because the chip select lines are converted to a logical address
SIGNAL ctlr_rd_req : STD_LOGIC;
SIGNAL ctlr_wr_req : STD_LOGIC;
SIGNAL ctlr_rst_n : STD_LOGIC;
SIGNAL ctlr_gen_rst_n : STD_LOGIC;
SIGNAL i_ctlr_gen_clk : STD_LOGIC;
SIGNAL i_ctlr_gen_rst : STD_LOGIC;
SIGNAL i_ctlr_gen_clk_2x : STD_LOGIC;
SIGNAL i_ctlr_init_done : STD_LOGIC;
SIGNAL i_ctlr_rdy : STD_LOGIC;
SIGNAL i_dvr_done : STD_LOGIC;
SIGNAL dvr_cur_addr : t_ddr3_addr;
SIGNAL dvr_flush : STD_LOGIC := '0';
SIGNAL ctlr_wr_siso : t_dp_siso := c_dp_siso_rdy; -- default xon='1'
SIGNAL ctlr_wr_sosi : t_dp_sosi;
SIGNAL flush_wr_siso : t_dp_siso;
SIGNAL flush_wr_sosi : t_dp_sosi;
SIGNAL ctlr_rd_siso : t_dp_siso;
SIGNAL ctlr_rd_sosi : t_dp_sosi;
SIGNAL wr_fifo_usedw : STD_LOGIC_VECTOR(ceil_log2(g_wr_fifo_depth)-1 DOWNTO 0); -- read side depth of the write FIFO
-- signals for Arria 10 DDR4
signal mb_a_internal : std_logic_vector(g_ddr.a_w-1 DOWNTO 0);
BEGIN
dvr_done <= i_dvr_done;
ctlr_rst_n <= NOT(ctlr_rst);
i_ctlr_gen_rst <= NOT(ctlr_gen_rst_n);
ctlr_gen_clk <= i_ctlr_gen_clk;
ctlr_gen_rst <= i_ctlr_gen_rst;
ctlr_gen_clk_2x <= i_ctlr_gen_clk_2x;
ctlr_rdy <= i_ctlr_rdy;
ctlr_init_done <= i_ctlr_init_done;
u_wr_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => g_wr_data_w,
g_rd_data_w => c_ddr_local_data_w,
g_use_ctrl => g_wr_use_ctrl,
g_wr_fifo_size => c_wr_fifo_depth,
g_wr_fifo_af_margin => 4 + c_latency, --default (4) + c_latency to compensate for latency introduced by registering wr_siso.ready
g_rd_fifo_rl => 0
)
PORT MAP (
wr_rst => wr_rst,
wr_clk => wr_clk,
rd_rst => i_ctlr_gen_rst,
rd_clk => i_ctlr_gen_clk,
snk_out => wr_siso,
snk_in => wr_sosi,
wr_usedw => OPEN,
rd_usedw => wr_fifo_usedw,
rd_emp => OPEN,
src_in => flush_wr_siso,
src_out => flush_wr_sosi
);
u_dp_flush : ENTITY dp_lib.dp_flush -- Always instantiate the flusher as it also contains a RL adapter
GENERIC MAP (
g_ready_latency => 0,
g_framed_xon => g_wr_use_ctrl, -- stop flushing when dvr_flush is low and a sop has arrived
g_framed_xoff => FALSE -- immediately start flushing when dvr_flush goes high
)
PORT MAP (
rst => i_ctlr_gen_rst,
clk => i_ctlr_gen_clk,
snk_in => flush_wr_sosi,
snk_out => flush_wr_siso,
src_out => ctlr_wr_sosi,
src_in => ctlr_wr_siso, -- fixed streaming xon='1'
flush_en => dvr_flush -- memory mapped xon/xoff control
);
gen_flush : IF g_flush_wr_fifo = TRUE GENERATE
u_flush_ctrl : ENTITY work.ddr3_flush_ctrl
GENERIC MAP (
g_sop => g_flush_sop,
g_sop_channel => g_flush_sop_channel,
g_sop_start_channel => g_flush_sop_start_channel,
g_nof_channels => g_flush_nof_channels
)
PORT MAP (
rst => wr_rst,
clk => wr_clk,
dvr_en => dvr_en,
dvr_wr_not_rd => dvr_wr_not_rd,
dvr_done => i_dvr_done,
wr_sosi => wr_sosi,
dvr_flush => dvr_flush
);
END GENERATE;
u_rd_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
GENERIC MAP (
g_wr_data_w => c_ddr_local_data_w,
g_rd_data_w => g_rd_data_w,
g_use_ctrl => FALSE,
g_wr_fifo_size => g_rd_fifo_depth,
g_wr_fifo_af_margin => c_ddr3_ctrl_nof_latent_reads, -- >=4 (required by dp_fifo)
g_rd_fifo_rl => 1
)
PORT MAP (
wr_rst => i_ctlr_gen_rst,
wr_clk => i_ctlr_gen_clk,
rd_rst => rd_rst,
rd_clk => rd_clk,
snk_out => ctlr_rd_siso,
snk_in => ctlr_rd_sosi,
wr_usedw => OPEN,
rd_usedw => rd_fifo_usedw,
rd_emp => OPEN,
src_in => rd_siso,
src_out => rd_sosi
);
u_ddr3_driver : ENTITY work.ddr3_driver
GENERIC MAP (
g_wr_fifo_depth => g_wr_fifo_depth,
g_ddr => g_ddr
)
PORT MAP (
rst => i_ctlr_gen_rst,
clk => i_ctlr_gen_clk,
ctlr_rdy => i_ctlr_rdy,
ctlr_init_done => i_ctlr_init_done,
ctlr_wr_req => ctlr_wr_req,
ctlr_rd_req => ctlr_rd_req,
ctlr_burst => ctlr_burst,
ctlr_burst_size => ctlr_burst_size,
wr_val => ctlr_wr_sosi.valid,
wr_rdy => ctlr_wr_siso.ready,
rd_rdy => ctlr_rd_siso.ready,
cur_addr => dvr_cur_addr,
start_addr => dvr_start_addr,
end_addr => dvr_end_addr,
dvr_en => dvr_en,
dvr_wr_not_rd => dvr_wr_not_rd,
dvr_done => i_dvr_done,
wr_fifo_usedw => wr_fifo_usedw
);
ctlr_address <= dvr_cur_addr.chip & dvr_cur_addr.bank & dvr_cur_addr.row(g_ddr.a_w-1 DOWNTO 0) & dvr_cur_addr.column(g_ddr.a_col_w -1 DOWNTO c_ddr3_ctlr_rsl_w);
gen_aphy_4g_800 : IF g_mts = 800 AND g_phy = 0 GENERATE
u_aphy_4g_800 : ENTITY work.aphy_4g_800
PORT MAP(
aux_full_rate_clk => i_ctlr_gen_clk_2x,
aux_half_rate_clk => OPEN,
aux_scan_clk => OPEN,
aux_scan_clk_reset_n => OPEN,
dll_reference_clk => OPEN,
dqs_delay_ctrl_export => OPEN,
global_reset_n => ctlr_rst_n,
local_address => ctlr_address,
local_be => (OTHERS => '1'),
local_burstbegin => ctlr_burst,
local_init_done => i_ctlr_init_done,
local_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0),
local_rdata_valid => ctlr_rd_sosi.valid,
local_read_req => ctlr_rd_req,
local_ready => i_ctlr_rdy,
local_refresh_ack => OPEN,
local_size => ctlr_burst_size,
local_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0),
local_wdata_req => OPEN,
local_write_req => ctlr_wr_req,
mem_addr => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_cas_n => phy_ou.cas_n,
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_clk => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_clk_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqsn => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_reset_n => phy_ou.reset_n,
mem_we_n => phy_ou.we_n,
oct_ctl_rs_value => c_ddr3_phy_oct_rs,
oct_ctl_rt_value => c_ddr3_phy_oct_rt,
phy_clk => i_ctlr_gen_clk,
pll_ref_clk => ctlr_ref_clk,
reset_phy_clk_n => ctlr_gen_rst_n,
reset_request_n => OPEN,
soft_reset_n => '1'
);
END GENERATE;
gen_uphy_4g_800_master : IF g_mts = 800 AND g_phy = 1 GENERATE
u_uphy_4g_800_master : COMPONENT uphy_4g_800_master
PORT MAP (
pll_ref_clk => ctlr_ref_clk,
global_reset_n => ctlr_rst_n,
soft_reset_n => '1',
afi_clk => i_ctlr_gen_clk,
afi_half_clk => OPEN,
afi_reset_n => ctlr_gen_rst_n,
mem_a => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_cas_n => phy_ou.cas_n,
mem_we_n => phy_ou.we_n,
mem_reset_n => phy_ou.reset_n,
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
avl_ready => i_ctlr_rdy,
avl_burstbegin => ctlr_burst,
avl_addr => ctlr_address,
avl_rdata_valid => ctlr_rd_sosi.valid,
avl_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0),
avl_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0),
avl_be => (OTHERS => '1'),
avl_read_req => ctlr_rd_req,
avl_write_req => ctlr_wr_req,
avl_size => ctlr_burst_size,
local_init_done => i_ctlr_init_done,
local_cal_success => OPEN,
local_cal_fail => OPEN,
oct_rdn => phy_in.oct_rdn,
oct_rup => phy_in.oct_rup,
seriesterminationcontrol => ser_term_ctrl_out,
parallelterminationcontrol => par_term_ctrl_out,
pll_mem_clk => i_ctlr_gen_clk_2x,
pll_write_clk => OPEN,
pll_write_clk_pre_phy_clk => OPEN,
pll_addr_cmd_clk => OPEN,
pll_locked => OPEN,
pll_avl_clk => OPEN,
pll_config_clk => OPEN,
dll_delayctrl => OPEN
);
END GENERATE;
gen_uphy_4g_800_slave : IF g_mts = 800 AND g_phy = 2 GENERATE
u_uphy_4g_800_slave : COMPONENT uphy_4g_800_slave
PORT MAP (
pll_ref_clk => ctlr_ref_clk,
global_reset_n => ctlr_rst_n,
soft_reset_n => '1',
afi_clk => i_ctlr_gen_clk,
afi_half_clk => OPEN,
afi_reset_n => ctlr_gen_rst_n,
mem_a => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_cas_n => phy_ou.cas_n,
mem_we_n => phy_ou.we_n,
mem_reset_n => phy_ou.reset_n,
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
avl_ready => i_ctlr_rdy,
avl_burstbegin => ctlr_burst,
avl_addr => ctlr_address,
avl_rdata_valid => ctlr_rd_sosi.valid,
avl_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0),
avl_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0),
avl_be => (OTHERS => '1'),
avl_read_req => ctlr_rd_req,
avl_write_req => ctlr_wr_req,
avl_size => ctlr_burst_size,
local_init_done => i_ctlr_init_done,
local_cal_success => OPEN,
local_cal_fail => OPEN,
seriesterminationcontrol => ser_term_ctrl_in,
parallelterminationcontrol => par_term_ctrl_in,
pll_mem_clk => i_ctlr_gen_clk_2x,
pll_write_clk => OPEN,
pll_write_clk_pre_phy_clk => OPEN,
pll_addr_cmd_clk => OPEN,
pll_locked => OPEN,
pll_avl_clk => OPEN,
pll_config_clk => OPEN,
dll_delayctrl => OPEN
);
END GENERATE;
gen_aphy_4g_1066 : IF g_mts = 1066 AND g_phy = 0 GENERATE
u_aphy_4g_1066 : ENTITY work.aphy_4g_1066
PORT MAP(
aux_full_rate_clk => i_ctlr_gen_clk_2x,
aux_half_rate_clk => OPEN,
aux_scan_clk => OPEN,
aux_scan_clk_reset_n => OPEN,
dll_reference_clk => OPEN,
dqs_delay_ctrl_export => OPEN,
global_reset_n => ctlr_rst_n,
local_address => ctlr_address,
local_be => (OTHERS => '1'),
local_burstbegin => ctlr_burst,
local_init_done => i_ctlr_init_done,
local_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0),
local_rdata_valid => ctlr_rd_sosi.valid,
local_read_req => ctlr_rd_req,
local_ready => i_ctlr_rdy,
local_refresh_ack => OPEN,
local_size => ctlr_burst_size,
local_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0),
local_wdata_req => OPEN,
local_write_req => ctlr_wr_req,
mem_addr => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_cas_n => phy_ou.cas_n,
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_clk => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_clk_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqsn => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_reset_n => phy_ou.reset_n,
mem_we_n => phy_ou.we_n,
oct_ctl_rs_value => c_ddr3_phy_oct_rs,
oct_ctl_rt_value => c_ddr3_phy_oct_rt,
phy_clk => i_ctlr_gen_clk,
pll_ref_clk => ctlr_ref_clk,
reset_phy_clk_n => ctlr_gen_rst_n,
reset_request_n => OPEN,
soft_reset_n => '1'
);
END GENERATE;
gen_uphy_4g_1066_master : IF g_mts = 1066 AND g_phy = 1 GENERATE
u_uphy_4g_1066_master : COMPONENT uphy_4g_1066_master
PORT MAP (
pll_ref_clk => ctlr_ref_clk,
global_reset_n => ctlr_rst_n,
soft_reset_n => '1',
afi_clk => i_ctlr_gen_clk,
afi_half_clk => OPEN,
afi_reset_n => ctlr_gen_rst_n,
mem_a => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_cas_n => phy_ou.cas_n,
mem_we_n => phy_ou.we_n,
mem_reset_n => phy_ou.reset_n,
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
avl_ready => i_ctlr_rdy,
avl_burstbegin => ctlr_burst,
avl_addr => ctlr_address,
avl_rdata_valid => ctlr_rd_sosi.valid,
avl_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0), avl_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0), avl_be => (OTHERS => '1'),
avl_read_req => ctlr_rd_req,
avl_write_req => ctlr_wr_req,
avl_size => ctlr_burst_size,
local_init_done => i_ctlr_init_done,
local_cal_success => OPEN,
local_cal_fail => OPEN,
oct_rdn => phy_in.oct_rdn,
oct_rup => phy_in.oct_rup,
seriesterminationcontrol => ser_term_ctrl_out,
parallelterminationcontrol => par_term_ctrl_out,
pll_mem_clk => i_ctlr_gen_clk_2x,
pll_write_clk => OPEN,
pll_write_clk_pre_phy_clk => OPEN,
pll_addr_cmd_clk => OPEN,
pll_locked => OPEN,
pll_avl_clk => OPEN,
pll_config_clk => OPEN,
dll_delayctrl => OPEN
);
END GENERATE;
gen_uphy_4g_1066_slave : IF g_mts = 1066 AND g_phy = 2 GENERATE
u_uphy_4g_1066_slave : COMPONENT uphy_4g_1066_slave
PORT MAP (
pll_ref_clk => ctlr_ref_clk,
global_reset_n => ctlr_rst_n,
soft_reset_n => '1',
afi_clk => i_ctlr_gen_clk,
afi_half_clk => OPEN,
afi_reset_n => ctlr_gen_rst_n,
mem_a => phy_ou.a(g_ddr.a_w-1 DOWNTO 0),
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0),
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0),
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0),
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0),
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0),
mem_dm => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0),
mem_ras_n => phy_ou.ras_n,
mem_cas_n => phy_ou.cas_n,
mem_we_n => phy_ou.we_n,
mem_reset_n => phy_ou.reset_n,
mem_dq => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0),
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0),
mem_odt => phy_ou.odt(g_ddr.cs_w-1 DOWNTO 0),
avl_ready => i_ctlr_rdy,
avl_burstbegin => ctlr_burst,
avl_addr => ctlr_address,
avl_rdata_valid => ctlr_rd_sosi.valid,
avl_rdata => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0),
avl_wdata => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0), avl_be => (OTHERS => '1'),
avl_read_req => ctlr_rd_req,
avl_write_req => ctlr_wr_req,
avl_size => ctlr_burst_size,
local_init_done => i_ctlr_init_done,
local_cal_success => OPEN,
local_cal_fail => OPEN,
seriesterminationcontrol => ser_term_ctrl_in,
parallelterminationcontrol => par_term_ctrl_in,
pll_mem_clk => i_ctlr_gen_clk_2x,
pll_write_clk => OPEN,
pll_write_clk_pre_phy_clk => OPEN,
pll_addr_cmd_clk => OPEN,
pll_locked => OPEN,
pll_avl_clk => OPEN,
pll_config_clk => OPEN,
dll_delayctrl => OPEN
);
END GENERATE;
-- DDR4 for Arria 10 with hard EMIF controller
-- This version uses all the IO pins as in the pinning design
gen_emif_ddr4_all_1800 : IF g_mts = 1800 AND g_phy = 3 GENERATE
phy_ou.a <= mb_a_internal(13 downto 0);
phy_ou.we_a14 <= mb_a_internal(14);
phy_ou.cas_a15 <= mb_a_internal(15);
phy_ou.ras_a16 <= mb_a_internal(16);
u_ddr4 : ddr4_all
port map (
global_reset_n => ctlr_rst_n, -- reset_n
pll_ref_clk => ctlr_ref_clk, -- Must connect directly to MB_II_REF_CLK pin
oct_rzqin => MB_I_RZQ, -- Direct connection to pin. No separate calibration module
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_a => mb_a_internal, -- 17
mem_act_n => phy_ou.act_n(g_ddr.act_w-1 DOWNTO 0), -- 1
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0), -- 2
mem_bg => phy_ou.bg(g_ddr.bg_w-1 DOWNTO 0), --2
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0), -- 2
mem_odt => phy_ou.odt(g_ddr.odt_w-1 DOWNTO 0), -- 2
mem_reset_n => phy_ou.resetarr_n(g_ddr.resetarr_w-1 DOWNTO 0), -- 1
mem_alert_n => phy_in.alert_n(g_ddr.alert_w-1 DOWNTO 0), -- 1
mem_par => phy_ou.par(g_ddr.par_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0), -- 9
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0), -- 9
mem_dq(63 downto 0) => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0), -- 64
mem_dq(71 downto 64)=> phy_io.cb(g_ddr.cb_w-1 DOWNTO 0), -- 8
mem_dbi_n => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0), -- 9
local_cal_success => open,
local_cal_fail => open,
emif_usr_reset_n => ctlr_gen_rst_n, --local_i_reset_n,
emif_usr_clk => i_ctlr_gen_clk, --local_i_clk,
amm_ready_0 => i_ctlr_rdy, --local_i_ready,
amm_read_0 => ctlr_rd_req, --local_i_read,
amm_write_0 => ctlr_wr_req, --local_i_write,
amm_address_0 => ctlr_address, --local_i_address, - 27
amm_readdata_0 => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0), --local_i_readdata, -- 576
amm_writedata_0 => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0), --local_i_writedata, -- 576
amm_burstcount_0 => ctlr_burst_size, --local_i_burstcount,
amm_byteenable_0 => (OTHERS => '1'), --local_i_be,
amm_readdatavalid_0 => ctlr_rd_sosi.valid --local_i_read_data_valid
);
end generate;
gen_emif_ddr4_4g_1600 : IF g_mts = 1600 AND g_phy = 3 GENERATE
phy_ou.a <= mb_a_internal(13 downto 0);
phy_ou.we_a14 <= mb_a_internal(14);
phy_ou.cas_a15 <= mb_a_internal(15);
phy_ou.ras_a16 <= mb_a_internal(16);
u_ddr4 : ddr4_4g_1600
port map (
global_reset_n => ctlr_rst_n, -- reset_n
pll_ref_clk => ctlr_ref_clk, -- Must connect directly to MB_II_REF_CLK pin
oct_rzqin => MB_I_RZQ, -- Direct connection to pin. No separate calibration module
mem_ck => phy_io.clk(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_ck_n => phy_io.clk_n(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_a => mb_a_internal, -- 17
mem_act_n => phy_ou.act_n(g_ddr.act_w-1 DOWNTO 0), -- 1
mem_ba => phy_ou.ba(g_ddr.ba_w-1 DOWNTO 0), -- 2
mem_bg => phy_ou.bg(g_ddr.bg_w-1 DOWNTO 0), --2
mem_cke => phy_ou.cke(g_ddr.clk_w-1 DOWNTO 0), -- 2
mem_cs_n => phy_ou.cs_n(g_ddr.cs_w-1 DOWNTO 0), -- 2
mem_odt => phy_ou.odt(g_ddr.odt_w-1 DOWNTO 0), -- 2
mem_reset_n => phy_ou.resetarr_n(g_ddr.resetarr_w-1 DOWNTO 0), -- 1
mem_alert_n => phy_in.alert_n(g_ddr.alert_w-1 DOWNTO 0), -- 1
mem_par => phy_ou.par(g_ddr.par_w-1 DOWNTO 0),
mem_dqs => phy_io.dqs(g_ddr.dqs_w-1 DOWNTO 0), -- 9
mem_dqs_n => phy_io.dqs_n(g_ddr.dqs_w-1 DOWNTO 0), -- 9
mem_dq(63 downto 0) => phy_io.dq(g_ddr.dq_w-1 DOWNTO 0), -- 64
mem_dq(71 downto 64)=> phy_io.cb(g_ddr.cb_w-1 DOWNTO 0), -- 8
mem_dbi_n => phy_ou.dm(g_ddr.dm_w-1 DOWNTO 0), -- 9
local_cal_success => open,
local_cal_fail => open,
emif_usr_reset_n => ctlr_gen_rst_n, --local_i_reset_n,
emif_usr_clk => i_ctlr_gen_clk, --local_i_clk,
amm_ready_0 => i_ctlr_rdy, --local_i_ready,
amm_read_0 => ctlr_rd_req, --local_i_read,
amm_write_0 => ctlr_wr_req, --local_i_write,
amm_address_0 => ctlr_address, --local_i_address, - 27
amm_readdata_0 => ctlr_rd_sosi.data(c_ddr_local_data_w-1 downto 0), --local_i_readdata, -- 576
amm_writedata_0 => ctlr_wr_sosi.data(c_ddr_local_data_w-1 downto 0), --local_i_writedata, -- 576
amm_burstcount_0 => ctlr_burst_size, --local_i_burstcount,
amm_byteenable_0 => (OTHERS => '1'), --local_i_be,
amm_readdatavalid_0 => ctlr_rd_sosi.valid --local_i_read_data_valid
);
end generate;
END str;
This diff is collapsed.
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment