diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd
index ade1d6b6432ddf2e5be3c3762fa8ebc1c5028af5..36f9ab5db6b01afa822bf00414e445e56c607e22 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd
@@ -33,15 +33,14 @@ ENTITY io_ddr IS
     g_technology              : NATURAL := c_tech_select_default;
     g_tech_ddr                : t_c_tech_ddr;
     g_wr_data_w               : NATURAL := 32;  
-    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 >g_tech_ddr.maxburstsize                              , defined at read  side of write FIFO.
-    g_rd_fifo_depth           : NATURAL := 256;                -- >=16 AND >g_tech_ddr.maxburstsize > c_ddr_ctlr_nof_latent_reads, defined at write side of read  FIFO. 
+    g_wr_use_ctrl             : BOOLEAN := FALSE;   -- TRUE to allow filling the write FIFO by disabling flush after an EOP
+    g_wr_fifo_depth           : NATURAL := 128;     -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO.
+    g_rd_fifo_depth           : NATURAL := 256;     -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO. 
     g_rd_data_w               : NATURAL := 32;
-    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
+    g_flush_mode              : STRING := "VALID";  -- "VALID", "SOP", "SYNC"
+    g_flush_use_channel       : BOOLEAN := FALSE;
+    g_flush_start_channel     : NATURAL := 0;
+    g_flush_nof_channels      : POSITIVE := 1
   );                      
   PORT (
     -- DDR reference clock
@@ -63,6 +62,7 @@ ENTITY io_ddr IS
     dvr_start_addr     : IN    t_tech_ddr_addr;
     dvr_end_addr       : IN    t_tech_ddr_addr;
     dvr_done           : OUT   STD_LOGIC;
+    dvr_flush_en       : IN    STD_LOGIC := '0';
 
     -- Write FIFO clock domain
     wr_clk             : IN    STD_LOGIC;
@@ -90,22 +90,20 @@ END io_ddr;
 
 ARCHITECTURE str OF io_ddr IS  
  
-  CONSTANT c_ctlr_data_w      : NATURAL := func_tech_ddr_ctlr_data_w( g_tech_ddr);
+  CONSTANT c_ctlr_data_w       : NATURAL := func_tech_ddr_ctlr_data_w(g_tech_ddr);
   
-  CONSTANT c_wr_fifo_depth    : NATURAL := g_wr_fifo_depth * (c_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_ddr_ctlr_nof_latent_reads : NATURAL := 100;  -- Due to having a command cue, even after de-asserting read requests, the PHY keeps processing the 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_latency       : NATURAL := 1;
+  CONSTANT c_wr_fifo_depth     : NATURAL := g_wr_fifo_depth * (c_ctlr_data_w/g_wr_data_w);  -- get FIFO depth at write side
   
+  CONSTANT c_wr_fifo_af_margin : NATURAL := 4 + 1;                        -- use +1 to compensate for latency introduced by registering wr_siso.ready due to RL=0
+  CONSTANT c_rd_fifo_af_margin : NATURAL := 4 + g_tech_ddr.maxburstsize;  -- use ctlr_rd_src_in.ready to only start new rd access when there is sufficient space in the read FIFO
+                                                          
   SIGNAL i_ctlr_init_done  : STD_LOGIC;
   SIGNAL i_dvr_done        : STD_LOGIC;
 
   SIGNAL ctlr_mosi         : t_tech_ddr_mosi := c_tech_ddr_mosi_rst;
   SIGNAL ctlr_miso         : t_tech_ddr_miso := c_tech_ddr_miso_rst;
 
-  SIGNAL dvr_flush         : STD_LOGIC := '0';
+  SIGNAL wr_flush          : STD_LOGIC := '0';
  
   SIGNAL ctlr_wr_snk_out   : t_dp_siso := c_dp_siso_rdy;  -- default xon='1'
   SIGNAL ctlr_wr_snk_in    : t_dp_sosi := c_dp_sosi_rst;
@@ -130,7 +128,7 @@ BEGIN
     g_rd_data_w         => c_ctlr_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_wr_fifo_af_margin => c_wr_fifo_af_margin,
     g_rd_fifo_rl        => 0
   )
   PORT MAP (
@@ -150,11 +148,11 @@ BEGIN
     src_out        => flush_wr_sosi
   );
 
-  u_dp_flush : ENTITY dp_lib.dp_flush -- Always instantiate the flusher as it also contains a RL adapter
+  u_dp_flush : ENTITY dp_lib.dp_flush
   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
+    g_framed_xon    => g_wr_use_ctrl,  -- stop flushing when wr_flush is low and a sop has arrived 
+    g_framed_xoff   => FALSE           -- immediately start flushing when wr_flush goes high
   )
   PORT MAP (
     rst      => ctlr_rst_in,
@@ -166,30 +164,29 @@ BEGIN
     src_out  => ctlr_wr_snk_in,
     src_in   => ctlr_wr_snk_out,
 
-    flush_en => dvr_flush
+    flush_en => wr_flush
   );
 
-  gen_io_ddr_driver_flush_ctrl : IF g_flush_wr_fifo = TRUE GENERATE  
-    u_io_ddr_driver_flush_ctrl : ENTITY work.io_ddr_driver_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_io_ddr_driver_flush_ctrl : ENTITY work.io_ddr_driver_flush_ctrl
+  GENERIC MAP (
+    g_mode          => g_flush_mode,
+    g_use_channel   => g_flush_use_channel,
+    g_start_channel => g_flush_start_channel,
+    g_nof_channels  => g_flush_nof_channels
+  )
+  PORT MAP (
+    rst           => wr_rst,
+    clk           => wr_clk,
+
+    dvr_flush_en  => dvr_flush_en,
+    dvr_en        => dvr_en,
+    dvr_wr_not_rd => dvr_wr_not_rd,
+    dvr_done      => i_dvr_done,
+
+    wr_sosi       => wr_sosi,
+
+    wr_flush      => wr_flush
+  );
 
   u_rd_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
   GENERIC MAP (
@@ -197,7 +194,7 @@ BEGIN
     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_ddr_ctlr_nof_latent_reads, -- >=4 (required by dp_fifo)
+    g_wr_fifo_af_margin => c_rd_fifo_af_margin, -- >=4 (required by dp_fifo)
     g_rd_fifo_rl        => 1
   )
   PORT MAP (
diff --git a/libraries/io/ddr/src/vhdl/io_ddr_driver_flush_ctrl.vhd b/libraries/io/ddr/src/vhdl/io_ddr_driver_flush_ctrl.vhd
index f2f9e6aac4ee8b1484ca90f68b3c4ac81cafe39d..744a446edfee9a64633da692507284086f48ab4f 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr_driver_flush_ctrl.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr_driver_flush_ctrl.vhd
@@ -18,7 +18,20 @@
 -- You should have received a copy of the GNU General Public License
 -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
 --
---------------------------------------------------------------------------------
+-------------------------------------------------------------------------------- 
+
+-- Purpose: Flush the write input FIFO in io_ddr when not doing a write access.
+-- Description:
+--   The write input FIFO is flushed by when the io_ddr is not doing a write
+--   access, so when idle or also when doing a read access.
+--   When the io_ddr is starting a new write access, then the write input FIFO
+--   gets filled. The filling starts dependent on:
+--
+--   . g_mode = "VALID" : immediately start filling on next valid data
+--   . g_mode = "SOP"   : start filling on next sop
+--   . g_mode = "SYNC"  : start filling on next sync
+--
+--   . g_use_channel = TRUE : start filling when channel matches g_start_channel
 
 LIBRARY IEEE, common_lib, dp_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
@@ -28,23 +41,23 @@ USE dp_lib.dp_stream_pkg.ALL;
 
 ENTITY io_ddr_driver_flush_ctrl IS 
   GENERIC (
-    g_sop               : BOOLEAN := FALSE; -- Stop flushing on SOP, otherwise stop flushing on valid data
-    g_sop_channel       : BOOLEAN := FALSE; -- When g_sop=TRUE, also check if the channel matches g_sop_start_channel
-    g_sop_start_channel : NATURAL := 0;
-    g_nof_channels      : NATURAL := 0
+    g_mode          : STRING := "VALID";  -- "VALID", "SOP", "SYNC"
+    g_use_channel   : BOOLEAN := FALSE;
+    g_start_channel : NATURAL := 0;
+    g_nof_channels  : POSITIVE := 1
    );  
   PORT ( 
     clk                : IN  STD_LOGIC;
     rst                : IN  STD_LOGIC;
 
+    dvr_flush_en       : IN  STD_LOGIC := '1';
     dvr_en             : IN  STD_LOGIC := '1';
     dvr_wr_not_rd      : IN  STD_LOGIC;       
     dvr_done           : IN  STD_LOGIC; 
 
     wr_sosi            : IN  t_dp_sosi;
 
-    dvr_flush          : OUT STD_LOGIC
-
+    wr_flush           : OUT STD_LOGIC
    );
 END io_ddr_driver_flush_ctrl;
 
@@ -58,27 +71,25 @@ ARCHITECTURE str OF io_ddr_driver_flush_ctrl IS
   SIGNAL state     : t_state;
   SIGNAL nxt_state : t_state;
 
+  SIGNAL channel   : NATURAL RANGE 0 TO g_nof_channels-1;
+  
   SIGNAL flush_dis : STD_LOGIC;
 
 BEGIN
 
-  -- Flush ddr3 module's FIFO (keep sinking the stream but simply discard the 
-  -- data) after reset to prevent ddr3 write fifo from filling up - which would
-  -- cause problems downstream (dp_mux uses two fifos that cannot be
-  -- allowed to fill up too much).
-  -- Also flush the ddr3 module's FIFO when it is reading.
-
-  gen_sop : IF g_sop = TRUE GENERATE -- Disable flushing on arrival of SOP
-    gen_sop_only: IF g_sop_channel = FALSE GENERATE
-      flush_dis <= '1' WHEN wr_sosi.sop='1' ELSE '0';
-    END GENERATE;
-    gen_channel : IF g_sop_channel = TRUE GENERATE -- Only disable flushing on arrival of specific channel SOP
-      flush_dis <= '1' WHEN wr_sosi.sop='1' AND UNSIGNED(wr_sosi.channel(c_channel_w-1 DOWNTO 0))=g_sop_start_channel ELSE '0';
-    END GENERATE;
+  -- Flush disable control
+  no_channel: IF g_use_channel=FALSE GENERATE
+    gen_valid : IF g_mode="VALID" GENERATE flush_dis <= wr_sosi.valid; END GENERATE;
+    gen_sop   : IF g_mode="SOP"   GENERATE flush_dis <= wr_sosi.sop  ; END GENERATE;
+    gen_sync  : IF g_mode="SYNC"  GENERATE flush_dis <= wr_sosi.sync ; END GENERATE;
   END GENERATE;
-
-  gen_val : IF g_sop = FALSE GENERATE -- Disable flushing on arrival of 1st valid data
-    flush_dis <= wr_sosi.valid;
+    
+  use_channel: IF g_use_channel=TRUE GENERATE
+    channel <= TO_UINT(wr_sosi.channel(c_channel_w-1 DOWNTO 0));
+    
+    gen_valid : IF g_mode="VALID" GENERATE flush_dis <= '1' WHEN wr_sosi.valid='1' AND channel=g_start_channel ELSE '0'; END GENERATE;
+    gen_sop   : IF g_mode="SOP"   GENERATE flush_dis <= '1' WHEN wr_sosi.sop  ='1' AND channel=g_start_channel ELSE '0'; END GENERATE;
+    gen_sync  : IF g_mode="SYNC"  GENERATE flush_dis <= '1' WHEN wr_sosi.sync ='1' AND channel=g_start_channel ELSE '0'; END GENERATE;
   END GENERATE;
 
   p_reg : PROCESS(rst, clk)
@@ -90,23 +101,23 @@ BEGIN
     END IF;
   END PROCESS;
   
-  p_state : PROCESS(state, dvr_done, dvr_en, dvr_wr_not_rd, flush_dis)
+  p_state : PROCESS(state, dvr_flush_en, dvr_done, dvr_en, dvr_wr_not_rd, flush_dis)
   BEGIN
     nxt_state <= state;
-    dvr_flush <= '0';
+    wr_flush <= '0';
     CASE state IS
       WHEN s_idle => 
-        IF dvr_done='1' THEN
-          dvr_flush <= '1';
+        IF dvr_flush_en='1' AND dvr_done='1' THEN
+          wr_flush <= '1';
           nxt_state <= s_flush;
         END IF;
       WHEN s_flush =>
-        dvr_flush <= '1';
+        wr_flush <= '1';
         IF dvr_en='1' AND dvr_wr_not_rd='1' THEN
           nxt_state <= s_stop;
         END IF;
       WHEN OTHERS => -- s_stop
-        dvr_flush <= '1';
+        wr_flush <= '1';
         IF flush_dis = '1' THEN
           nxt_state <= s_idle;
         END IF;
diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
index 415db0eb043d291231670c9a737ab42ac9839141..7f3534ad3db561b9ad89eb7c70d2569709f055ba 100644
--- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
@@ -89,7 +89,8 @@ ARCHITECTURE str of tb_io_ddr IS
   SIGNAL dvr_en               : STD_LOGIC;
   SIGNAL dvr_wr_not_rd        : STD_LOGIC;
   SIGNAL dvr_done             : STD_LOGIC;
-
+  SIGNAL dvr_flush_en         : STD_LOGIC := '0';
+  
   SIGNAL wr_siso              : t_dp_siso;
   SIGNAL wr_sosi              : t_dp_sosi;
 
@@ -135,6 +136,9 @@ BEGIN
     src_diag_en   <= '1';
     snk_diag_en   <= '1';
     
+    -- When dvr_flush_en='0' then the write FIFO is flushed until the first write access is started
+    proc_common_wait_some_cycles(ctlr_clk, 100);
+    
     FOR I IN c_address_lo_arr'RANGE LOOP
       v_addr_lo := func_tech_ddr_dq_address(TO_DDR_CTLR_ADDRESS(4*c_address_lo_arr(I))                         , c_tech_ddr);
       v_addr_hi := func_tech_ddr_dq_address(TO_DDR_CTLR_ADDRESS(4*c_address_lo_arr(I)+4*c_nof_address_arr(I)-1), c_tech_ddr);
@@ -217,7 +221,8 @@ BEGIN
     dvr_done           => dvr_done,
     dvr_start_addr     => dvr_start_addr,
     dvr_end_addr       => dvr_end_addr,
- 
+    dvr_flush_en       => dvr_flush_en,
+    
     wr_clk             => dp_clk,
     wr_rst             => dp_rst,