diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd
index 771b6ace6f76fbb22079481055a6791ada71d8c9..7ba7531c4987a8d314f1a0efb2663291a09f8ea5 100644
--- a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd
+++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/apertif_unb1_fn_beamformer_tp_bg.vhd
@@ -27,7 +27,8 @@ ENTITY apertif_unb1_fn_beamformer_tp_bg IS
   GENERIC (
     g_design_name : STRING  := "apertif_unb1_fn_beamformer_tp_bg"; 
     g_design_note : STRING  := "transpose revision with BGs"; 
-    g_sim         : BOOLEAN := FALSE; 
+    g_sim         : BOOLEAN := FALSE;
+    g_sim_model   : BOOLEAN := FALSE; -- Use fast DDR3 sim model
     g_sim_unb_nr  : NATURAL := 0;
     g_sim_node_nr : NATURAL := 0;
     g_stamp_date  : NATURAL := 0;
@@ -101,7 +102,8 @@ BEGIN
   GENERIC MAP (
     g_design_name => g_design_name,
     g_design_note => g_design_note,
-    g_sim         => g_sim,        
+    g_sim         => g_sim,   
+    g_sim_model   => g_sim_model,     
     g_sim_unb_nr  => g_sim_unb_nr, 
     g_sim_node_nr => g_sim_node_nr,
     g_stamp_date  => g_stamp_date, 
diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd
index 64318f84b37e5412996866d87b72e699b5b2a07e..df21cd03c3dec547a6e2dda79093dd64d4628f82 100644
--- a/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd
+++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/revisions/apertif_unb1_fn_beamformer_tp_bg/tb_apertif_unb1_fn_beamformer_tp_bg.vhd
@@ -39,6 +39,7 @@ END tb_apertif_unb1_fn_beamformer_tp_bg;
 ARCHITECTURE tb OF tb_apertif_unb1_fn_beamformer_tp_bg IS
 
   CONSTANT c_sim             : BOOLEAN := TRUE;
+  CONSTANT c_sim_model       : BOOLEAN := TRUE; --Use fast DDR3 sim model
 
   CONSTANT c_unb_nr          : NATURAL := 0; -- UniBoard 0
   CONSTANT c_node_nr         : NATURAL := 0; -- Front node 0
@@ -111,6 +112,7 @@ BEGIN
   u_apertif_unb1_fn_beamformer : ENTITY work.apertif_unb1_fn_beamformer_tp_bg
     GENERIC MAP (
       g_sim         => c_sim,
+      g_sim_model   => c_sim_model,
       g_sim_unb_nr  => c_unb_nr,
       g_sim_node_nr => c_node_nr
     )
@@ -159,15 +161,16 @@ BEGIN
   ------------------------------------------------------------------------------
   -- DDR3 memory model
   ------------------------------------------------------------------------------
-  u_tech_ddr_memory_model : ENTITY tech_ddr_lib.tech_ddr_memory_model
-  GENERIC MAP (
-    g_tech_ddr => c_ddr
-  )
-  PORT MAP (
-    mem3_in => phy_ou,
-    mem3_io => phy_io,
-    mem3_ou => phy_in
-  );
-    
+  gen_tech_ddr_memory_model : IF c_sim_model = FALSE GENERATE
+    u_tech_ddr_memory_model : ENTITY tech_ddr_lib.tech_ddr_memory_model
+    GENERIC MAP (
+      g_tech_ddr => c_ddr
+    )
+    PORT MAP (
+      mem3_in => phy_ou,
+      mem3_io => phy_io,
+      mem3_ou => phy_in
+    );
+   END GENERATE;   
 
 END tb;
diff --git a/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd b/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd
index 3f725a3758e69c5f45f3bd8b6bc7010aae2d072a..768ef9b138de804469bba1f84667553da87eff1f 100644
--- a/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd
+++ b/applications/apertif/designs/apertif_unb1_fn_beamformer/src/vhdl/apertif_unb1_fn_beamformer.vhd
@@ -43,6 +43,7 @@ ENTITY apertif_unb1_fn_beamformer IS
     g_design_name : STRING  := "apertif_unb1_fn_beamformer"; --"apertif_unb1_fn_beamformer";
     g_design_note : STRING  := "revision info"; --"UNUSED";
     g_sim         : BOOLEAN := FALSE; --Overridden by TB
+    g_sim_model   : BOOLEAN := FALSE; -- Use fast DDR3 model
     g_sim_unb_nr  : NATURAL := 0;
     g_sim_node_nr : NATURAL := 0;
     g_stamp_date  : NATURAL := 0;  -- Date (YYYYMMDD) -- set by QSF
@@ -529,6 +530,7 @@ BEGIN
     
     u_ddr_mem_ctrl : ENTITY io_ddr_lib.io_ddr
     GENERIC MAP( 
+      g_sim_model              => g_sim_model,
       g_technology             => c_tech_select_default, 
       g_tech_ddr               => c_tech_ddr,      
       g_cross_domain_dvr_ctlr  => FALSE, 
diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd
index 4fe304f12f1f2eb828b9545c285d168428ea66cc..1a4a516dfca2e8a38163c37ee9085a7b6d704bef 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd
@@ -154,6 +154,7 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY io_ddr IS
   GENERIC(
+    g_sim_model               : BOOLEAN := FALSE;
     g_technology              : NATURAL := c_tech_select_default;
     g_tech_ddr                : t_c_tech_ddr;
     g_cross_domain_dvr_ctlr   : BOOLEAN := TRUE;
@@ -441,6 +442,7 @@ BEGIN
   
   u_tech_ddr : ENTITY tech_ddr_lib.tech_ddr
   GENERIC MAP (
+    g_sim_model            => g_sim_model,
     g_technology           => g_technology,
     g_tech_ddr             => g_tech_ddr
   )
diff --git a/libraries/technology/ddr/tech_ddr.vhd b/libraries/technology/ddr/tech_ddr.vhd
index 79dcd05a1165e8aba6c659dedb6a291c129feca4..03961ea0085e885f76acecd6d7d76ecc2ea39c9c 100644
--- a/libraries/technology/ddr/tech_ddr.vhd
+++ b/libraries/technology/ddr/tech_ddr.vhd
@@ -27,6 +27,7 @@
 
 LIBRARY IEEE, common_lib, technology_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
+USE common_lib.common_pkg.ALL;
 USE common_lib.common_mem_pkg.ALL;
 USE technology_lib.technology_pkg.ALL;
 USE technology_lib.technology_select_pkg.ALL;
@@ -34,6 +35,7 @@ USE work.tech_ddr_pkg.ALL;
 
 ENTITY tech_ddr IS
   GENERIC (
+    g_sim_model            : BOOLEAN := FALSE; -- TRUE: use fast behavioural model, requires no external memory (uses memory array).
     g_technology           : NATURAL := c_tech_select_default;
     g_tech_ddr             : t_c_tech_ddr
   );
@@ -69,25 +71,128 @@ END tech_ddr;
 
 ARCHITECTURE str OF tech_ddr IS
 
+  CONSTANT c_nof_addr : NATURAL := 8192;
+  CONSTANT c_dat_w    : NATURAL := 256;
+
+  TYPE t_mem_arr IS ARRAY(0 TO c_nof_addr-1) OF STD_LOGIC_VECTOR(c_dat_w-1 DOWNTO 0);
+
+  SIGNAL sim_clk : STD_LOGIC;
+  SIGNAL sim_rst : STD_LOGIC;
+  SIGNAL sim_ctlr_mosi : t_mem_ctlr_mosi;
+
+  SIGNAL address : NATURAL;
+
 BEGIN
- 
-  gen_ip_stratixiv : IF g_technology=c_tech_stratixiv GENERATE
-    u0 : ENTITY work.tech_ddr_stratixiv
-    GENERIC MAP (g_tech_ddr)
-    PORT MAP (ref_clk, ref_rst,
-              ctlr_gen_clk, ctlr_gen_rst, ctlr_gen_clk_2x, ctlr_gen_rst_2x,
-              ctlr_mosi, ctlr_miso, term_ctrl_out, term_ctrl_in,
-              phy3_in, phy3_io, phy3_ou);
+
+  -----------------------------------------------------------------------------
+  -- Technology IP cores
+  ----------------------------------------------------------------------------- 
+  gen_ip: IF g_sim_model = FALSE GENERATE
+    gen_ip_stratixiv : IF g_technology=c_tech_stratixiv GENERATE
+      u0 : ENTITY work.tech_ddr_stratixiv
+      GENERIC MAP (g_tech_ddr)
+      PORT MAP (ref_clk, ref_rst,
+                ctlr_gen_clk, ctlr_gen_rst, ctlr_gen_clk_2x, ctlr_gen_rst_2x,
+                ctlr_mosi, ctlr_miso, term_ctrl_out, term_ctrl_in,
+                phy3_in, phy3_io, phy3_ou);
+    END GENERATE;
+    
+    gen_ip_arria10 : IF g_technology=c_tech_arria10 GENERATE
+      u0 : ENTITY work.tech_ddr_arria10
+      GENERIC MAP (g_tech_ddr)
+      PORT MAP (ref_clk, ref_rst,
+                ctlr_gen_clk, ctlr_gen_rst,
+                ctlr_mosi, ctlr_miso,
+                phy4_in, phy4_io, phy4_ou);
+    END GENERATE;
   END GENERATE;
+ 
+  -----------------------------------------------------------------------------
+  -- Functional simulation model
+  -- . Note: is it assumed that the user only performs burst reads/writes!
+  -----------------------------------------------------------------------------
+  gen_sim_model : IF g_sim_model=TRUE GENERATE
+    -- Prevent delta delay issues by using a re-assigned clk both internally 
+    -- (sim_clk) and externally (ctrl_gen_clk)
+    ctlr_gen_clk <= ref_clk;
+    ctlr_gen_rst <= ref_rst;
+    sim_clk      <= ref_clk;
+    sim_rst      <= ref_rst;
   
-  gen_ip_arria10 : IF g_technology=c_tech_arria10 GENERATE
-    u0 : ENTITY work.tech_ddr_arria10
-    GENERIC MAP (g_tech_ddr)
-    PORT MAP (ref_clk, ref_rst,
-              ctlr_gen_clk, ctlr_gen_rst,
-              ctlr_mosi, ctlr_miso,
-              phy4_in, phy4_io, phy4_ou);
-  END GENERATE;
+    ctlr_miso.done   <= '0' , '1' AFTER 1000 ps;
+    ctlr_miso.cal_ok <= '0' , '1' AFTER 1000 ps;
   
+    -- Delay the control one cycle here so p_mem_access can update its outputs
+    -- immediately
+    p_clk : PROCESS(sim_clk)
+    BEGIN
+      IF rising_edge(sim_clk) THEN
+        sim_ctlr_mosi <= ctlr_mosi;
+      END IF;
+    END PROCESS;
+  
+    p_mem_access : PROCESS(sim_clk, sim_ctlr_mosi)
+      VARIABLE v_enable_model  : BOOLEAN := FALSE;
+      VARIABLE v_mem_arr       : t_mem_arr := (OTHERS=>(OTHERS=>'0'));
+      VARIABLE v_address       : NATURAL := 0;
+      VARIABLE v_wr_bursting   : BOOLEAN := FALSE;
+      VARIABLE v_rd_bursting   : BOOLEAN := FALSE;
+      VARIABLE v_burst_cnt     : NATURAL := 0;
+      VARIABLE v_burst_size    : NATURAL := 0;
+    BEGIN
+  
+      -- Don't waste simulation time when user does not use the model anyway
+      IF v_enable_model = FALSE THEN
+        ctlr_miso.waitrequest_n <= '1'; 
+        IF sim_ctlr_mosi.burstbegin='1' THEN
+          v_enable_model := TRUE;
+        END IF;
+      END IF;
+  
+      IF v_enable_model = TRUE THEN
+        IF rising_edge(sim_clk) THEN
+    
+          ctlr_miso.rdval <= '0'; 
+          ctlr_miso.waitrequest_n <= '1'; 
+    
+          -- Access: burst begin
+          IF sim_ctlr_mosi.burstbegin='1' THEN
+            IF sim_ctlr_mosi.wr='1' THEN
+              v_wr_bursting := TRUE;
+            ELSIF sim_ctlr_mosi.rd='1' THEN
+              v_rd_bursting := TRUE;
+            END IF;
+            v_address     := TO_UINT(sim_ctlr_mosi.address);
+            v_burst_size  := TO_UINT(sim_ctlr_mosi.burstsize);
+            v_burst_cnt   := 0;
+          END IF;
+      
+          IF v_wr_bursting=TRUE OR v_rd_bursting=TRUE THEN
+            IF sim_ctlr_mosi.wr='1' THEN -- Write
+              v_mem_arr(v_address) := sim_ctlr_mosi.wrdata(c_dat_w-1 DOWNTO 0);
+              v_address   := v_address+1;
+              v_burst_cnt := v_burst_cnt +1;
+            ELSIF v_rd_bursting=TRUE THEN -- Read
+              ctlr_miso.rddata(c_dat_w-1 DOWNTO 0) <= v_mem_arr(v_address);  
+              ctlr_miso.rdval <= '1';
+              ctlr_miso.waitrequest_n <= '0';
+              v_address   := v_address+1;
+              v_burst_cnt := v_burst_cnt +1;
+            END IF;
+      
+            IF v_burst_cnt = v_burst_size THEN
+              v_wr_bursting := FALSE;
+              v_rd_bursting := FALSE;
+            END IF;
+          END IF;
+      
+          address <= v_address;
+    
+        END IF;
+      END IF;
+  
+    END PROCESS;
+  END GENERATE;
+ 
 END str;