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