From 4e963835da11e49318f075f65d83fed6e75f82b4 Mon Sep 17 00:00:00 2001 From: Jonathan Hargreaves <hargreaves@astron.nl> Date: Fri, 28 Nov 2014 09:17:29 +0000 Subject: [PATCH] low level wrapper for DDR3 and DDR4 controller IP --- libraries/io/ddr/ddr.vhd | 666 ++++++++++++++++++++++ libraries/io/ddr/ddr_pkg.vhd | 466 +++++++++++++++ libraries/io/ddr/ddr_testdriver.vhd | 845 ++++++++++++++++++++++++++++ 3 files changed, 1977 insertions(+) create mode 100644 libraries/io/ddr/ddr.vhd create mode 100644 libraries/io/ddr/ddr_pkg.vhd create mode 100644 libraries/io/ddr/ddr_testdriver.vhd diff --git a/libraries/io/ddr/ddr.vhd b/libraries/io/ddr/ddr.vhd new file mode 100644 index 0000000000..30bc8ab9f8 --- /dev/null +++ b/libraries/io/ddr/ddr.vhd @@ -0,0 +1,666 @@ +-------------------------------------------------------------------------------- +-- +-- 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; + diff --git a/libraries/io/ddr/ddr_pkg.vhd b/libraries/io/ddr/ddr_pkg.vhd new file mode 100644 index 0000000000..057344b031 --- /dev/null +++ b/libraries/io/ddr/ddr_pkg.vhd @@ -0,0 +1,466 @@ +------------------------------------------------------------------------------- +-- +-- 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/>. +-- +------------------------------------------------------------------------------- + +LIBRARY IEEE, common_lib; +USE IEEE.STD_LOGIC_1164.ALL; +USE common_lib.common_pkg.ALL; +USE IEEE.NUMERIC_STD.ALL; + +PACKAGE ddr_pkg IS + + -- DDR3 and DDR4 widths + TYPE t_c_ddr_phy IS RECORD + a_w : NATURAL; -- = 16; + a_row_w : NATURAL; -- = 16; -- = a_w, row address width, via a_w lines + a_col_w : NATURAL; -- = 10; -- <= a_w, col address width, via a_w lines + ba_w : NATURAL; -- = 2; + bg_w : NATURAL; -- = 2; + dq_w : NATURAL; -- = 64; + dqs_w : NATURAL; -- = 8; -- = dq_w / nof_dq_per_dqs; + dm_w : NATURAL; -- = 8; + cs_w : NATURAL; -- = 2; + act_w : NATURAL; -- = 1; + odt_w : NATURAL; -- = 2; + resetarr_w : NATURAL; -- = 1; + alert_w : NATURAL; -- = 1; + par_w : NATURAL; -- = 1; + cb_w : NATURAL; -- = 8; + END RECORD; + + CONSTANT c_ddr4_phy_all : t_c_ddr_phy := (17, 0, 0, 2, 2, 64, 9, 9, 2, 1, 2, 1, 1, 1, 8); + CONSTANT c_ddr4_phy_4g : t_c_ddr_phy := (17, 0, 0, 2, 2, 64, 9, 9, 1, 1, 1, 1, 1, 1, 8); + + TYPE t_ddr_phy_in IS RECORD + evt : STD_LOGIC; + alert_n : STD_LOGIC_VECTOR(c_ddr_phy.alert_w-1 DOWNTO 0); + oct_rup : STD_LOGIC; + oct_rdn : STD_LOGIC; + oct_rzqin : STD_LOGIC; + nc : STD_LOGIC; -- not connected, needed to be able to initialize constant record which has to have more than one field in VHDL + END RECORD; + + TYPE t_ddr_phy_io IS RECORD -- Do not use this type in Quartus! Use the _sel version instead. + dq : STD_LOGIC_VECTOR(c_ddr_phy.dq_w-1 DOWNTO 0); -- data bus + cb : STD_LOGIC_VECTOR(c_ddr_phy.cb_w-1 DOWNTO 0); -- data bus + dqs : STD_LOGIC_VECTOR(c_ddr_phy.dqs_w-1 DOWNTO 0); -- data strobe bus + dqs_n : STD_LOGIC_VECTOR(c_ddr_phy.dqs_w-1 DOWNTO 0); + clk : STD_LOGIC_VECTOR(c_ddr_phy.clk_w-1 DOWNTO 0); -- clock, positive edge clock + clk_n : STD_LOGIC_VECTOR(c_ddr_phy.clk_w-1 DOWNTO 0); -- clock, negative edge clock + scl : STD_LOGIC; -- I2C + sda : STD_LOGIC; + END RECORD; + + TYPE t_ddr_phy_ou IS RECORD + a : STD_LOGIC_VECTOR(c_ddr_phy.a_w-1 DOWNTO 0); -- row and column address + ba : STD_LOGIC_VECTOR(c_ddr_phy.ba_w-1 DOWNTO 0); -- bank address + bg : STD_LOGIC_VECTOR(c_ddr_phy.bg_w-1 DOWNTO 0); -- bank + dm : STD_LOGIC_VECTOR(c_ddr_phy.dm_w-1 DOWNTO 0); -- data mask bus + cas_n : STD_LOGIC; --_VECTOR(0 DOWNTO 0); -- column address strobe + ras_n : STD_LOGIC; --_VECTOR(0 DOWNTO 0); -- row address strobe + we_n : STD_LOGIC; --_VECTOR(0 DOWNTO 0); -- write enable signal + reset_n : STD_LOGIC; -- reset signal + resetarr_n : STD_LOGIC_VECTOR(c_ddr_phy.resetarr_w-1 DOWNTO 0); -- on-die termination control signal + par : STD_LOGIC_VECTOR(c_ddr_phy.par_w-1 DOWNTO 0); -- on-die termination control signal + odt : STD_LOGIC_VECTOR(c_ddr_phy.cs_w-1 DOWNTO 0); -- on-die termination control signal + cke : STD_LOGIC_VECTOR(c_ddr_phy.cs_w-1 DOWNTO 0); -- clock enable + cs_n : STD_LOGIC_VECTOR(c_ddr_phy.cs_w-1 DOWNTO 0); -- chip select + END RECORD; + + CONSTANT c_ddr_phy_in_rst : t_ddr_phy_in := ('0', '1', 'X', 'X', 'X', 'X'); + CONSTANT c_ddr_phy_io_rst : t_ddr_phy_io := ((OTHERS=>'0'), (others => '0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), '0', '0'); + CONSTANT c_ddr_phy_ou_rst : t_ddr_phy_ou := ((OTHERS=>'0'), (OTHERS=>'0'), (others => '0'), (OTHERS=>'0'), '0', '0', '0', '0', (others => '0'), (others => '0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0')); + + TYPE t_ddr_phy_in_arr IS ARRAY(NATURAL RANGE <>) OF t_ddr_phy_in; + TYPE t_ddr_phy_io_arr IS ARRAY(NATURAL RANGE <>) OF t_ddr_phy_io; + TYPE t_ddr_phy_ou_arr IS ARRAY(NATURAL RANGE <>) OF t_ddr_phy_ou; + + TYPE t_ddr_addr IS RECORD + chip : STD_LOGIC_VECTOR(ceil_log2(c_ddr_phy.cs_w) -1 DOWNTO 0); -- Note: The controller interprets the chip address as logical address (NOT individual chip sel lines), hence ceil_log2 + bank : STD_LOGIC_VECTOR( c_ddr_phy.ba_w -1 DOWNTO 0); + row : STD_LOGIC_VECTOR( c_ddr_phy.a_row_w-1 DOWNTO 0); + column : STD_LOGIC_VECTOR( c_ddr_phy.a_col_w-1 DOWNTO 0); + END RECORD; + + TYPE t_ddr_addr_arr IS ARRAY(NATURAL RANGE <>) OF t_ddr_addr; + + constant c_ddr_local_data_w : integer := sel_n(g_phy, 256, 256, 256, 576) + --CONSTANT c_ddr_ctlr_data_w : NATURAL := 256; -- = 64 (PHY dq width) * 2 (use both PHY clock edges) * 2 (PHY transfer at double rate) -- 512 for DDR4 + CONSTANT c_ddr_ctlr_rsl : NATURAL := c_ddr_local_data_w / (c_ddr_phy.dq_w + c_ddr_phy.cb_w); -- =4 or 8 + CONSTANT c_ddr_ctlr_rsl_w : NATURAL := ceil_log2(c_ddr_ctlr_rsl); -- 2 or 3 + CONSTANT c_ddr_ctlr_maxburstsize : NATURAL := 64; + CONSTANT c_ddr_ctlr_maxburstsize_w : NATURAL := ceil_log2(c_ddr_ctlr_maxburstsize+1); + CONSTANT c_ddr_ctrl_nof_latent_reads : NATURAL := 100; -- The downside to having a command cue: even after de-asserting read requests, the ALTMEMPHY keeps processing your cued read requests. + -- This makes sure 100 words are still available in the read FIFO after it de-asserted its siso.ready signal towards the ddr3 read side. + + + CONSTANT c_ddr_addr_lo : t_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0'), (OTHERS=>'0')); + CONSTANT c_ddr_address_lo : NATURAL := 0; + + CONSTANT c_ddr_addr_hi_4gb : t_ddr_addr := ((OTHERS=>'1'), (OTHERS=>'1'), (OTHERS=>'1'), TO_UVEC(2**c_ddr_phy_4g.a_col_w - c_ddr_ctlr_rsl, c_ddr_phy_4g.a_col_w)); + + -- 4 rows * 1024 cols * 64 bits / 128bits per associative mem array element = 2048 = default ALTMEMPHY mem_model array depth. + CONSTANT c_ddr_addr_hi_sim : t_ddr_addr := ((OTHERS=>'0'), (OTHERS=>'0'), TO_UVEC(3, c_ddr_phy.a_row_w), TO_UVEC(2**c_ddr_phy_4g.a_col_w - c_ddr_ctlr_rsl, c_ddr_phy_4g.a_col_w)); + CONSTANT c_ddr_address_hi_sim : NATURAL := 4092; --TB uses generated mem model with 2ki addresses of 128k - so the array holds 4096 64-bit words. End address is 4092 (resolution=4: last write=4092,4093,4094,4095.) + + TYPE t_ddr_seq IS RECORD + g_wr_chunksize : POSITIVE; -- := 256; + g_wr_nof_steps : POSITIVE; -- := 1; + g_wr_nof_blocks : POSITIVE; -- := 64; + g_rd_chunksize : POSITIVE; -- := 8; + g_rd_nof_steps : POSITIVE; -- := 16; + g_rd_nof_blocks : POSITIVE; -- := 128; + g_switch_size : POSITIVE; -- := 256; -- This defines the switch interval between read and write operation. + g_page_size : POSITIVE; -- := 16384; -- Page size defines the size of a single page. Total memory will be doubled. + END RECORD; + + CONSTANT c_ddr_seq : t_ddr_seq := (256, 1, 64, 8, 16, 128, 256, 16384); + + + COMPONENT uphy_4g_800_master IS + PORT ( + pll_ref_clk : IN STD_LOGIC := '0'; -- pll_ref_clk.clk + global_reset_n : IN STD_LOGIC := '0'; -- global_reset.reset_n + soft_reset_n : IN STD_LOGIC := '0'; -- soft_reset.reset_n + afi_clk : OUT STD_LOGIC; -- afi_clk.clk + afi_half_clk : OUT STD_LOGIC; -- afi_half_clk.clk + afi_reset_n : OUT STD_LOGIC; -- afi_reset.reset_n + mem_a : OUT STD_LOGIC_VECTOR(14 DOWNTO 0); -- memory.mem_a + mem_ba : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); -- .mem_ba + mem_ck : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck + mem_ck_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck_n + mem_cke : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cke + mem_cs_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cs_n + mem_dm : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- .mem_dm + mem_ras_n : OUT STD_LOGIC; -- .mem_ras_n + mem_cas_n : OUT STD_LOGIC; -- .mem_cas_n + mem_we_n : OUT STD_LOGIC; -- .mem_we_n + mem_reset_n : OUT STD_LOGIC; -- .mem_reset_n + mem_dq : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0'); -- .mem_dq + mem_dqs : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs + mem_dqs_n : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs_n + mem_odt : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_odt + avl_ready : OUT STD_LOGIC; -- avl.waitrequest_n + avl_burstbegin : IN STD_LOGIC := '0'; -- .beginbursttransfer + avl_addr : IN STD_LOGIC_VECTOR(26 DOWNTO 0) := (OTHERS => '0'); -- .address + avl_rdata_valid : OUT STD_LOGIC; -- .readdatavalid + avl_rdata : OUT STD_LOGIC_VECTOR(255 DOWNTO 0); -- .readdata + avl_wdata : IN STD_LOGIC_VECTOR(255 DOWNTO 0):= (OTHERS => '0'); -- .writedata + avl_be : IN STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); -- .byteenable + avl_read_req : IN STD_LOGIC := '0'; -- .read + avl_write_req : IN STD_LOGIC := '0'; -- .write + avl_size : IN STD_LOGIC_VECTOR(6 DOWNTO 0) := (OTHERS => '0'); -- .burstcount + local_init_done : OUT STD_LOGIC; -- status.local_init_done + local_cal_success : OUT STD_LOGIC; -- .local_cal_success + local_cal_fail : OUT STD_LOGIC; -- .local_cal_fail + oct_rdn : IN STD_LOGIC := '0'; -- oct.rdn + oct_rup : IN STD_LOGIC := '0'; -- oct.rup + seriesterminationcontrol : OUT STD_LOGIC_VECTOR(13 DOWNTO 0); -- oct_sharing.seriesterminationcontrol + parallelterminationcontrol : OUT STD_LOGIC_VECTOR(13 DOWNTO 0); -- .parallelterminationcontrol + pll_mem_clk : OUT STD_LOGIC; -- export + pll_write_clk : OUT STD_LOGIC; -- export + pll_write_clk_pre_phy_clk : OUT STD_LOGIC; -- export + pll_addr_cmd_clk : OUT STD_LOGIC; -- export + pll_locked : OUT STD_LOGIC; -- export + pll_avl_clk : OUT STD_LOGIC; -- export + pll_config_clk : OUT STD_LOGIC; -- export + dll_delayctrl : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) -- export + ); + END COMPONENT uphy_4g_800_master; + + COMPONENT uphy_4g_800_slave IS + PORT ( + pll_ref_clk : IN STD_LOGIC := '0'; -- pll_ref_clk.clk + global_reset_n : IN STD_LOGIC := '0'; -- global_reset.reset_n + soft_reset_n : IN STD_LOGIC := '0'; -- soft_reset.reset_n + afi_clk : OUT STD_LOGIC; -- afi_clk.clk + afi_half_clk : OUT STD_LOGIC; -- afi_half_clk.clk + afi_reset_n : OUT STD_LOGIC; -- afi_reset.reset_n + mem_a : OUT STD_LOGIC_VECTOR(14 DOWNTO 0); -- memory.mem_a + mem_ba : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); -- .mem_ba + mem_ck : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck + mem_ck_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck_n + mem_cke : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cke + mem_cs_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cs_n + mem_dm : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- .mem_dm + mem_ras_n : OUT STD_LOGIC; -- .mem_ras_n + mem_cas_n : OUT STD_LOGIC; -- .mem_cas_n + mem_we_n : OUT STD_LOGIC; -- .mem_we_n + mem_reset_n : OUT STD_LOGIC; -- .mem_reset_n + mem_dq : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0'); -- .mem_dq + mem_dqs : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs + mem_dqs_n : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs_n + mem_odt : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_odt + avl_ready : OUT STD_LOGIC; -- avl.waitrequest_n + avl_burstbegin : IN STD_LOGIC := '0'; -- .beginbursttransfer + avl_addr : IN STD_LOGIC_VECTOR(26 DOWNTO 0) := (OTHERS => '0'); -- .address + avl_rdata_valid : OUT STD_LOGIC; -- .readdatavalid + avl_rdata : OUT STD_LOGIC_VECTOR(255 DOWNTO 0); -- .readdata + avl_wdata : IN STD_LOGIC_VECTOR(255 DOWNTO 0):= (OTHERS => '0'); -- .writedata + avl_be : IN STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); -- .byteenable + avl_read_req : IN STD_LOGIC := '0'; -- .read + avl_write_req : IN STD_LOGIC := '0'; -- .write + avl_size : IN STD_LOGIC_VECTOR(6 DOWNTO 0) := (OTHERS => '0'); -- .burstcount + local_init_done : OUT STD_LOGIC; -- status.local_init_done + local_cal_success : OUT STD_LOGIC; -- .local_cal_success + local_cal_fail : OUT STD_LOGIC; -- .local_cal_fail + seriesterminationcontrol : IN STD_LOGIC_VECTOR(13 DOWNTO 0); -- oct_sharing.seriesterminationcontrol + parallelterminationcontrol : IN STD_LOGIC_VECTOR(13 DOWNTO 0); -- .parallelterminationcontrol + pll_mem_clk : OUT STD_LOGIC; -- export + pll_write_clk : OUT STD_LOGIC; -- export + pll_write_clk_pre_phy_clk : OUT STD_LOGIC; -- export + pll_addr_cmd_clk : OUT STD_LOGIC; -- export + pll_locked : OUT STD_LOGIC; -- export + pll_avl_clk : OUT STD_LOGIC; -- export + pll_config_clk : OUT STD_LOGIC; -- export + dll_delayctrl : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) -- export + ); + END COMPONENT uphy_4g_800_slave; + + COMPONENT uphy_4g_1066_master IS + PORT ( + pll_ref_clk : IN STD_LOGIC := '0'; -- pll_ref_clk.clk + global_reset_n : IN STD_LOGIC := '0'; -- global_reset.reset_n + soft_reset_n : IN STD_LOGIC := '0'; -- soft_reset.reset_n + afi_clk : OUT STD_LOGIC; -- afi_clk.clk + afi_half_clk : OUT STD_LOGIC; -- afi_half_clk.clk + afi_reset_n : OUT STD_LOGIC; -- afi_reset.reset_n + mem_a : OUT STD_LOGIC_VECTOR(14 DOWNTO 0); -- memory.mem_a + mem_ba : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); -- .mem_ba + mem_ck : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck + mem_ck_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck_n + mem_cke : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cke + mem_cs_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cs_n + mem_dm : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- .mem_dm + mem_ras_n : OUT STD_LOGIC; -- .mem_ras_n + mem_cas_n : OUT STD_LOGIC; -- .mem_cas_n + mem_we_n : OUT STD_LOGIC; -- .mem_we_n + mem_reset_n : OUT STD_LOGIC; -- .mem_reset_n + mem_dq : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0'); -- .mem_dq + mem_dqs : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs + mem_dqs_n : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs_n + mem_odt : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_odt + avl_ready : OUT STD_LOGIC; -- avl.waitrequest_n + avl_burstbegin : IN STD_LOGIC := '0'; -- .beginbursttransfer + avl_addr : IN STD_LOGIC_VECTOR(26 DOWNTO 0) := (OTHERS => '0'); -- .address + avl_rdata_valid : OUT STD_LOGIC; -- .readdatavalid + avl_rdata : OUT STD_LOGIC_VECTOR(255 DOWNTO 0); -- .readdata + avl_wdata : IN STD_LOGIC_VECTOR(255 DOWNTO 0):= (OTHERS => '0'); -- .writedata + avl_be : IN STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); -- .byteenable + avl_read_req : IN STD_LOGIC := '0'; -- .read + avl_write_req : IN STD_LOGIC := '0'; -- .write + avl_size : IN STD_LOGIC_VECTOR(6 DOWNTO 0) := (OTHERS => '0'); -- .burstcount + local_init_done : OUT STD_LOGIC; -- status.local_init_done + local_cal_success : OUT STD_LOGIC; -- .local_cal_success + local_cal_fail : OUT STD_LOGIC; -- .local_cal_fail + oct_rdn : IN STD_LOGIC := '0'; -- oct.rdn + oct_rup : IN STD_LOGIC := '0'; -- oct.rup + seriesterminationcontrol : OUT STD_LOGIC_VECTOR(13 DOWNTO 0); -- oct_sharing.seriesterminationcontrol + parallelterminationcontrol : OUT STD_LOGIC_VECTOR(13 DOWNTO 0); -- .parallelterminationcontrol + pll_mem_clk : OUT STD_LOGIC; -- export + pll_write_clk : OUT STD_LOGIC; -- export + pll_write_clk_pre_phy_clk : OUT STD_LOGIC; -- export + pll_addr_cmd_clk : OUT STD_LOGIC; -- export + pll_locked : OUT STD_LOGIC; -- export + pll_avl_clk : OUT STD_LOGIC; -- export + pll_config_clk : OUT STD_LOGIC; -- export + dll_delayctrl : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) -- export + ); + END COMPONENT uphy_4g_1066_master; + + COMPONENT uphy_4g_1066_slave IS + PORT ( + pll_ref_clk : IN STD_LOGIC := '0'; -- pll_ref_clk.clk + global_reset_n : IN STD_LOGIC := '0'; -- global_reset.reset_n + soft_reset_n : IN STD_LOGIC := '0'; -- soft_reset.reset_n + afi_clk : OUT STD_LOGIC; -- afi_clk.clk + afi_half_clk : OUT STD_LOGIC; -- afi_half_clk.clk + afi_reset_n : OUT STD_LOGIC; -- afi_reset.reset_n + mem_a : OUT STD_LOGIC_VECTOR(14 DOWNTO 0); -- memory.mem_a + mem_ba : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); -- .mem_ba + mem_ck : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck + mem_ck_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_ck_n + mem_cke : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cke + mem_cs_n : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_cs_n + mem_dm : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); -- .mem_dm + mem_ras_n : OUT STD_LOGIC; -- .mem_ras_n + mem_cas_n : OUT STD_LOGIC; -- .mem_cas_n + mem_we_n : OUT STD_LOGIC; -- .mem_we_n + mem_reset_n : OUT STD_LOGIC; -- .mem_reset_n + mem_dq : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => '0'); -- .mem_dq + mem_dqs : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs + mem_dqs_n : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => '0'); -- .mem_dqs_n + mem_odt : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); -- .mem_odt + avl_ready : OUT STD_LOGIC; -- avl.waitrequest_n + avl_burstbegin : IN STD_LOGIC := '0'; -- .beginbursttransfer + avl_addr : IN STD_LOGIC_VECTOR(26 DOWNTO 0) := (OTHERS => '0'); -- .address + avl_rdata_valid : OUT STD_LOGIC; -- .readdatavalid + avl_rdata : OUT STD_LOGIC_VECTOR(255 DOWNTO 0); -- .readdata + avl_wdata : IN STD_LOGIC_VECTOR(255 DOWNTO 0):= (OTHERS => '0'); -- .writedata + avl_be : IN STD_LOGIC_VECTOR(31 DOWNTO 0) := (OTHERS => '0'); -- .byteenable + avl_read_req : IN STD_LOGIC := '0'; -- .read + avl_write_req : IN STD_LOGIC := '0'; -- .write + avl_size : IN STD_LOGIC_VECTOR(6 DOWNTO 0) := (OTHERS => '0'); -- .burstcount + local_init_done : OUT STD_LOGIC; -- status.local_init_done + local_cal_success : OUT STD_LOGIC; -- .local_cal_success + local_cal_fail : OUT STD_LOGIC; -- .local_cal_fail + seriesterminationcontrol : IN STD_LOGIC_VECTOR(13 DOWNTO 0); -- oct_sharing.seriesterminationcontrol + parallelterminationcontrol : IN STD_LOGIC_VECTOR(13 DOWNTO 0); -- .parallelterminationcontrol + pll_mem_clk : OUT STD_LOGIC; -- export + pll_write_clk : OUT STD_LOGIC; -- export + pll_write_clk_pre_phy_clk : OUT STD_LOGIC; -- export + pll_addr_cmd_clk : OUT STD_LOGIC; -- export + pll_locked : OUT STD_LOGIC; -- export + pll_avl_clk : OUT STD_LOGIC; -- export + pll_config_clk : OUT STD_LOGIC; -- export + dll_delayctrl : OUT STD_LOGIC_VECTOR(5 DOWNTO 0) -- export + ); + END COMPONENT uphy_4g_1066_slave; + + COMPONENT alt_mem_if_ddr3_mem_model_top_ddr3_mem_if_dm_pins_en_mem_if_dqsn_en IS + GENERIC ( + MEM_IF_ADDR_WIDTH : INTEGER := 0; + MEM_IF_ROW_ADDR_WIDTH : INTEGER := 0; + MEM_IF_COL_ADDR_WIDTH : INTEGER := 0; + MEM_IF_CS_PER_RANK : INTEGER := 0; + MEM_IF_CONTROL_WIDTH : INTEGER := 0; + MEM_IF_DQS_WIDTH : INTEGER := 0; + MEM_IF_CS_WIDTH : INTEGER := 0; + MEM_IF_BANKADDR_WIDTH : INTEGER := 0; + MEM_IF_DQ_WIDTH : INTEGER := 0; + MEM_IF_CK_WIDTH : INTEGER := 0; + MEM_IF_CLK_EN_WIDTH : INTEGER := 0; + DEVICE_WIDTH : INTEGER := 1; + MEM_TRCD : INTEGER := 0; + MEM_TRTP : INTEGER := 0; + MEM_DQS_TO_CLK_CAPTURE_DELAY : INTEGER := 0; + MEM_CLK_TO_DQS_CAPTURE_DELAY : INTEGER := 0; + MEM_IF_ODT_WIDTH : INTEGER := 0; + MEM_MIRROR_ADDRESSING_DEC : INTEGER := 0; + MEM_REGDIMM_ENABLED : BOOLEAN := FALSE; + DEVICE_DEPTH : INTEGER := 1; + MEM_GUARANTEED_WRITE_INIT : BOOLEAN := FALSE; + MEM_VERBOSE : BOOLEAN := TRUE; + MEM_INIT_EN : BOOLEAN := FALSE; + MEM_INIT_FILE : STRING := ""; + DAT_DATA_WIDTH : INTEGER := 32 + ); + PORT ( + mem_a : IN STD_LOGIC_VECTOR(14 DOWNTO 0) := (OTHERS => 'X'); -- mem_a + mem_ba : IN STD_LOGIC_VECTOR(2 DOWNTO 0) := (OTHERS => 'X'); -- mem_ba + mem_ck : IN STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => 'X'); -- mem_ck + mem_ck_n : IN STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => 'X'); -- mem_ck_n + mem_cke : IN STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => 'X'); -- mem_cke + mem_cs_n : IN STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => 'X'); -- mem_cs_n + mem_dm : IN STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => 'X'); -- mem_dm + mem_ras_n : IN STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => 'X'); -- mem_ras_n + mem_cas_n : IN STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => 'X'); -- mem_cas_n + mem_we_n : IN STD_LOGIC_VECTOR(0 DOWNTO 0) := (OTHERS => 'X'); -- mem_we_n + mem_reset_n : IN STD_LOGIC := 'X'; -- mem_reset_n + mem_dq : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0) := (OTHERS => 'X'); -- mem_dq + mem_dqs : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => 'X'); -- mem_dqs + mem_dqs_n : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) := (OTHERS => 'X'); -- mem_dqs_n + mem_odt : IN STD_LOGIC_VECTOR(1 DOWNTO 0) := (OTHERS => 'X') -- mem_odt + ); + END COMPONENT alt_mem_if_ddr3_mem_model_top_ddr3_mem_if_dm_pins_en_mem_if_dqsn_en; + + -- generic component using all possible IOs for pinning check + component ddr4_all is + port ( + global_reset_n : in std_logic := 'X'; -- reset_n + pll_ref_clk : in std_logic := 'X'; -- clk + oct_rzqin : in std_logic := 'X'; -- oct_rzqin + mem_ck : out std_logic_vector(1 downto 0); -- mem_ck + mem_ck_n : out std_logic_vector(1 downto 0); -- mem_ck_n + mem_a : out std_logic_vector(16 downto 0); -- mem_a + mem_act_n : out std_logic_vector(0 downto 0); -- mem_act_n + mem_ba : out std_logic_vector(1 downto 0); -- mem_ba + mem_bg : out std_logic_vector(1 downto 0); -- mem_bg + mem_cke : out std_logic_vector(1 downto 0); -- mem_cke + mem_cs_n : out std_logic_vector(1 downto 0); -- mem_cs_n + mem_odt : out std_logic_vector(1 downto 0); -- mem_odt + mem_reset_n : out std_logic_vector(0 downto 0); -- mem_reset_n + mem_alert_n : in std_logic_vector(0 downto 0); -- mem_alert_n + mem_par : out std_logic_vector(0 downto 0); -- mem_par ** new in 14.0 ** + mem_dqs : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dqs + mem_dqs_n : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dqs_n + mem_dq : inout std_logic_vector(71 downto 0) := (others => 'X'); -- mem_dq + mem_dbi_n : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dbi_n + local_cal_success : out std_logic; -- local_cal_success + local_cal_fail : out std_logic; -- local_cal_fail + emif_usr_reset_n : out std_logic; -- reset_n + emif_usr_clk : out std_logic; -- clk + amm_ready_0 : out std_logic; -- waitrequest_n + amm_read_0 : in std_logic := 'X'; -- read + amm_write_0 : in std_logic := 'X'; -- write + amm_address_0 : in std_logic_vector(26 downto 0) := (others => 'X'); -- address ** chg from 23 bits in 14.0 ** + amm_readdata_0 : out std_logic_vector(575 downto 0); -- readdata + amm_writedata_0 : in std_logic_vector(575 downto 0) := (others => 'X'); -- writedata + amm_burstcount_0 : in std_logic_vector(6 downto 0) := (others => 'X'); -- burstcount ** chg from 8 bits in 14.0 ** + amm_byteenable_0 : in std_logic_vector(71 downto 0) := (others => 'X'); -- byteenable + amm_readdatavalid_0 : out std_logic -- readdatavalid + ); + end component ddr4_all; + + -- Micron MTA9ASF51272PZ - 4GB + -- clock speed 800MHz for testing + component ddr4_4g_1600 is + port ( + global_reset_n : in std_logic := 'X'; -- reset_n + pll_ref_clk : in std_logic := 'X'; -- clk + oct_rzqin : in std_logic := 'X'; -- oct_rzqin + mem_ck : out std_logic_vector(0 downto 0); -- mem_ck + mem_ck_n : out std_logic_vector(0 downto 0); -- mem_ck_n + mem_a : out std_logic_vector(16 downto 0); -- mem_a + mem_act_n : out std_logic_vector(0 downto 0); -- mem_act_n + mem_ba : out std_logic_vector(1 downto 0); -- mem_ba + mem_bg : out std_logic_vector(1 downto 0); -- mem_bg + mem_cke : out std_logic_vector(0 downto 0); -- mem_cke + mem_cs_n : out std_logic_vector(0 downto 0); -- mem_cs_n + mem_odt : out std_logic_vector(0 downto 0); -- mem_odt + mem_reset_n : out std_logic_vector(0 downto 0); -- mem_reset_n + mem_alert_n : in std_logic_vector(0 downto 0); -- mem_alert_n + mem_par : out std_logic_vector(0 downto 0); -- mem_par ** new in 14.0 ** + mem_dqs : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dqs + mem_dqs_n : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dqs_n + mem_dq : inout std_logic_vector(71 downto 0) := (others => 'X'); -- mem_dq + mem_dbi_n : inout std_logic_vector(8 downto 0) := (others => 'X'); -- mem_dbi_n + local_cal_success : out std_logic; -- local_cal_success + local_cal_fail : out std_logic; -- local_cal_fail + emif_usr_reset_n : out std_logic; -- reset_n + emif_usr_clk : out std_logic; -- clk + amm_ready_0 : out std_logic; -- waitrequest_n + amm_read_0 : in std_logic := 'X'; -- read + amm_write_0 : in std_logic := 'X'; -- write + amm_address_0 : in std_logic_vector(25 downto 0) := (others => 'X'); -- address ** chg from 23 bits in 14.0 ** + amm_readdata_0 : out std_logic_vector(575 downto 0); -- readdata + amm_writedata_0 : in std_logic_vector(575 downto 0) := (others => 'X'); -- writedata + amm_burstcount_0 : in std_logic_vector(6 downto 0) := (others => 'X'); -- burstcount ** chg from 8 bits in 14.0 ** + amm_byteenable_0 : in std_logic_vector(71 downto 0) := (others => 'X'); -- byteenable + amm_readdatavalid_0 : out std_logic -- readdatavalid + ); + end component ddr4_4g_1600; + +END ddr_pkg; + +PACKAGE BODY ddr_pkg IS + +END ddr_pkg; + diff --git a/libraries/io/ddr/ddr_testdriver.vhd b/libraries/io/ddr/ddr_testdriver.vhd new file mode 100644 index 0000000000..57d5dc6848 --- /dev/null +++ b/libraries/io/ddr/ddr_testdriver.vhd @@ -0,0 +1,845 @@ +------------------------------------------------------------------------------- +-- +-- Copyright (C) 2009 +-- 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; +USE IEEE.STD_LOGIC_1164.ALL; +USE IEEE.STD_LOGIC_ARITH.ALL; +USE IEEE.STD_LOGIC_UNSIGNED.ALL; +use work.tech_ddr_component_pkg.all; + +-- This module instantiates the Altera MegaWizard DDR3 controller and +-- test driver for both modules. +-- It adds a control state machine so the Nios can offload the task of +-- monitoring the test progress. + +-- Nov 13th 2014 +-- name changed to ddr_testdriver +-- added generic for technology independance +-- added support for DDR4 in Arria10 +-- parameterise bus widths + +ENTITY ddr_testdriver IS + generic ( + g_SELECT_MODULE : IN INTEGER := 5 -- 0 for original guess using 'normal' high peed controller, + -- 1 for Micron MT4JSF12864HZ-1G4D1 at 800MT/s using high speed controller II + -- 2 for Micron MT4JSF12864HZ-1G4D1 at 1066MT/s using high speed controller II + -- 3 for Micron MT8JSF12864HZ-1G4D1 at 800MT/s using high speed controller II + -- 4 for Micron MT8JSF12864HZ-1G4D1 at 1066MT/s using high speed controller II + -- 5 for Micron MT16JSF51264HZ-1G4D1 at 1066MT/s using high speed controller II + -- 6 for Micron MT8JSF12864HZ-1G4D1 at 1066MT/s using high speed controller II with bitwise pnf + ); + PORT ( + -- GENERAL + CLK : IN STD_LOGIC; -- System Clock + reset_n : IN STD_LOGIC; -- active low reset + + -- SO-DIMM Memory Bank I + MB_I_EVENT : IN STD_LOGIC; + MB_I_DQ : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0); + MB_I_A : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); + MB_I_BA : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); + MB_I_DQS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_I_DQS_N : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_I_DM : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_I_CAS : OUT STD_LOGIC; + MB_I_RAS : OUT STD_LOGIC; + MB_I_WE : OUT STD_LOGIC; + MB_I_RESET : OUT STD_LOGIC; + MB_I_ODT : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_I_CK : INOUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_I_CK_N : INOUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_I_CKE : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_I_S : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_I_SCL : OUT STD_LOGIC; + MB_I_SDA : INOUT STD_LOGIC; + + -- SO-DIMM Memory Bank II + MB_II_EVENT : IN STD_LOGIC; + MB_II_DQ : INOUT STD_LOGIC_VECTOR(63 DOWNTO 0); + MB_II_A : OUT STD_LOGIC_VECTOR(15 DOWNTO 0); + MB_II_BA : OUT STD_LOGIC_VECTOR(2 DOWNTO 0); + MB_II_DQS : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_II_DQS_N : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_II_DM : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); + MB_II_CAS : OUT STD_LOGIC; + MB_II_RAS : OUT STD_LOGIC; + MB_II_WE : OUT STD_LOGIC; + MB_II_RESET : OUT STD_LOGIC; + MB_II_ODT : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_II_CK : INOUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_II_CK_N : INOUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_II_CKE : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_II_S : OUT STD_LOGIC_VECTOR(1 DOWNTO 0); + MB_II_SCL : OUT STD_LOGIC; + MB_II_SDA : INOUT STD_LOGIC; + + -- avalon MM control interface + mm_clock : in std_logic; + mm_writedata : in std_logic_vector(31 downto 0); + mm_readdata : out std_logic_vector(31 downto 0); + mm_write : in std_logic; + mm_address : in std_logic_vector(2 downto 0) + + ); +END ddr_testdriver; + +architecture archi of ddr_testdriver is + + + component ddr3_test_example_top_special_hsII1066_MT8 is + port ( + -- inputs: + signal clock_source : IN STD_LOGIC; + signal global_reset_n : IN STD_LOGIC; + signal start_test : IN STD_LOGIC; + + -- outputs: + signal mem_addr : OUT STD_LOGIC_VECTOR (13 DOWNTO 0); + signal mem_ba : OUT STD_LOGIC_VECTOR (2 DOWNTO 0); + signal mem_cas_n : OUT STD_LOGIC; + signal mem_cke : OUT STD_LOGIC_VECTOR (0 DOWNTO 0); + signal mem_clk : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0); + signal mem_clk_n : INOUT STD_LOGIC_VECTOR (1 DOWNTO 0); + signal mem_cs_n : OUT STD_LOGIC_VECTOR (0 DOWNTO 0); + signal mem_dm : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); + signal mem_dq : INOUT STD_LOGIC_VECTOR (63 DOWNTO 0); + signal mem_dqs : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); + signal mem_dqsn : INOUT STD_LOGIC_VECTOR (7 DOWNTO 0); + signal mem_odt : OUT STD_LOGIC_VECTOR (0 DOWNTO 0); + signal mem_ras_n : OUT STD_LOGIC; + signal mem_reset_n : OUT STD_LOGIC; + signal mem_we_n : OUT STD_LOGIC; + signal pnf : OUT STD_LOGIC; + signal pnf_per_byte : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + signal pnf_per_bit : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + signal data_per_bit : OUT STD_LOGIC_VECTOR (31 DOWNTO 0); + signal test_complete : OUT STD_LOGIC; + signal test_status : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) + ); + end component; + + + + type driver_state_type is ( + IDLE, + START_TEST, + WAIT_FOR_TEST, + STOP_ON_ERROR + ); + + + -- Signals for controlling the tests + signal driver_state_I : driver_state_type; + signal driver_state_II : driver_state_type; + signal control : STD_LOGIC_VECTOR (31 DOWNTO 0); + signal itercount_I : STD_LOGIC_VECTOR (63 DOWNTO 0); + signal itercount_II : STD_LOGIC_VECTOR (63 DOWNTO 0); + signal testtimeout_I : STD_LOGIC; + signal testtimeout_II : STD_LOGIC; + signal timeoutcount_I : STD_LOGIC_VECTOR (15 DOWNTO 0); + signal timeoutcount_II : STD_LOGIC_VECTOR (15 DOWNTO 0); + + + -- signal to generate delays before initialising the modules + signal delay_count : STD_LOGIC_VECTOR (23 DOWNTO 0); + signal delayed_resetn_I : STD_LOGIC; + signal delayed_resetn_II: STD_LOGIC; + + -- signals for controlling the tests + signal pnf_I_d1 : STD_LOGIC := '0'; + signal pnf_I_d2 : STD_LOGIC := '0'; + signal pnf_II_d1 : STD_LOGIC := '0'; + signal pnf_II_d2 : STD_LOGIC := '0'; + signal test_complete_I_d1 : STD_LOGIC := '0'; + signal test_complete_I_d2 : STD_LOGIC := '0'; + signal test_complete_II_d1 : STD_LOGIC := '0'; + signal test_complete_II_d2 : STD_LOGIC := '0'; + signal start_test_I : STD_LOGIC := '0'; + signal start_test_II : STD_LOGIC := '0'; + signal test_complete_I : STD_LOGIC; + signal test_complete_II : STD_LOGIC; + signal test_status_I : STD_LOGIC_VECTOR (7 DOWNTO 0); + signal test_status_II : STD_LOGIC_VECTOR (7 DOWNTO 0); + signal pnf_I : STD_LOGIC; + signal pnf_II : STD_LOGIC; + signal pnfperbyte_I : STD_LOGIC_VECTOR (31 DOWNTO 0); + signal pnfperbyte_II : STD_LOGIC_VECTOR (31 DOWNTO 0); + signal pnfperbit_I : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000"; + signal pnfperbit_II : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000"; + signal dataperbit_I : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000"; + signal dataperbit_II : STD_LOGIC_VECTOR (31 DOWNTO 0) := X"00000000"; + signal fsm_I : STD_LOGIC_VECTOR (1 DOWNTO 0); + signal fsm_II : STD_LOGIC_VECTOR (1 DOWNTO 0); + + +begin + +-- Avalon MM control registers +mm_interface: process(mm_clock) + variable arp_timeout_count : integer := 0; +begin + if mm_clock'event and mm_clock = '1' then + if mm_write = '1' then + case mm_address is + when "000" => + control <= mm_writedata; + when others => + + end case; + else + case mm_address is + when "001" => + mm_readdata <= test_status_I & X"0000" & "00" & fsm_I &"00" & testtimeout_I & pnf_I_d2; + when "010" => + mm_readdata <= itercount_I(31 downto 0); + when "011" => + mm_readdata <= itercount_I(63 downto 32); + when "100" => + mm_readdata <= test_status_II & X"0000" & "00" & fsm_II &"00" & testtimeout_II & pnf_II_d2; + when "101" => + mm_readdata <= itercount_II(31 downto 0); + when "110" => + mm_readdata <= itercount_II(63 downto 32); + when others => + mm_readdata <= X"ffffffff"; + end case; + end if; + + end if; +end process; + +-- Test control process +test_control_I: process(mm_clock) +begin + if mm_clock'event and mm_clock = '1' then + if reset_n = '0' then + driver_state_I <= IDLE; + driver_state_II <= IDLE; + itercount_I <= (others => '0'); + itercount_II <= (others => '0'); + pnf_I_d1 <= '0'; + pnf_I_d2 <= '0'; + pnf_II_d1 <= '0'; + pnf_II_d2 <= '0'; + test_complete_I_d1 <= '0'; + test_complete_I_d2 <= '0'; + test_complete_II_d1 <= '0'; + test_complete_II_d2 <= '0'; + else + -- reclock the control signals from the phy clock domains + pnf_I_d1 <= pnf_I; + pnf_I_d2 <= pnf_I_d1; + pnf_II_d1 <= pnf_II; + pnf_II_d2 <= pnf_II_d1; + test_complete_I_d1 <= test_complete_I; + test_complete_I_d2 <= test_complete_I_d1; + test_complete_II_d1 <= test_complete_II; + test_complete_II_d2 <= test_complete_II_d1; + + case driver_state_I is + when IDLE => + fsm_I <= "00"; + if control(0) = '1' then + itercount_I <= (others => '0'); + driver_state_I <= START_TEST; + end if; + when START_TEST => + fsm_I <= "01"; + start_test_I <= '1'; + timeoutcount_I <= (others => '0'); + testtimeout_I <= '0'; + driver_state_I <= WAIT_FOR_TEST; + when WAIT_FOR_TEST => + fsm_I <= "10"; + timeoutcount_I <= timeoutcount_I + 1; + + if timeoutcount_I = X"000F" then + start_test_I <= '0'; + end if; + if timeoutcount_I = X"FFFF" then + testtimeout_I <= '1'; + driver_state_I <= STOP_ON_ERROR; + end if; + + if test_complete_I_d2 = '1' then + if pnf_I_d2 = '1' then + if control(0) = '1' then + driver_state_I <= START_TEST; + itercount_I <= itercount_I + 1; + else + driver_state_I <= IDLE; + end if; + else + driver_state_I <= STOP_ON_ERROR; + end if; + end if; + when STOP_ON_ERROR => + fsm_I <= "11"; + if control(0) = '0' then + driver_state_I <= IDLE; + end if; + + when others => + driver_state_I <= IDLE; + + end case; + + + case driver_state_II is + when IDLE => + fsm_II <= "00"; + if control(1) = '1' then + itercount_II <= (others => '0'); + driver_state_II <= START_TEST; + end if; + when START_TEST => + fsm_II <= "01"; + start_test_II <= '1'; + timeoutcount_II <= (others => '0'); + testtimeout_II <= '0'; + driver_state_II <= WAIT_FOR_TEST; + when WAIT_FOR_TEST => + fsm_II <= "10"; + timeoutcount_II <= timeoutcount_II + 1; + + if timeoutcount_II = X"000F" then + start_test_II <= '0'; + end if; + + if timeoutcount_II = X"FFFF" then + testtimeout_II <= '1'; + driver_state_II <= STOP_ON_ERROR; + end if; + + if test_complete_II_d2 = '1' then + if PNF_II_d2 = '1' then + if control(1) = '1' then + driver_state_II <= START_TEST; + itercount_II <= itercount_II + 1; + else + driver_state_II <= IDLE; + end if; + else + driver_state_II <= STOP_ON_ERROR; + end if; + end if; + when STOP_ON_ERROR => + fsm_II <= "11"; + if control(1) = '0' then + driver_state_II <= IDLE; + end if; + + when others => + driver_state_II <= IDLE; + end case; + + end if; + end if; +end process; + + -- instantiate the DDR3 test generator examples depending on the chosen module + + hsIgen: if g_SELECT_MODULE = 0 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_I_A(14 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE, + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S, + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT, + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + ddr3_test_II : ddr3_test_example_top_runonce + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_II_A(14 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE, + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S, + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT, + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + end GENERATE hsIgen; + + hsII800gen: if g_SELECT_MODULE = 1 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce_hsII800 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_I_A(13 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE, + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S, + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT, + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + ddr3_test_II : ddr3_test_example_top_runonce_hsII800 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_II_A(13 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE, + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S, + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT, + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + end GENERATE hsII800gen; + + hsII1066gen: if g_SELECT_MODULE = 2 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce_hsII1066 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_I_A(13 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE, + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S, + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT, + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + ddr3_test_II : ddr3_test_example_top_runonce_hsII1066 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_II_A(13 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE, + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S, + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT, + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + end GENERATE hsII1066gen; + + hsII800MT8gen: if g_SELECT_MODULE = 3 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce_hsII800_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_I_A(13 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE(0 downto 0), + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S(0 downto 0), + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT(0 downto 0), + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + MB_I_CKE(1) <= '0'; + MB_I_S(1) <= '0'; + MB_I_ODT(1) <= '0'; + + ddr3_test_II : ddr3_test_example_top_runonce_hsII800_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => reset_n, + + -- outputs: + mem_addr => MB_II_A(13 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE(0 downto 0), + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S(0 downto 0), + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT(0 downto 0), + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + + MB_II_CKE(1) <= '0'; + MB_II_S(1) <= '0'; + MB_II_ODT(1) <= '0'; + + end GENERATE hsII800MT8gen; + + hsII1066MT8gen: if g_SELECT_MODULE = 4 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce_hsII1066_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_I, + + -- outputs: + mem_addr => MB_I_A(13 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE(0 downto 0), + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S(0 downto 0), + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT(0 downto 0), + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + MB_I_CKE(1) <= '0'; + MB_I_S(1) <= '0'; + MB_I_ODT(1) <= '0'; + + ddr3_test_II : ddr3_test_example_top_runonce_hsII1066_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_II, + + -- outputs: + mem_addr => MB_II_A(13 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE(0 downto 0), + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S(0 downto 0), + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT(0 downto 0), + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + + MB_II_CKE(1) <= '0'; + MB_II_S(1) <= '0'; + MB_II_ODT(1) <= '0'; + + end GENERATE hsII1066MT8gen; + + hsII1066MT16gen: if g_SELECT_MODULE = 5 GENERATE + ddr3_test_I : ddr3_test_example_top_runonce_hsII1066_MT16 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_I, + + -- outputs: + mem_addr => MB_I_A(14 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE, + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S, + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT, + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + ddr3_test_II : ddr3_test_example_top_runonce_hsII1066_MT16 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_II, + + -- outputs: + mem_addr => MB_II_A(14 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE, + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S, + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT, + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + end GENERATE hsII1066MT16gen; + + + hsII1066MT8specgen: if g_SELECT_MODULE = 6 GENERATE + ddr3_test_I : ddr3_test_example_top_special_hsII1066_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_I, + + -- outputs: + mem_addr => MB_I_A(13 downto 0), + mem_ba => MB_I_BA, + mem_cas_n => MB_I_CAS, + mem_cke => MB_I_CKE(0 downto 0), + mem_clk => MB_I_CK , + mem_clk_n => MB_I_CK_N, + mem_cs_n => MB_I_S(0 downto 0), + mem_dm => MB_I_DM, + mem_dq => MB_I_DQ, + mem_dqs => MB_I_DQS , + mem_dqsn => MB_I_DQS_N, + mem_odt => MB_I_ODT(0 downto 0), + mem_ras_n => MB_I_RAS, + mem_reset_n => MB_I_RESET, + mem_we_n => MB_I_WE, + pnf => pnf_I, + pnf_per_byte => pnfperbyte_I, + pnf_per_bit => pnfperbit_I, + data_per_bit => dataperbit_I, + start_test => start_test_I, + test_complete => test_complete_I, + test_status => test_status_I + ); + + MB_I_CKE(1) <= '0'; + MB_I_S(1) <= '0'; + MB_I_ODT(1) <= '0'; + + ddr3_test_II : ddr3_test_example_top_special_hsII1066_MT8 + port map( + -- inputs: + clock_source => CLK, + global_reset_n => delayed_resetn_II, + + -- outputs: + mem_addr => MB_II_A(13 downto 0), + mem_ba => MB_II_BA, + mem_cas_n => MB_II_CAS, + mem_cke => MB_II_CKE(0 downto 0), + mem_clk => MB_II_CK , + mem_clk_n => MB_II_CK_N, + mem_cs_n => MB_II_S(0 downto 0), + mem_dm => MB_II_DM, + mem_dq => MB_II_DQ, + mem_dqs => MB_II_DQS , + mem_dqsn => MB_II_DQS_N, + mem_odt => MB_II_ODT(0 downto 0), + mem_ras_n => MB_II_RAS, + mem_reset_n => MB_II_RESET, + mem_we_n => MB_II_WE, + pnf => pnf_II, + pnf_per_byte => pnfperbyte_II, + pnf_per_bit => pnfperbit_II, + data_per_bit => dataperbit_II, + start_test => start_test_II, + test_complete => test_complete_II, + test_status => test_status_II + ); + + MB_II_CKE(1) <= '0'; + MB_II_S(1) <= '0'; + MB_II_ODT(1) <= '0'; + + end GENERATE hsII1066MT8specgen; + + + + + delay_proc : process(mm_clock) + begin + if rising_edge(mm_clock)then + if reset_n = '0' then + delay_count <= (others => '0'); + delayed_resetn_I <= '0'; + delayed_resetn_II <= '0'; + else + if delayed_resetn_II = '0' then -- stop counter after module II enabled + delay_count <= delay_count + 1; + end if; + if delay_count = X"4C4B40" then -- 100ms +-- if delay_count = X"4C" then + delayed_resetn_I <= '1'; + end if; + if delay_count = X"989680" then -- 200ms +-- if delay_count = X"4C" then + delayed_resetn_II <= '1'; + end if; + end if; + end if; + end process; + + + + + + +end archi; + -- GitLab