diff --git a/applications/lofar2/libraries/ddrctrl/hdllib.cfg b/applications/lofar2/libraries/ddrctrl/hdllib.cfg
index 8f92d2ddd3f4d347fdfc32811cdbcefd07fe0288..24ebbd5221d3368de0a737ed46622798f23d32ef 100644
--- a/applications/lofar2/libraries/ddrctrl/hdllib.cfg
+++ b/applications/lofar2/libraries/ddrctrl/hdllib.cfg
@@ -1,6 +1,6 @@
 hdl_lib_name = lofar2_ddrctrl
 hdl_library_clause_name = lofar2_ddrctrl_lib
-hdl_lib_uses_synth = technology common tech_ddr dp
+hdl_lib_uses_synth = technology common tech_ddr dp io_ddr
 hdl_lib_uses_sim = 
 hdl_lib_technology = 
 
@@ -8,12 +8,14 @@ synth_files =
     src/vhdl/ddrctrl_address_counter.vhd 
     src/vhdl/ddrctrl_pack.vhd
     src/vhdl/ddrctrl_repack.vhd
+    src/vhdl/ddrctrl_input.vhd
     src/vhdl/ddrctrl.vhd
 
 test_bench_files =
     tb/vhdl/tb_ddrctrl_address_counter.vhd
     tb/vhdl/tb_ddrctrl_pack.vhd
     tb/vhdl/tb_ddrctrl_repack.vhd
+    tb/vhdl/tb_ddrctrl_input.vhd
     tb/vhdl/tb_ddrctrl.vhd
 
 regression_test_vhdl = 
diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd
index 838e8f5c89576d1b3a336d91e8d2ab180e863269..9577a0ca48378e3eede404c1f93486941a0fa9e2 100644
--- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl.vhd
@@ -32,29 +32,46 @@
 --  https://support.astron.nl/confluence/display/SBe/VHDL+design+patterns+for+RTL+coding
 --  The maximum value of the address is determend by g_tech_ddr.
 
-LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib;
+LIBRARY IEEE, technology_lib, tech_ddr_lib, common_lib, dp_lib, io_ddr_lib;
 USE IEEE.std_logic_1164.ALL;
 USE IEEE.numeric_std.ALL;
 USE technology_lib.technology_pkg.ALL;
+USE technology_lib.technology_select_pkg.ALL;
 USE tech_ddr_lib.tech_ddr_pkg.ALL;
 USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE dp_lib.dp_stream_pkg.ALL;
+USE io_ddr_lib.ALL;
 
 
 ENTITY ddrctrl IS
   GENERIC (
     g_tech_ddr        : t_c_tech_ddr;                                   -- type of memory
     g_sim_model       : BOOLEAN       := TRUE;                          -- determens if this is a simulation
+    g_technology      : NATURAL       := c_tech_select_default;
     g_nof_streams     : NATURAL       := 12;                            -- number of input streams
-    g_data_w          : NATURAL       := 14                             -- data with of input data vectors
-  );
+    g_data_w          : NATURAL       := 14;                            -- data with of input data vectors
+    g_wr_fifo_depth   : NATURAL       := 256;                           -- defined at DDR side of the FIFO, >=16 and independent of wr burst size, default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
+    g_rd_fifo_depth   : NATURAL       := 256                            -- defined at DDR side of the FIFO, >=16 AND > max number of rd burst sizes (so > c_rd_fifo_af_margin), default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
+    );
   PORT (
     clk               : IN  STD_LOGIC := '0';
     rst               : IN  STD_LOGIC;
     in_sosi_arr       : IN  t_dp_sosi_arr;                              -- input data
     out_of            : OUT NATURAL;                                    -- amount of internal overflow this output
-    out_mosi          : OUT t_mem_ctlr_mosi                             -- output data
+
+    term_ctrl_out     : OUT   t_tech_ddr3_phy_terminationcontrol;
+    term_ctrl_in      : IN    t_tech_ddr3_phy_terminationcontrol := c_tech_ddr3_phy_terminationcontrol_rst;
+    
+    -- DDR3 PHY external interface
+    phy3_in           : IN    t_tech_ddr3_phy_in := c_tech_ddr3_phy_in_x;
+    phy3_io           : INOUT t_tech_ddr3_phy_io;
+    phy3_ou           : OUT   t_tech_ddr3_phy_ou;
+    
+    -- DDR4 PHY external interface
+    phy4_in           : IN    t_tech_ddr4_phy_in := c_tech_ddr4_phy_in_x;
+    phy4_io           : INOUT t_tech_ddr4_phy_io;
+    phy4_ou           : OUT   t_tech_ddr4_phy_ou
   );
 END ddrctrl;
 
@@ -62,16 +79,25 @@ END ddrctrl;
 ARCHITECTURE str OF ddrctrl IS
 
   -- constant for readability
-  CONSTANT  c_out_data_w : NATURAL    := g_nof_streams*g_data_w;        -- the input data with for ddrctrl_repack
-
+  CONSTANT  c_out_data_w : NATURAL        := g_nof_streams*g_data_w;    -- the input data width for ddrctrl_repack 168
+  CONSTANT  c_io_ddr_data_w  : NATURAL    := func_tech_ddr_ctlr_data_w( g_tech_ddr );
 
   -- signals for connecting the components
   SIGNAL    data         : STD_LOGIC_VECTOR(c_out_data_w-1 DOWNTO 0);
   SIGNAL    sosi         : t_dp_sosi  := c_dp_sosi_init;
-  SIGNAL    a_of           : NATURAL    := 0;
+  SIGNAL    adr          : NATURAL    := 0;
+  SIGNAL    a_of         : NATURAL    := 0;
+  SIGNAL    ctrl_clk     : STD_LOGIC  := '0';
+  SIGNAL    ctrl_rst     : STD_LOGIC  := '0';
+  SIGNAL    wr_sosi      : t_dp_sosi  := c_dp_sosi_init;
+  SIGNAL    wr_siso      : t_dp_siso;
+  SIGNAL    rd_siso      : t_dp_siso;
+  SIGNAL    dvr_mosi     : t_mem_ctlr_mosi;
 
 BEGIN
 
+  dvr_mosi.address <= TO_UVEC(adr, dvr_mosi.address'length);
+
   -- makes one data vector out of all the data from the t_dp_sosi_arr
   u_pack : ENTITY work.ddrctrl_pack
   GENERIC MAP(
@@ -112,8 +138,83 @@ BEGIN
     rst               => rst,
     in_sosi           => sosi,                                          -- input data
     in_of             => a_of,
-    out_mosi          => out_mosi,                                      -- output data
-    out_of            => out_of
+    out_sosi          => wr_sosi,                                       -- output data
+    out_of            => out_of,
+    out_adr           => adr
+  );
+
+  -- functions as a fifo buffer for input data into the sdram stick. also manages input to sdram stick.
+  u_io_ddr : ENTITY io_ddr_lib.io_ddr
+  GENERIC MAP(
+    g_sim_model               => g_sim_model,
+    g_technology              => g_technology,
+    g_tech_ddr                => g_tech_ddr,
+    g_cross_domain_dvr_ctlr   => FALSE,
+    g_wr_data_w               => c_io_ddr_data_w,  
+    g_wr_fifo_depth           => g_wr_fifo_depth,
+    g_rd_fifo_depth           => g_rd_fifo_depth,
+    g_rd_data_w               => c_io_ddr_data_w,
+    g_wr_flush_mode           => "VAL",
+    g_wr_flush_use_channel    => FALSE,
+    g_wr_flush_start_channel  => 0,
+    g_wr_flush_nof_channels   => 1
+    )
+    PORT MAP(
+
+    -- DDR reference clock
+    ctlr_ref_clk              => clk,
+    ctlr_ref_rst              => rst,
+
+    -- DDR controller clock domain
+    ctlr_clk_out              => ctrl_clk,
+    ctlr_rst_out              => ctrl_rst,
+    
+    ctlr_clk_in               => ctrl_clk,
+    ctlr_rst_in               => ctrl_rst,
+    
+    -- MM clock + reset
+    mm_rst                    => rst,                                           
+    mm_clk                    => clk, 
+    
+    -- MM interface
+    reg_io_ddr_mosi           => open,
+    reg_io_ddr_miso           => open,
+    
+    -- Driver clock domain
+    dvr_clk                   => clk,
+    dvr_rst                   => rst,
+    
+    dvr_miso                  => open,
+    dvr_mosi                  => dvr_mosi,
+    
+    -- Write FIFO clock domain
+    wr_clk                    => clk,
+    wr_rst                    => rst,
+
+    wr_fifo_usedw             => open,
+    wr_sosi                   => wr_sosi,
+    wr_siso                   => wr_siso,
+  
+    -- Read FIFO clock domain
+    rd_clk                    => clk,
+    rd_rst                    => rst,
+    
+    rd_fifo_usedw             => open,
+    rd_sosi                   => open,
+    rd_siso                   => rd_siso,
+
+    term_ctrl_out             => term_ctrl_out,
+    term_ctrl_in              => term_ctrl_in,
+    
+    -- DDR3 PHY external interface
+    phy3_in                   => phy3_in,
+    phy3_io                   => phy3_io,
+    phy3_ou                   => phy3_ou,
+    
+    -- DDR4 PHY external interface
+    phy4_in                   => phy4_in,
+    phy4_io                   => phy4_io,
+    phy4_ou                   => phy4_ou
   );
 
 END str;
diff --git a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
index 25d43e825ad5bd8bd5babdb72071004b391f9945..8c2fad8bce712d12678a5ed6b4a9bd816ce857f0 100644
--- a/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
+++ b/applications/lofar2/libraries/ddrctrl/src/vhdl/ddrctrl_address_counter.vhd
@@ -49,8 +49,9 @@ ENTITY ddrctrl_address_counter IS
     rst                   : IN  STD_LOGIC;
     in_sosi               : IN  t_dp_sosi;                                                                                                -- input data
     in_of                 : IN  NATURAL;
-    out_mosi              : OUT t_mem_ctlr_mosi                   := c_mem_ctlr_mosi_rst;                                                 -- output data
-    out_of                : OUT NATURAL
+    out_sosi              : OUT t_dp_sosi                         := c_dp_sosi_init;                                                      -- output data
+    out_of                : OUT NATURAL;
+    out_adr               : OUT NATURAL
   );
 END ddrctrl_address_counter;
 
@@ -60,7 +61,7 @@ ARCHITECTURE rtl OF ddrctrl_address_counter IS
   -- constants for readability
   CONSTANT c_data_w       : NATURAL                               := func_tech_ddr_ctlr_data_w( g_tech_ddr );                             -- the with of the input data and output data, 576
   CONSTANT c_adr_w        : NATURAL                               := sel_a_b(g_sim_model, 4, func_tech_ddr_ctlr_address_w( g_tech_ddr )); -- the lengt of the address vector, for simulation this is smaller, otherwise the simulation would take to long, 27
-  CONSTANT c_max_adr      : STD_LOGIC_VECTOR(c_adr_w-1 DOWNTO 0)  := STD_LOGIC_VECTOR(TO_UVEC(2**(c_adr_w)-1, c_adr_w));                  -- the maximal address that is possible within the vector length of the address
+  CONSTANT c_max_adr      : NATURAL                               := 2**(c_adr_w)-1;                                                      -- the maximal address that is possible within the vector length of the address
 
   -- type for statemachine
   TYPE t_state IS (RESET, COUNTING, MAX, IDLE);
@@ -68,13 +69,14 @@ ARCHITECTURE rtl OF ddrctrl_address_counter IS
   -- record for readability
   TYPE t_reg IS RECORD
   state                   : t_state;
-  out_mosi                : t_mem_ctlr_mosi;
+  out_sosi                : t_dp_sosi;
   out_of                  : NATURAL;
   s_in_sosi               : t_dp_sosi;
   s_in_of                 : NATURAL;
+  s_adr                   : NATURAL;
   END RECORD;
 
-  CONSTANT  c_t_reg_init  : t_reg                                 := (RESET, c_mem_ctlr_mosi_rst, 0, c_dp_sosi_init, 0);
+  CONSTANT  c_t_reg_init  : t_reg                                 := (RESET, c_dp_sosi_init, 0, c_dp_sosi_init, 0, 0);
 
 
   -- signals for readability
@@ -92,8 +94,8 @@ BEGIN
 
   BEGIN
     v                                                             := q_reg;
-    v.out_mosi.wrdata(c_data_w-1 DOWNTO 0)                        := q_reg.s_in_sosi.data(c_data_w - 1 DOWNTO 0);
-    v.out_mosi.wr                                                 := q_reg.s_in_sosi.valid;
+    v.out_sosi.data(c_data_w-1 DOWNTO 0)                          := q_reg.s_in_sosi.data(c_data_w - 1 DOWNTO 0);
+    v.out_sosi.valid                                              := q_reg.s_in_sosi.valid;
     v.out_of                                                      := q_reg.s_in_of;
     v.s_in_sosi                                                   := in_sosi;
     v.s_in_of                                                     := in_of;
@@ -101,13 +103,13 @@ BEGIN
 
     CASE q_reg.state IS
     WHEN RESET =>
-      v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0');
+      v.s_adr := 0;
 
     WHEN COUNTING =>
-      v.out_mosi.address(c_adr_w-1 DOWNTO 0) := STD_LOGIC_VECTOR(TO_UVEC(TO_UINT(q_reg.out_mosi.address)+1, c_adr_w));
+      v.s_adr := q_reg.s_adr+1;
 
     WHEN MAX =>
-      v.out_mosi.address(c_adr_w-1 DOWNTO 0) := (OTHERS => '0');
+      v.s_adr := 0;
 
     WHEN IDLE =>
 
@@ -115,7 +117,7 @@ BEGIN
 
     IF rst = '1' THEN
       v.state := RESET;
-    ELSIF q_reg.out_mosi.address(c_adr_w-1 DOWNTO 0) = c_max_adr(c_adr_w-1 DOWNTO 0) AND in_sosi.valid = '1' THEN
+    ELSIF q_reg.s_adr = c_max_adr AND in_sosi.valid = '1' THEN
       v.state := MAX;
     ELSIF in_sosi.valid = '1' THEN
       v.state := COUNTING;
@@ -127,7 +129,8 @@ BEGIN
   END PROCESS;
 
   -- fill outputs
-  out_mosi <= q_reg.out_mosi;
+  out_sosi <= q_reg.out_sosi;
   out_of   <= q_reg.out_of;
+  out_adr  <= q_reg.s_adr;
 
 END rtl;
diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd
index 8b56c9ddcf22d7455e0099fbc19f4179ba6e526c..ff2f25739c6e171f8d4739cbab2604826d7f58a9 100644
--- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd
+++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl.vhd
@@ -40,7 +40,9 @@ ENTITY tb_ddrctrl IS
     g_nof_streams             : POSITIVE                                              := 12;                                      -- number of input streams
     g_data_w                  : NATURAL                                               := 14;                                      -- data with of input data vectors
     g_sim_length              : NATURAL                                               := 52
-
+    g_technology              : NATURAL                                               := c_tech_select_default;
+    g_wr_fifo_depth           : NATURAL                                               := 256;                                     -- defined at DDR side of the FIFO, >=16 and independent of wr burst size, default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
+    g_rd_fifo_depth           : NATURAL                                               := 256                                      -- defined at DDR side of the FIFO, >=16 AND > max number of rd burst sizes (so > c_rd_fifo_af_margin), default >= 256 because 32b*256 fits in 1 M9K so c_ctlr_data_w=256b will require 8 M9K
   );
 END tb_ddrctrl;
 
@@ -195,15 +197,17 @@ BEGIN
   GENERIC MAP (
     g_tech_ddr        => g_tech_ddr,
     g_sim_model       => g_sim_model,
+    g_technology      => g_technology,
     g_nof_streams     => g_nof_streams,
-    g_data_w          => g_data_w
+    g_data_w          => g_data_w,
+    g_wr_fifo_depth   => g_wr_fifo_depth,
+    g_rd_fifo_depth   => g_rd_fifo_depth
   )
   PORT MAP (
     clk               => clk,
     rst               => rst,
     in_sosi_arr       => in_sosi_arr,
     out_of            => out_of,
-    out_mosi          => out_mosi
   );
 
 END tb;
diff --git a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
index a17f098b594c673887acdc59f982a8dd87d515f2..14f4d34b1982c2f65f0fe7055c58e0b7c4f50b1d 100644
--- a/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
+++ b/applications/lofar2/libraries/ddrctrl/tb/vhdl/tb_ddrctrl_address_counter.vhd
@@ -61,7 +61,8 @@ ARCHITECTURE tb OF tb_ddrctrl_address_counter IS
   SIGNAL    in_of             : NATURAL         := 0;                                       -- signal which contains the amount of overflow
 
   -- output signal from ddrctrl_address_counter.vhd
-  SIGNAL    out_mosi          : t_mem_ctlr_mosi := c_mem_ctlr_mosi_rst;                     -- signal which is the output from ddrctrl_address_counter.vhd
+  SIGNAL    out_sosi          : t_dp_sosi := c_dp_sosi_init;                     -- signal which is the output from ddrctrl_address_counter.vhd
+  SIGNAL    out_adr           : NATURAL         := 0;
   SIGNAL    out_of            : NATURAL         := 0;                                       -- signal which is the output from ddrctrl_address_counter.vhd
 
   -- testbench signals
@@ -112,8 +113,8 @@ BEGIN
     ASSERT FALSE                                                                      REPORT "Test: OK"                                                                                                                           SEVERITY FAILURE;
   END PROCESS;
 
-  -- generating compare data for out_mosi
-  p_out_mosi : PROCESS
+  -- generating compare data for out_sosi
+  p_out_sosi : PROCESS
   BEGIN
     WAIT UNTIL rising_edge(clk);
     if rising_edge(clk) THEN
@@ -128,10 +129,10 @@ BEGIN
       q_rst              <= rst;
     END IF;
     IF q_rst = '1' THEN
-      IF lag_due_reset + TO_UINT(out_mosi.address) >= c_adr_size THEN
-        lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address)-c_adr_size;
+      IF lag_due_reset + out_adr >= c_adr_size THEN
+        lag_due_reset <= lag_due_reset+out_adr-c_adr_size;
       ELSE
-        lag_due_reset <= lag_due_reset+TO_UINT(out_mosi.address);
+        lag_due_reset <= lag_due_reset+out_adr;
       END IF;
     END IF;
   END PROCESS;
@@ -142,8 +143,8 @@ BEGIN
   BEGIN
     WAIT UNTIL rising_edge(clk);
     IF rising_edge(clk) THEN
-      ASSERT q_q_in_data(c_data_w-1 DOWNTO 0) = out_mosi.wrdata(c_data_w-1 DOWNTO 0)  REPORT "in_sosi.data does not match out_mosi.wrdata"                                                                                        SEVERITY ERROR;
-      ASSERT q_q_in_data_enable               = out_mosi.wr                           REPORT "in_sosi.valid does not match out_mosi.wr"                                                                                           SEVERITY ERROR;
+      ASSERT q_q_in_data(c_data_w-1 DOWNTO 0) = out_sosi.data(c_data_w-1 DOWNTO 0)    REPORT "in_sosi.data does not match out_sosi.wrdata"                                                                                        SEVERITY ERROR;
+      ASSERT q_q_in_data_enable               = out_sosi.valid                        REPORT "in_sosi.valid does not match out_sosi.wr"                                                                                           SEVERITY ERROR;
       ASSERT q_q_in_of                        = out_of                                REPORT "in_of does not match out_of"                                                                                                        SEVERITY ERROR;
     END IF;
   END PROCESS;
@@ -162,13 +163,13 @@ BEGIN
   BEGIN
     FOR I IN 0 TO c_adr_size-1 LOOP
       IF I >= q_lag_due_reset THEN
-        ASSERT I-q_lag_due_reset              = TO_UINT(out_mosi.address)             REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address))              SEVERITY ERROR;
+        ASSERT I-q_lag_due_reset              = out_adr                      REPORT "Wrong address, 1, I = " & NATURAL'image(I-q_lag_due_reset) & ", address = " & NATURAL'image(out_adr)                       SEVERITY ERROR;
       ELSE
-        ASSERT (I-q_lag_due_reset)+c_adr_size = TO_UINT(out_mosi.address)             REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(TO_UINT(out_mosi.address)) SEVERITY ERROR;
+        ASSERT (I-q_lag_due_reset)+c_adr_size = out_adr                      REPORT "Wrong address, 2, I = " & NATURAL'image((I-q_lag_due_reset)+c_adr_size) & ", address = " & NATURAL'image(out_adr)          SEVERITY ERROR;
       END IF;
-      WAIT UNTIL out_mosi.wr = '1';     
+      WAIT UNTIL out_sosi.valid = '1';     
       IF q_q_rst = '1' THEN
-        WAIT UNTIL out_mosi.wr = '1';
+        WAIT UNTIL out_sosi.valid = '1';
       END IF;
     END LOOP;
   END PROCESS;
@@ -186,8 +187,9 @@ BEGIN
     in_sosi           => in_sosi,
     in_of             => in_of,
 
-    out_mosi          => out_mosi,
-    out_of            => out_of
+    out_sosi          => out_sosi,
+    out_of            => out_of,
+    out_adr           => out_adr
   );
 
 END tb;