diff --git a/libraries/io/ddr/src/vhdl/io_ddr.vhd b/libraries/io/ddr/src/vhdl/io_ddr.vhd
index 36f9ab5db6b01afa822bf00414e445e56c607e22..1df78c88cb69a91ba4d0aed2c3cbf28c23d1310c 100644
--- a/libraries/io/ddr/src/vhdl/io_ddr.vhd
+++ b/libraries/io/ddr/src/vhdl/io_ddr.vhd
@@ -37,7 +37,7 @@ ENTITY io_ddr IS
     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_mode              : STRING := "VALID";  -- "VALID", "SOP", "SYNC"
+    g_flush_mode              : STRING := "VAL";    -- "VAL", "SOP", "SYN"
     g_flush_use_channel       : BOOLEAN := FALSE;
     g_flush_start_channel     : NATURAL := 0;
     g_flush_nof_channels      : POSITIVE := 1
@@ -63,6 +63,7 @@ ENTITY io_ddr IS
     dvr_end_addr       : IN    t_tech_ddr_addr;
     dvr_done           : OUT   STD_LOGIC;
     dvr_flush_en       : IN    STD_LOGIC := '0';
+    dvr_wr_fifo_usedw  : OUT   STD_LOGIC_VECTOR(ceil_log2(g_wr_fifo_depth * (func_tech_ddr_ctlr_data_w(g_tech_ddr)/g_wr_data_w) )-1 DOWNTO 0);  -- for monitoring purposes
 
     -- Write FIFO clock domain
     wr_clk             : IN    STD_LOGIC;
@@ -105,12 +106,12 @@ ARCHITECTURE str OF io_ddr IS
 
   SIGNAL wr_flush          : STD_LOGIC := '0';
  
+  SIGNAL wr_fifo_src_in    : t_dp_siso;
+  SIGNAL wr_fifo_src_out   : t_dp_sosi := c_dp_sosi_rst;
+
   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;
 
-  SIGNAL flush_wr_siso     : t_dp_siso;
-  SIGNAL flush_wr_sosi     : t_dp_sosi := c_dp_sosi_rst;
-
   SIGNAL ctlr_rd_src_in    : t_dp_siso;
   SIGNAL ctlr_rd_src_out   : t_dp_sosi := c_dp_sosi_rst;
   
@@ -121,6 +122,7 @@ BEGIN
   ctlr_init_done <= i_ctlr_init_done;
   ctlr_rdy <= ctlr_miso.waitrequest_n;
   dvr_done <= i_dvr_done;
+  dvr_wr_fifo_usedw <= wr_fifo_usedw;
   
   u_wr_fifo : ENTITY dp_lib.dp_fifo_dc_mixed_widths
   GENERIC MAP (
@@ -144,8 +146,8 @@ BEGIN
     rd_usedw       => wr_fifo_usedw,
     rd_emp         => OPEN,
 
-    src_in         => flush_wr_siso,
-    src_out        => flush_wr_sosi
+    src_in         => wr_fifo_src_in,
+    src_out        => wr_fifo_src_out
   );
 
   u_dp_flush : ENTITY dp_lib.dp_flush
@@ -158,8 +160,8 @@ BEGIN
     rst      => ctlr_rst_in,
     clk      => ctlr_clk_in,
    
-    snk_in   => flush_wr_sosi,
-    snk_out  => flush_wr_siso,
+    snk_in   => wr_fifo_src_out,
+    snk_out  => wr_fifo_src_in,
 
     src_out  => ctlr_wr_snk_in,
     src_in   => ctlr_wr_snk_out,
@@ -175,15 +177,15 @@ BEGIN
     g_nof_channels  => g_flush_nof_channels
   )
   PORT MAP (
-    rst           => wr_rst,
-    clk           => wr_clk,
+    rst           => ctlr_rst_in,
+    clk           => ctlr_clk_in,
 
     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_sosi       => wr_fifo_src_out,
 
     wr_flush      => wr_flush
   );
diff --git a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
index 7f3534ad3db561b9ad89eb7c70d2569709f055ba..90018df621a1f4eb2f3fbc609a32d5173c98ad38 100644
--- a/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
+++ b/libraries/io/ddr/tb/vhdl/tb_io_ddr.vhd
@@ -49,6 +49,8 @@ END ENTITY tb_io_ddr;
 
 ARCHITECTURE str of tb_io_ddr IS
 
+  CONSTANT c_nof_repeat          : NATURAL := 2;
+
   CONSTANT c_ctlr_ref_clk_period : TIME := 5 ns;  -- 200 MHz
   CONSTANT c_dp_clk_period       : TIME := 5000 ps;  -- 200 MHz
 
@@ -71,6 +73,14 @@ ARCHITECTURE str of tb_io_ddr IS
   --CONSTANT c_dp_data_w        : NATURAL := 32;
   CONSTANT c_dp_data_w        : NATURAL := 256;
   CONSTANT c_dp_factor        : NATURAL := c_ctlr_data_w/c_dp_data_w;
+  
+  CONSTANT c_wr_fifo_depth    : NATURAL := 128;
+  CONSTANT c_rd_fifo_depth    : NATURAL := 256;
+  
+  -- Frame size for sop/eop
+  CONSTANT c_wr_flush_mode    : STRING := "SOP";  -- "VAL", "SOP", "SYN"
+  CONSTANT c_wr_use_ctrl      : BOOLEAN := sel_a_b(c_wr_flush_mode="VAL", FALSE, TRUE);
+  CONSTANT c_wr_frame_size    : NATURAL := 32;
  
   SIGNAL tb_end               : STD_LOGIC := '0';
   SIGNAL ctlr_ref_clk         : STD_LOGIC := '0';
@@ -89,13 +99,17 @@ 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 dvr_flush_en         : STD_LOGIC;
+  SIGNAL dvr_wr_fifo_usedw    : STD_LOGIC_VECTOR(ceil_log2(c_wr_fifo_depth * c_dp_factor)-1 DOWNTO 0);    
   
-  SIGNAL wr_siso              : t_dp_siso;
-  SIGNAL wr_sosi              : t_dp_sosi;
+  SIGNAL diag_wr_src_in       : t_dp_siso;
+  SIGNAL diag_wr_src_out      : t_dp_sosi;
+  
+  SIGNAL wr_src_out           : t_dp_sosi;
+  SIGNAL wr_val_cnt           : NATURAL := 0;
 
-  SIGNAL rd_siso              : t_dp_siso;
-  SIGNAL rd_sosi              : t_dp_sosi;
+  SIGNAL diag_rd_snk_out      : t_dp_siso;
+  SIGNAL diag_rd_snk_in       : t_dp_sosi;
 
   SIGNAL src_diag_en          : STD_LOGIC;
   SIGNAL src_val_cnt          : STD_LOGIC_VECTOR(31 DOWNTO 0);
@@ -123,6 +137,7 @@ BEGIN
     VARIABLE v_addr_hi : t_tech_ddr_addr;
   BEGIN
     tb_end        <= '0';
+    dvr_flush_en  <= '0';
     dvr_en        <= '0';
     src_diag_en   <= '0';
     dvr_wr_not_rd <= '0';
@@ -132,40 +147,56 @@ BEGIN
     proc_common_wait_until_high(ctlr_clk, ctlr_init_done);
     proc_common_wait_some_cycles(ctlr_clk, 2);  -- Give the driver FSM a cycle to go into idle mode
     
-    -- START diagnostics source for write and sink for verify read
-    src_diag_en   <= '1';
-    snk_diag_en   <= '1';
+    -- Start diagnostics source for write and sink for verify read
+    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
+    -- After reset even 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);
+    FOR R IN 0 TO c_nof_repeat-1 LOOP
+      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);
+        
+        dvr_start_addr <= v_addr_lo;
+        dvr_end_addr   <= v_addr_hi;
+        
+        -- START ACCESS
+        dvr_wr_not_rd <= c_wr_not_rd_arr(I);
+        dvr_en        <= '1';
+        proc_common_wait_some_cycles(ctlr_clk, 1);
+        dvr_en        <= '0'; 
+        
+        -- ACCESS DONE  
+        proc_common_wait_until_lo_hi(ctlr_clk, dvr_done);
+        
+        IF c_wr_not_rd_arr(I)='0' THEN
+          expected_cnt <= expected_cnt + c_nof_address_arr(I)*c_dp_factor;
+        
+          ASSERT snk_diag_res_val = '1' REPORT "[ERROR] DIAG_RES INVALID!"  SEVERITY FAILURE;
+          ASSERT snk_diag_res = '0'     REPORT "[ERROR] NON-ZERO DIAG_RES!" SEVERITY FAILURE;
+        END IF;
+      END LOOP;
       
-      dvr_start_addr <= v_addr_lo;
-      dvr_end_addr   <= v_addr_hi;
+      -- Stop diagnostics source and sink
+      src_diag_en <= '0';
+      snk_diag_en <= '0';
       
-      -- START ACCESS
-      dvr_wr_not_rd <= c_wr_not_rd_arr(I);
-      dvr_en        <= '1';
+      -- Flush the wr fifo
+      dvr_flush_en <= '1';
       proc_common_wait_some_cycles(ctlr_clk, 1);
-      dvr_en        <= '0'; 
-      
-      -- ACCESS DONE  
-      proc_common_wait_until_lo_hi(ctlr_clk, dvr_done);
+      dvr_flush_en <= '0';
       
-      IF c_wr_not_rd_arr(I)='0' THEN
-        expected_cnt <= expected_cnt + c_nof_address_arr(I)*c_dp_factor;
+      proc_common_wait_some_cycles(ctlr_clk, 500);
+      ASSERT UNSIGNED(dvr_wr_fifo_usedw) = 0      REPORT "[ERROR] Write FIFO is flushed but not empty!" SEVERITY FAILURE;
+      ASSERT UNSIGNED(snk_val_cnt) = expected_cnt REPORT "[ERROR] Unexpected number of read data!" SEVERITY FAILURE;
       
-        ASSERT snk_diag_res_val = '1' REPORT "[ERROR] DIAG_RES INVALID!"  SEVERITY FAILURE;
-        ASSERT snk_diag_res = '0'     REPORT "[ERROR] NON-ZERO DIAG_RES!" SEVERITY FAILURE;
-      END IF;
+      -- Restart diagnostics source and sink
+      src_diag_en <= '1';
+      snk_diag_en <= '1';
     END LOOP;
     
-    proc_common_wait_some_cycles(ctlr_clk, 500);
-    ASSERT UNSIGNED(snk_val_cnt) = expected_cnt REPORT "[ERROR] Unexpected number of read data!" SEVERITY FAILURE;
-    
     REPORT "[OK] Test passed." SEVERITY NOTE;
     tb_end <= '1';
 
@@ -181,32 +212,55 @@ BEGIN
     rst                 => dp_rst,
     clk                 => dp_clk,
 
-    snk_out_arr(0)      => rd_siso,
-    snk_in_arr(0)       => rd_sosi,
+    snk_out_arr(0)      => diag_rd_snk_out,
+    snk_in_arr(0)       => diag_rd_snk_in,
     snk_diag_en(0)      => snk_diag_en,
     snk_diag_md(0)      => '1',
     snk_diag_res(0)     => snk_diag_res,
     snk_diag_res_val(0) => snk_diag_res_val,
     snk_val_cnt(0)      => snk_val_cnt,
 
-    src_out_arr(0)      => wr_sosi,
-    src_in_arr(0)       => wr_siso,
+    src_out_arr(0)      => diag_wr_src_out,
+    src_in_arr(0)       => diag_wr_src_in,
     src_diag_en(0)      => src_diag_en,
     src_diag_md(0)      => '1',
     src_val_cnt(0)      => src_val_cnt
   );
 
+  wr_val_cnt <= wr_val_cnt + 1 WHEN rising_edge(dp_clk) AND diag_wr_src_out.valid='1';
+  
+  p_sop_eop : PROCESS (diag_wr_src_out, wr_val_cnt)
+  BEGIN
+    wr_src_out <= diag_wr_src_out;
+    wr_src_out.sop <= '0';
+    wr_src_out.eop <= '0';
+    IF wr_val_cnt MOD c_wr_frame_size = 0 THEN
+      wr_src_out.sop <= diag_wr_src_out.valid;
+    ELSIF wr_val_cnt MOD c_wr_frame_size = c_wr_frame_size-1 THEN
+      wr_src_out.eop <= diag_wr_src_out.valid;
+    END IF;
+  END PROCESS;
+    
   u_io_ddr: ENTITY work.io_ddr
   GENERIC MAP(
-    g_technology       => c_tech_select_default,
-    g_tech_ddr         => c_tech_ddr,
-    g_wr_data_w        => c_dp_data_w,
-    g_rd_data_w        => c_dp_data_w
+    g_technology          => c_tech_select_default,
+    g_tech_ddr            => c_tech_ddr,
+    g_wr_data_w           => c_dp_data_w,
+    g_wr_use_ctrl         => c_wr_use_ctrl,    -- TRUE to allow filling the write FIFO by disabling flush after an EOP
+    g_wr_fifo_depth       => c_wr_fifo_depth,  -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO.
+    g_rd_fifo_depth       => c_rd_fifo_depth,  -- >=16 AND >g_tech_ddr.maxburstsize, defined at DDR side of the FIFO. 
+    g_rd_data_w           => c_dp_data_w,
+    g_flush_mode          => c_wr_flush_mode,  -- "VAL", "SOP", "SYN"
+    g_flush_use_channel   => FALSE,
+    g_flush_start_channel => 0,
+    g_flush_nof_channels  => 1
   )                      
   PORT MAP (
+    -- DDR reference clock
     ctlr_ref_clk       => ctlr_ref_clk,
     ctlr_ref_rst       => ctlr_ref_rst,
                                      
+    -- DDR controller clock domain
     ctlr_clk_out       => ctlr_clk,
     ctlr_rst_out       => ctlr_rst,
     
@@ -222,15 +276,18 @@ BEGIN
     dvr_start_addr     => dvr_start_addr,
     dvr_end_addr       => dvr_end_addr,
     dvr_flush_en       => dvr_flush_en,
+    dvr_wr_fifo_usedw  => dvr_wr_fifo_usedw,
     
+    -- Write FIFO clock domain
     wr_clk             => dp_clk,
     wr_rst             => dp_rst,
 
-    wr_sosi            => wr_sosi, 
-    wr_siso            => wr_siso,
+    wr_sosi            => wr_src_out, 
+    wr_siso            => diag_wr_src_in,
   
-    rd_sosi            => rd_sosi,
-    rd_siso            => rd_siso,
+    -- Read FIFO clock domain
+    rd_sosi            => diag_rd_snk_in,
+    rd_siso            => diag_rd_snk_out,
 
     rd_clk             => dp_clk,
     rd_rst             => dp_rst,