diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
index 795c772f562a4c8e01bd747ff4e3c6bc49016fed..67c5bd1959c35b1a11084c59370e6add731a101a 100644
--- a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
+++ b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd
@@ -18,11 +18,41 @@
 
 -- --------------------------------------------------------------------------
 -- Author: 
--- . Pieter Donker, R van der Walle
+-- . Pieter Donker, R van der Walle, E. Kooistra
 -- Purpose:
 -- . Read a block of data from memory mapped (MM) location and stream it as a block of data.
 -- Description:
 -- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank
+--
+-- . g_*_size, g_word_w:
+--   The g_*_size values are in number of g_word_w memory words, so e.g.
+--   32bit words. The 32bit words are read in data blocks of g_data_size
+--   words. The data block contains g_data_size / g_user_size number of
+--   user words, this occurs e.g. when the data block contains:
+--   - a complex value, so with real part and imag part
+--   - dual polarization value, so with X polarization and Y polarization
+--   The user words contain g_user_size number of g_word_w = 32bit words.
+--   The output out_sosi.data width is also g_word_w bits.
+--
+-- . g_step_size:
+--   The g_step_size = K * g_data_size, where K >= 1 to allow read out of
+--   data blocks that are interleaved by a factor K.
+--
+-- . g_nof_data and start_pulse, start_address, mm_mosi, mm_miso, mm_done:
+--   The g_nof_data is the number of data blocks that are read out via
+--   mm_mosi/mm_miso per start_pulse, to form a new aggregate output block
+--   with out_sosi.sop and out_sosi.eop. When the read out is done, then
+--   mm_done pulses and a new start_pulse can be issued. By incrementing
+--   the start_address for every start_pulse it is possible to read out K
+--   interleaved sets of data blocks from the memory.
+--
+-- . g_reverse_word_order per g_user_size:
+--   The g_reverse_word_order has no effect when FALSE, but reverses the
+--   read out order of the 32bit words per user word when TRUE. The
+--   g_reverse_word_order has to apply per user word and not per data block,
+--   to preserve the order of the user parts (e.g. real and imag, X and Y
+--   polarization) in a data block.
+--
 -- --------------------------------------------------------------------------
 
 LIBRARY IEEE,common_lib;
@@ -34,10 +64,11 @@ USE work.dp_stream_pkg.ALL;
 
 ENTITY dp_block_from_mm IS
   GENERIC (
+    g_user_size          : NATURAL;
     g_data_size          : NATURAL;
     g_step_size          : NATURAL;
     g_nof_data           : NATURAL;
-    g_data_w             : NATURAL := c_word_w;
+    g_word_w             : NATURAL := c_word_w;
     g_mm_rd_latency      : NATURAL := 1;  -- default 1 from rd_en to rd_val, use 2 to ease timing closure
     g_reverse_word_order : BOOLEAN := FALSE
   ); 
@@ -58,7 +89,7 @@ END dp_block_from_mm;
 ARCHITECTURE rtl OF dp_block_from_mm IS 
 
   CONSTANT c_mem_size : NATURAL := g_step_size * g_nof_data;
-  CONSTANT c_word_index_rst : NATURAL := sel_a_b(g_reverse_word_order, g_data_size - 1, 0);
+  CONSTANT c_word_index_rst : NATURAL := sel_a_b(g_reverse_word_order, g_user_size - 1, 0);
 
   TYPE t_reg IS RECORD
     busy       : STD_LOGIC;
@@ -95,7 +126,7 @@ BEGIN
   u_sosi : PROCESS(r, mm_miso, out_sop, out_eop)
   BEGIN
     out_sosi       <= c_dp_sosi_rst;  -- To avoid Modelsim warnings on conversion to integer from unused fields.
-    out_sosi.data  <= RESIZE_DP_DATA(mm_miso.rddata(g_data_w-1 DOWNTO 0));
+    out_sosi.data  <= RESIZE_DP_DATA(mm_miso.rddata(g_word_w-1 DOWNTO 0));
     out_sosi.valid <= mm_miso.rdval;  -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1)
     out_sosi.sop   <= out_sop;        -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.sop can be used for output sop
     out_sosi.eop   <= out_eop;        -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.eop can be used for output eop
@@ -147,6 +178,15 @@ BEGIN
             v.sop := '1';
           END IF;
 
+        -- check end of block
+          IF mm_address = last_mm_address - (g_data_size - 1) THEN -- with reversed word order the last word to read is actually the first word of the last step index
+            v.eop := '1';
+            -- prepare for next block
+            v.busy := '0';
+            v.step_index := 0;
+            v.word_index := g_data_size - 1;
+          END IF;
+
         ELSE
 
           IF r.word_index < g_data_size - 1 THEN
@@ -161,24 +201,17 @@ BEGIN
             v.sop := '1';
           END IF;
 
-        END IF;
-        
         -- check end of block
-        IF g_reverse_word_order THEN
-          IF mm_address = last_mm_address - (g_data_size - 1) THEN -- with reversed word order the last word to read is actually the first word of the last step index
+          IF mm_address >= last_mm_address THEN
             v.eop := '1';
             -- prepare for next block
             v.busy := '0';
             v.step_index := 0;
-            v.word_index := g_data_size - 1;
+            v.word_index := 0;
           END IF;
-        ELSIF mm_address >= last_mm_address THEN -- g_reverse_word_order = False
-          v.eop := '1';
-          -- prepare for next block
-          v.busy := '0';
-          v.step_index := 0;
-          v.word_index := 0;
+
         END IF;
+        
       END IF;
     END IF;
     nxt_r <= v;