diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
index bcae51be4d3e714c1a7816ef2c3d98520a50dc24..6b1bec8ba6a243392899fb1f3c7515676f3f4c09 100644
--- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
@@ -44,7 +44,7 @@ USE tech_ddr_lib.tech_ddr_pkg.ALL;
 
 ENTITY tb_io_ddr IS
   GENERIC (
-    g_sim_model             : BOOLEAN := FALSE;
+    g_sim_model             : BOOLEAN := TRUE;  --FALSE;
     g_technology            : NATURAL := c_tech_select_default;
     g_tech_ddr3             : t_c_tech_ddr := c_tech_ddr3_4g_800m_master;
     g_tech_ddr4             : t_c_tech_ddr := c_tech_ddr4_4g_1600m;
diff --git a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
index 8d7a99493202fa8f8e45169ed30de1643344f21a..b50423baf2dae7d994cbb663cfb26d0adeb94d96 100644
--- a/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_tb_io_ddr.vhd
@@ -39,7 +39,6 @@ END tb_tb_io_ddr;
 
 ARCHITECTURE tb OF tb_tb_io_ddr IS
 
-  CONSTANT c_sim_model      : BOOLEAN := FALSE;
   CONSTANT c_technology     : NATURAL      := c_tech_select_default;
   CONSTANT c_tech_ddr3      : t_c_tech_ddr := c_tech_ddr3_4g_800m_master;
   CONSTANT c_tech_ddr4      : t_c_tech_ddr := c_tech_ddr4_4g_1600m;
@@ -66,11 +65,9 @@ BEGIN
   -- g_nof_repeat            : NATURAL := 1;      -- number of stimuli repeats with write flush after each repeat
   -- g_wr_flush_mode         : STRING := "SYN"    -- "VAL", "SOP", "SYN"
 
-  gen_sim_model: IF c_sim_model=TRUE GENERATE
-    u_sim_model                 : ENTITY work.tb_io_ddr GENERIC MAP ( TRUE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE,  5 ns,  4,  2500, 2, 1, 1,   1, "VAL") PORT MAP (tb_end_vec(0));
-  END GENERATE;
+  u_sim_model : ENTITY work.tb_io_ddr GENERIC MAP ( TRUE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE,  5 ns,  4,  2500, 2, 1, 1,   1, "VAL") PORT MAP (tb_end_vec(0));
   
-  gen_ddr3 : IF c_sim_model=FALSE AND c_tech_ddr.name="DDR3" GENERATE
+  gen_ddr3 : IF c_tech_ddr.name="DDR3" GENERATE
     u_default                   : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE,  5 ns,  4,  2500, 2, 1, 1,   1, "VAL") PORT MAP (tb_end_vec(0));
                                                                                                                                         
     u_fill_wrfifo_on_next_valid : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE,  5 ns,  1,  1000, 2, 1, 4,   2, "VAL") PORT MAP (tb_end_vec(1));
@@ -91,7 +88,7 @@ BEGIN
   END GENERATE;
 
   -- Distinghuis between tests for DDR3 and DDR4, because the Quartus 14.1 ip_arria10 DDR4 model simulates about 40x slower than the Quartus 11.1 ip_stratixiv DDR3 uniphy model.
-  gen_ddr4 : IF c_sim_model=FALSE AND c_tech_ddr.name="DDR4" GENERATE
+  gen_ddr4 : IF c_tech_ddr.name="DDR4" GENERATE
     u_default                   : ENTITY work.tb_io_ddr GENERIC MAP (FALSE, c_technology, c_tech_ddr3, c_tech_ddr4, FALSE, FALSE,  5 ns,  4,  2500, 2, 1, 1,   1, "VAL") PORT MAP (tb_end_vec(0));
   END GENERATE;
   
diff --git a/libraries/technology/ddr/sim_ddr.vhd b/libraries/technology/ddr/sim_ddr.vhd
index d6fc241af788eb86de9455fa33a7190d12d4aafe..6bc51b873fdd70ea514203df18730cea8620c81f 100644
--- a/libraries/technology/ddr/sim_ddr.vhd
+++ b/libraries/technology/ddr/sim_ddr.vhd
@@ -20,14 +20,49 @@
 --
 --------------------------------------------------------------------------------
 
+-- Author: Eric Kooistra, 19 june 2017
 -- Purpose: Functional simulation model of both the DDR driver and the DDR memory.
 -- Description:
---   The component also supports different types of DDR, so DDR3 and DDR4.
--- Remark:
--- . It is assumed that the user only performs burst reads/writes!
--- . Modelsim raises warning 3391 when the DDR memory set by c_nof_addr is to big to fit in PC RAM.
---   Use 'verror 3391' to display the help. This means that the computer becomes too slow due to
---   page swapping to disk. Even loading the simulation becomes slow.
+--   This DDR model supports different types of DDR, so DDR3 and DDR4.
+--
+--   During a write burst the user still controls the access rate by means of
+--   ctrl_mosi.wr. During a read burst the memory determines the access rate.
+--   Therefore a new write or read burst request will not occure during a write
+--   burst, but they can occur during a read burst. The ctrl_mosi.address and
+--   ctrl_mosi.burstsize are then captured with the pending_rd and prnding wr 
+--   state and the ctlr_miso.waitrequest_n is pulled low because the model only
+--   supports one pending burst request.
+--   
+--   The internal state of the DDR model is maintained in a variable of type
+--   t_mem_state. For debugging purposes this state is also assigned to a 
+--   signal to be able to view it together with ctrl_mosi and ctrl_miso in the
+--   wave window.
+-- 
+-- * About other DDR features:
+--   The sim_ddr only models the memory contents of the DDR, which is sufficient
+--   for now, because that is the main function of DDR and initially it is best
+--   to keep the model as simple as possible. If necessary, then possible extra
+--   future features could be to also model the latency caused by a periodical
+--   DRAM refresh cycle.
+--
+-- * About fixed size DDR memory:
+--   The sim_ddr uses a fixed size simulation memory that cannot be too large,
+--   because it as to fit in the PC memory. Modelsim raises warning 3391 when
+--   the DDR memory set by c_nof_addr is to big to fit in PC RAM. Use 
+--   'verror 3391' to display the help. This means that the computer becomes
+--   too slow due to  page swapping to disk. Even loading the simulation
+--   becomes slow. A way around this would be to use a simulation memory that
+--   grows dynamically for each address that is actually used (like a
+--   dictionary). An example of such a dynamic DDR memory model is available at:
+--
+--      https://svn.astron.nl/UniBoard_FP7/UniBoard/trunk/Firmware/modules/MegaWizard/ddr3/testbench/ddr3_test_mem_model.vhd
+--
+--   However this dynamic model will simulate slower the more it gets filled.
+--   Furthermore the simulation time of such larger blocks of data will
+--   become unfeasible. Instead it is better to scale the parameters of the
+--   application such that the fixed size sim_ddr memory is as small as
+--   possible.
+
 
 LIBRARY IEEE, common_lib, technology_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
@@ -67,20 +102,22 @@ ARCHITECTURE str OF sim_ddr IS
   -- DDR memory
   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 address               : NATURAL;
-  SIGNAL burst_size            : NATURAL;
-  SIGNAL burst_cnt             : NATURAL;
-  SIGNAL waitrequest_n         : STD_LOGIC := '1';
-  SIGNAL wr_bursting           : BOOLEAN := FALSE;
-  SIGNAL rd_bursting           : BOOLEAN := FALSE;
-  
-  SIGNAL pending_wr            : BOOLEAN := FALSE;
-  SIGNAL pending_rd            : BOOLEAN := FALSE;
-  SIGNAL pending_address       : NATURAL;
-  SIGNAL pending_burst_size    : NATURAL;
+  TYPE t_mem_state IS RECORD
+    address            : NATURAL;
+    burst_size         : NATURAL;
+    burst_cnt          : NATURAL;   -- = 0
+    wr_bursting        : BOOLEAN;   -- = FALSE
+    rd_bursting        : BOOLEAN;   -- = FALSE
+    pending_wr         : BOOLEAN;   -- = FALSE
+    pending_rd         : BOOLEAN;   -- = FALSE
+    pending_address    : NATURAL;
+    pending_burst_size : NATURAL;
+  END RECORD;
+
+  SIGNAL sim_clk     : STD_LOGIC;
+  SIGNAL sim_rst     : STD_LOGIC;
+
+  SIGNAL mem_state   : t_mem_state;
 
 BEGIN
 
@@ -93,117 +130,95 @@ BEGIN
   ctlr_miso.done     <= '0' , '1' AFTER 1 ns;
   ctlr_miso.cal_ok   <= '0' , '1' AFTER 1 ns;
   ctlr_miso.cal_fail <= '0';
-  
-  ctlr_miso.waitrequest_n <= waitrequest_n;
 
   p_mem_access : PROCESS(sim_clk)
     -- Process variables get initalized once and then they keep their state
-    VARIABLE v_mem_arr       : t_mem_arr := (OTHERS=>(OTHERS=>'0'));
-  
-    VARIABLE v_address       : NATURAL;
-    VARIABLE v_burst_size    : NATURAL;
-    VARIABLE v_burst_cnt     : NATURAL := 0;
-    VARIABLE v_wr_bursting   : BOOLEAN := FALSE;
-    VARIABLE v_rd_bursting   : BOOLEAN := FALSE;
-    VARIABLE v_waitrequest_n : STD_LOGIC := '1';
-    
+    VARIABLE v_mem_arr : t_mem_arr := (OTHERS=>(OTHERS=>'0'));
+    VARIABLE v         : t_mem_state := (0, 0, 0, FALSE, FALSE, FALSE, FALSE, 0, 0);
+
   BEGIN
 
     IF rising_edge(sim_clk) THEN
 
-      -- Get state
-      --v_address       := address;
-      --v_burst_size    := burst_size;
-      --v_burst_cnt     := burst_cnt;
-      --v_waitrequest_n := waitrequest_n;
-      --v_wr_bursting   := wr_bursting;
-      --v_rd_bursting   := rd_bursting;
-      
       -- Burst begin
       IF ctlr_mosi.burstbegin='1' THEN
         IF ctlr_mosi.wr='1' THEN
-          IF v_rd_bursting=FALSE THEN
-            v_wr_bursting := TRUE;
-            v_address     := TO_UINT(ctlr_mosi.address);
-            v_burst_size  := TO_UINT(ctlr_mosi.burstsize);
-            v_burst_cnt   := 0;
+          IF v.rd_bursting=FALSE THEN
+            v.wr_bursting := TRUE;
+            v.address     := TO_UINT(ctlr_mosi.address);
+            v.burst_size  := TO_UINT(ctlr_mosi.burstsize);
+            v.burst_cnt   := 0;
           ELSE
-            pending_wr         <= TRUE;
-            pending_address    <= TO_UINT(ctlr_mosi.address);
-            pending_burst_size <= TO_UINT(ctlr_mosi.burstsize);
+            v.pending_wr         := TRUE;
+            v.pending_address    := TO_UINT(ctlr_mosi.address);
+            v.pending_burst_size := TO_UINT(ctlr_mosi.burstsize);
           END IF;
         ELSIF ctlr_mosi.rd='1' THEN
-          IF v_rd_bursting=FALSE THEN
-            v_rd_bursting   := TRUE;
-            v_waitrequest_n := '0';
-            v_address       := TO_UINT(ctlr_mosi.address);
-            v_burst_size    := TO_UINT(ctlr_mosi.burstsize);
-            v_burst_cnt     := 0;
+          IF v.rd_bursting=FALSE THEN
+            v.rd_bursting := TRUE;
+            v.address     := TO_UINT(ctlr_mosi.address);
+            v.burst_size  := TO_UINT(ctlr_mosi.burstsize);
+            v.burst_cnt   := 0;
+            ctlr_miso.waitrequest_n <= '0';
           ELSE
-            pending_rd         <= TRUE;
-            pending_address    <= TO_UINT(ctlr_mosi.address);
-            pending_burst_size <= TO_UINT(ctlr_mosi.burstsize);
+            v.pending_rd         := TRUE;
+            v.pending_address    := TO_UINT(ctlr_mosi.address);
+            v.pending_burst_size := TO_UINT(ctlr_mosi.burstsize);
           END IF;
         END IF;
       END IF;
-  
+
       -- Pending write burst begin, after read burst
-      IF pending_wr=TRUE AND v_rd_bursting=FALSE THEN
-        pending_wr <= FALSE;
+      IF v.pending_wr=TRUE AND v.rd_bursting=FALSE THEN
+        v.pending_wr := FALSE;
         IF ctlr_mosi.wr='1' THEN  -- require that user has kept wr still active
-          v_wr_bursting   := TRUE;
-          v_address       := pending_address;
-          v_burst_size    := pending_burst_size;
-          v_burst_cnt     := 0;
+          v.wr_bursting   := TRUE;
+          v.address       := v.pending_address;
+          v.burst_size    := v.pending_burst_size;
+          v.burst_cnt     := 0;
         END IF;
       END IF;
-      
+
       -- Pending read burst begin, after read burst
-      IF pending_rd=TRUE AND v_rd_bursting=FALSE THEN
-        pending_rd <= FALSE;
+      IF v.pending_rd=TRUE AND v.rd_bursting=FALSE THEN
+        v.pending_rd := FALSE;
         IF ctlr_mosi.rd='1' THEN  -- require that user has kept rd still active
-          v_rd_bursting   := TRUE;
-          v_address       := pending_address;
-          v_burst_size    := pending_burst_size;
-          v_burst_cnt     := 0;
-          v_waitrequest_n := '0';
+          v.rd_bursting   := TRUE;
+          v.address       := v.pending_address;
+          v.burst_size    := v.pending_burst_size;
+          v.burst_cnt     := 0;
+          ctlr_miso.waitrequest_n <= '0';
         END IF;
       END IF;
-      
+
       -- Write access
-      IF v_wr_bursting=TRUE AND ctlr_mosi.wr='1' THEN
-        v_mem_arr(v_address) := ctlr_mosi.wrdata(c_dat_w-1 DOWNTO 0);
-        v_address   := v_address + 1;
-        v_burst_cnt := v_burst_cnt + 1;
+      IF v.wr_bursting=TRUE AND ctlr_mosi.wr='1' THEN
+        v_mem_arr(v.address) := ctlr_mosi.wrdata(c_dat_w-1 DOWNTO 0);
+        v.address   := v.address + 1;
+        v.burst_cnt := v.burst_cnt + 1;
       END IF;
-      
+
       -- Read access
-      ctlr_miso.rdval <= '0'; 
-      IF v_rd_bursting=TRUE THEN
-        ctlr_miso.rddata(c_dat_w-1 DOWNTO 0) <= v_mem_arr(v_address);  
+      ctlr_miso.rdval <= '0';
+      IF v.rd_bursting=TRUE THEN
+        ctlr_miso.rddata(c_dat_w-1 DOWNTO 0) <= v_mem_arr(v.address);
         ctlr_miso.rdval <= '1';
-        v_address   := v_address + 1;
-        v_burst_cnt := v_burst_cnt + 1;
+        v.address   := v.address + 1;
+        v.burst_cnt := v.burst_cnt + 1;
       END IF;
-  
+
       -- Burst size count
-      IF v_burst_cnt = v_burst_size THEN
-        v_wr_bursting := FALSE;
-        v_rd_bursting := FALSE;
-        v_waitrequest_n := '1';
+      IF v.burst_cnt = v.burst_size THEN
+        v.wr_bursting := FALSE;
+        v.rd_bursting := FALSE;
+        ctlr_miso.waitrequest_n <= '1';
       END IF;
-      
-      -- Show state
-      --address       <= v_address;
-      --burst_size    <= v_burst_size;
-      --burst_cnt     <= v_burst_cnt;
-      --wr_bursting   <= v_wr_bursting;
-      --rd_bursting   <= v_rd_bursting;
-
-      waitrequest_n <= v_waitrequest_n;
+
+      -- Show DDR memory state in wave window
+      mem_state <= v;
     END IF;
 
   END PROCESS;
- 
+
 END str;