diff --git a/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4.vhd b/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4.vhd
index 385070755e568427ed87dca798f003f535908e31..ff7b5771c14b9718b1812a151b02569c1f89824a 100644
--- a/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4.vhd
+++ b/libraries/io/aduh/src/vhdl/lvdsh_dd_phs4.vhd
@@ -24,9 +24,11 @@ USE IEEE.STD_LOGIC_1164.ALL;
 USE IEEE.NUMERIC_STD.ALL;
 USE common_lib.common_pkg.ALL;
 
+-- Author: Eric Kooistra
 -- Purpose: Detect the wide band factor phase 0, 1, 2 or 3 of the 200 MHz
 --          dp_clk using the rising and falling edge of the double data rate
---          400 MHz in_clk clock.
+--          400 MHz in_clk clock. The aim is to detect same sample phase
+--          after each restart of the ADC, without the need for calibration.
 -- Description:
 --   The edges of the in_clk occur at the 800 MHz sample rate of the ADC. The
 --   in_clk is a double data rate (DDR) 400 MHz clock as indicated by
@@ -46,12 +48,13 @@ USE common_lib.common_pkg.ALL;
 --   g_wb_factor-1 samples.
 --   The sample phase alignment within a g_wb_factor=4 sample word is done by
 --   lvdsh_dd_phs4_align. After that the word phase is also aligned by
---   adjusting the latency between wb_sync and dp_sync which. 
+--   adjusting the roundtrip latency between wb_sync and dp_sync which are both
+--   derived from the selected dp_phs_clk. 
 --   Both the sample phase alignment and the word phase alignment use the
 --   dp_phs_clk as reference. For the sample phase alignment within a word the
 --   dp_phs_clk could run at the same 200 MHz rate as the dp_clk. However to
---   support a word latency of about 16 dp_clk cycles the dp_phs_clk are
---   divided by 32 at the PLL and only their rising edge is used to do the
+--   support a roundtrip word latency of about 16 dp_clk cycles the dp_phs_clk
+--   are divided by 32 at the PLL and only their rising edge is used to do the
 --   alignments.
 --   The g_nof_dp_phs_clk>= 1 and maximum 6. When g_nof_dp_phs_clk=6 then 
 --   typically each dp_phs_clk is shifted by 11.25 or 22.5 degrees where 90
@@ -59,7 +62,7 @@ USE common_lib.common_pkg.ALL;
 --   period. By selecting one suitable out of a range of phase shifted
 --   dp_phs_clk it is possible to find a proper dp_phs_clk reference for all
 --   signal paths in the different nodes.
---   The whole sample phase realingment scheme relies on fixed clock
+--   The whole sample phase realignment scheme relies on fixed clock
 --   distribution delays on the boards and in the FPGA. Therefore a clock tree
 --   network is used for the dp_phs_clk as well, even though the dp_phs_clk
 --   does not clock any logic. The dp_phs_clk gets sampled by the dp_clk to
@@ -91,6 +94,22 @@ USE common_lib.common_pkg.ALL;
 --      an entire sample period and via MM control one phase is selected per
 --      BN- ADU pair. The MM control is then needed to select always the same
 --      phase in case not always the same phase is found automatically.
+-- . With multiple Apertif subracks it appears that the word alignment found
+--   for all ADC paths is not always the same for all ADC paths. This cannot
+--   be avoided with this lvdsh_dd_phs4, therefore any residual sample phase
+--   uncertainty needs to be accounted for by calibration. However for most 
+--   ADC dp_dat paths this lvdsh_dd_phs4 will ensure a proper word alignment
+--   that makes it feasible to perform coherent beamforming.
+-- . On Apertif subracks it appears that sometimes over hours an initial word
+--   alignment will get adjusted and this then causes a brief disturbance in
+--   the dp_dat values or it may even cause a sample shift that remains. Such
+--   a sample shift would harm the remainder of the observation. By setting
+--   in_maintain_phs='1' after word alignment it can be ensured that this word
+--   alignment maintained as long as the ADC in_clk remains active (so in
+--   practise for as long as the observation will last or the Apertif frontend
+--   and subracks remain on). The maintain lock feature is enabled when 
+--   g_maintain_phs = TRUE.
+--   
     
 ENTITY lvdsh_dd_phs4 IS
   GENERIC (
@@ -98,6 +117,7 @@ ENTITY lvdsh_dd_phs4 IS
     g_wb_factor          : NATURAL := 4;      -- fixed wideband factor 4 = c_rx_factor*c_dd_factor
     g_dp_phs_clk_period  : NATURAL := 32;     -- number of dp_clk periods per dp_phs_clk period, must match g_clk*_divide_by in unb_clk200_pll
     g_nof_dp_phs_clk     : NATURAL := 2;      -- nof dp_phs_clk that can be used to detect lock
+    g_maintain_phs       : BOOLEAN := TRUE;   -- when TRUE maintain the stable lock once it is found, else keep on checking whether the stable lock is still stable
     g_wb_use_rising_edge : BOOLEAN := FALSE;  -- when TRUE using rising edge of dp_clk domain to capture wb_sync as reference for dp_sync from in_clk domain, else use falling edge
     g_in_dat_w           : NATURAL := 8       -- nof PHY data bits
   );
@@ -148,34 +168,40 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
   CONSTANT c_word_req_lat           : NATURAL := 4;
   CONSTANT c_dp_phs_align_restart_w : NATURAL := 5;
   
-  CONSTANT c_in_dd_phs_locked_w     : NATURAL := sel_a_b(g_sim, 12, 25);    -- used to ensure that dd_phs_locked is only declared if dd_phs is detected ok for at least 2**(g_dd_phs_locked_w-1) in_clk cycles
-  CONSTANT c_dp_dd_phs_timeout_w    : NATURAL := c_in_dd_phs_locked_w + 0;  -- dd_phs locked timeout in dp_clk domain, use c_dd_factor longer or more than c_in_dd_phs_locked_w
-  CONSTANT c_wb_sync_offset         : INTEGER := g_dp_phs_clk_period/2;
-  CONSTANT c_wb_sync_delta          : INTEGER := 0;                         -- use c_wb_sync_offset for default FIFO fill level and c_wb_sync_delta < 0 or > 0 to decrease or increase it somewhat
-  CONSTANT c_wb_sync_latency        : NATURAL := c_wb_sync_offset + c_wb_sync_delta;  -- nof dp_clk cycles from getting wb_sync back via dp_sync
-  CONSTANT c_wb_sync_period         : NATURAL := g_dp_phs_clk_period;                 -- nof dp_clk cycles for wb_sync period, must be > c_wb_sync_latency
+  CONSTANT c_in_dd_phs_locked_w     : NATURAL := sel_a_b(g_sim, 12, 30);    -- used to ensure that dd_phs_locked is only declared if dd_phs is detected ok for at least 2**(g_dd_phs_locked_w-1) in_clk cycles
+  CONSTANT c_dp_dd_phs_timeout_w    : NATURAL := c_in_dd_phs_locked_w;      -- dd_phs locked timeout in dp_clk domain, so c_dd_factor=2 longer than c_in_dd_phs_locked_w, because c_in_dd_phs_locked_w runs
+                                                                            -- in the in_clk domain. This is enough to find stable lock if it is possible to have stable lock at the selected dp_phs_clk.
+  
+  CONSTANT c_wb_sync_period         : NATURAL := g_dp_phs_clk_period;       -- nof dp_clk cycles for wb_sync period, must be > c_wb_sync_roundtrip
   CONSTANT c_wb_cnt_w               : NATURAL := ceil_log2(c_wb_sync_period);
-  CONSTANT c_wb_fifo_latency        : NATURAL := c_wb_sync_latency-9;       -- estimated FIFO fill level based on simulation and measurement on hardware (6, 7 and 8 occur)
+  CONSTANT c_wb_fifo_fill_offset    : INTEGER := 2;         -- some offset to adjust the mean fifo fill level
+  CONSTANT c_wb_sync_in_latency     : NATURAL := 12;        -- estimated nof dp_clk cycles latency of wb_sync transfer in the in_clk domain based on simulation and measurement on hardware
+  CONSTANT c_wb_sync_roundtrip      : NATURAL := c_wb_fifo_fill_offset+g_dp_phs_clk_period/2;  -- achieve this nof dp_clk cycles from getting wb_sync back via dp_sync
+  CONSTANT c_wb_fifo_fill_level     : NATURAL := c_wb_fifo_fill_offset+c_wb_sync_roundtrip-c_wb_sync_in_latency;  -- expected FIFO fill level on read side  (mean level +- 1 can occur),
   CONSTANT c_wb_fifo_fill_margin    : NATURAL := 2;                         -- some symmetrical FIFO filled margin >= 0, use 0 in theory, use 1 to allow some timing uncertainty in rdusedw of dual clock FIFO
-  CONSTANT c_wb_fifo_fill_margin_p  : NATURAL := c_wb_fifo_fill_margin;                      -- some FIFO more filled margin >= 0, use 0 or 1 to allow 8 and 9
-  CONSTANT c_wb_fifo_fill_margin_n  : NATURAL := c_wb_fifo_fill_margin;                      -- some FIFO less filled margin >= 0, use 1 or 2 to allow 7 and 6
-  CONSTANT c_wb_fifo_fill_max       : NATURAL := c_wb_fifo_latency+c_wb_fifo_fill_margin_p;  -- maximum FIFO fill level at any time
-  CONSTANT c_wb_fifo_fill_min       : NATURAL := c_wb_fifo_latency-c_wb_fifo_fill_margin_n;  -- minimum FIFO fill level during lock
+  CONSTANT c_wb_fifo_fill_margin_p  : NATURAL := c_wb_fifo_fill_margin;     -- some FIFO more filled margin >= 0, use 0 or 1 to allow 8 and 9
+  CONSTANT c_wb_fifo_fill_margin_n  : NATURAL := c_wb_fifo_fill_margin;     -- some FIFO less filled margin >= 0, use 1 or 2 to allow 7 and 6
+  CONSTANT c_wb_fifo_fill_max       : NATURAL := c_wb_fifo_fill_level+c_wb_fifo_fill_margin_p;  -- maximum FIFO fill level at any time
+  CONSTANT c_wb_fifo_fill_min       : NATURAL := c_wb_fifo_fill_level-c_wb_fifo_fill_margin_n;  -- minimum FIFO fill level during lock
   
   -- view debug signals in Wave Window
   SIGNAL dbg_c_dp_phs_align_en      : BOOLEAN := c_dp_phs_align_en;
-  SIGNAL dbg_c_wb_sync_latency      : NATURAL := c_wb_sync_latency;
+  SIGNAL dbg_c_wb_sync_period       : NATURAL := c_wb_sync_period;
+  SIGNAL dbg_c_wb_fifo_fill_offset  : INTEGER := c_wb_fifo_fill_offset;
+  SIGNAL dbg_c_wb_sync_in_latency   : NATURAL := c_wb_sync_in_latency;
+  SIGNAL dbg_c_wb_sync_roundtrip    : NATURAL := c_wb_sync_roundtrip;
   SIGNAL dbg_c_wb_fifo_fill_max     : NATURAL := c_wb_fifo_fill_max;
-  SIGNAL dbg_c_wb_fifo_latency      : NATURAL := c_wb_fifo_latency;
+  SIGNAL dbg_c_wb_fifo_fill_level   : NATURAL := c_wb_fifo_fill_level;  -- must be > c_word_req_lat to ensure that fifo_rdusedw > 0
   SIGNAL dbg_c_wb_fifo_fill_min     : NATURAL := c_wb_fifo_fill_min;
   
   SIGNAL dbg_status_0_out_word_locked       : STD_LOGIC;
   SIGNAL dbg_status_1_out_word_stable       : STD_LOGIC;
   SIGNAL dbg_status_4_dp_phs_locked         : STD_LOGIC;
+  SIGNAL dbg_status_5_wb_roundtrip_stable   : STD_LOGIC;
   SIGNAL dbg_status_6_dp_in_clk_detected    : STD_LOGIC;
   SIGNAL dbg_status_7_dp_in_clk_stable      : STD_LOGIC;
   SIGNAL dbg_status_15_8_fifo_rdusedw       : STD_LOGIC_VECTOR(7 DOWNTO 0);
-  SIGNAL dbg_status_23_16_wb_cnt_latency    : STD_LOGIC_VECTOR(7 DOWNTO 0);
+  SIGNAL dbg_status_23_16_wb_cnt_roundtrip  : STD_LOGIC_VECTOR(7 DOWNTO 0);
   SIGNAL dbg_status_27_24_dp_phs_clk_select : STD_LOGIC_VECTOR(3 DOWNTO 0);
   SIGNAL dbg_status_31_28_dp_raw_phs        : STD_LOGIC_VECTOR(3 DOWNTO 0);
   
@@ -202,6 +228,7 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
   SIGNAL in_fifo_wr_dat      : STD_LOGIC_VECTOR(c_fifo_dat_w-1 DOWNTO 0);
   SIGNAL in_fifo_wr_req      : STD_LOGIC;
   SIGNAL in_phs_align_en     : STD_LOGIC;
+  SIGNAL in_maintain_phs     : STD_LOGIC := '0';
   
   SIGNAL r_in                : t_in_reg;
   SIGNAL nxt_r_in            : t_in_reg;
@@ -239,12 +266,13 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
     prev_dp_sync_cap     : STD_LOGIC;
     dp_sync              : STD_LOGIC;
     wb_cnt_clr           : STD_LOGIC;
-    wb_cnt_latency       : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
-    wb_cnt_latency_hold  : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
+    wb_cnt_roundtrip     : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
+    wb_cnt_roundtrip_hold: STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
     dp_word_req          : STD_LOGIC;
     dp_word_req_dly      : STD_LOGIC_VECTOR(c_word_req_lat-1 DOWNTO 0);
     dp_word_locked       : STD_LOGIC;
     dp_word_lock_failed  : STD_LOGIC;
+    dp_maintain_phs      : STD_LOGIC;
   END RECORD;
   
   SIGNAL r_dp                        : t_dp_reg;
@@ -274,14 +302,22 @@ ARCHITECTURE str OF lvdsh_dd_phs4 IS
   SIGNAL wb_phs_clk                  : STD_LOGIC;
   SIGNAL wb_sync_cap                 : STD_LOGIC;
   SIGNAL wb_cnt                      : STD_LOGIC_VECTOR(c_wb_cnt_w-1 DOWNTO 0);
+  SIGNAL wb_roundtrip_lock           : STD_LOGIC;
+  SIGNAL wb_roundtrip_stable         : STD_LOGIC;
   
 BEGIN
 
   ------------------------------------------------------------------------------
   -- Reset input section when lock is lost
   ------------------------------------------------------------------------------
-  
+
   --  Multiple triggers for dp_phs_align_restart
+  --
+  --  . The dp_phs_align_restart is an input to the dp_in_rst_req that drives in_rst for lvdsh_dd_phs4_align
+  --  . When out_word_stable='1' then dp_maintain_phs='1' if g_maintain_phs=TRUE. The dp_phs_timeout and dp_phs_lock_lost can then 
+  --    no longer occur, because the lvdsh_dd_phs4_align then continues on the current phs using common_toggle_align.
+  --    The dp_word_lock_failed can still occur, but only if the course check on wb_cnt_roundtrip latency and fifo_rdusedw FIFO fill 
+  --    level fails by more than a +-1 margin. 
   dp_phs_align_restart <= dp_phs_timeout OR dp_phs_lock_lost OR r_dp.dp_word_lock_failed;
   
   -- Extend dp_phs_align_restart to filter out any subsequent restart triggers
@@ -319,6 +355,9 @@ BEGIN
   -- . the in_clk has stopped, or
   -- . the dp_phs_clk_en_vec was changed via MM, or
   -- . an internal dp_phs_align_restart request occured
+  -- When out_word_stable='1' then dp_maintain_phs='1' if g_maintain_phs=TRUE. The dp_in_clk_stopped and dp_phs_clk_en_vec_evt
+  -- can the then still cause a reset. When dp_maintain_phs='1' the dp_phs_align_restart will effectively not occur anymore,
+  -- because both dp_clk and in_clk are active and in lock and any jitter is ignored.
   nxt_r_dp.dp_in_rst_req <= dp_in_clk_stopped OR dp_phs_clk_en_vec_evt OR dp_phs_align_restart_extend;
   
   u_common_async_in_rst : ENTITY common_lib.common_async
@@ -404,10 +443,11 @@ BEGIN
     
     u_lvdsh_dd_phs4_align : ENTITY work.lvdsh_dd_phs4_align
     GENERIC MAP (
-      g_wb_factor       => g_wb_factor,
-      g_nof_dp_phs_clk  => g_nof_dp_phs_clk,
-      g_dd_phs_locked_w => c_in_dd_phs_locked_w,
-      g_in_dat_w        => g_in_dat_w
+      g_wb_factor         => g_wb_factor,
+      g_nof_dp_phs_clk    => g_nof_dp_phs_clk,
+      g_dp_phs_clk_period => g_dp_phs_clk_period,
+      g_dd_phs_locked_w   => c_in_dd_phs_locked_w,
+      g_in_dat_w          => g_in_dat_w
     )
     PORT MAP (
       -- DP clock reference for word alignment
@@ -419,6 +459,7 @@ BEGIN
       in_clk             => in_clk,
       in_dat_hi          => in_dat_hi,
       in_dat_lo          => in_dat_lo,
+      in_maintain_phs    => in_maintain_phs,
       
       raw_phs            => raw_phs,
       out_phs_locked     => dd_phs_locked,
@@ -437,7 +478,7 @@ BEGIN
   -- Support raw data without realignment
   ------------------------------------------------------------------------------
   
-  u_common_async_1 : ENTITY common_lib.common_async
+  u_common_async_in_phs_align_en : ENTITY common_lib.common_async
   GENERIC MAP (
     g_delay_len   => c_delay_len
   )
@@ -580,10 +621,10 @@ BEGIN
   dp_phs_timeout <= dp_phs_timeout_cnt(dp_phs_timeout_cnt'HIGH);                        -- dp_phs_timeout pulse also restarts the timer
   
   ------------------------------------------------------------------------------
-  -- Determine DP word lock based on the wb_sync - dp_sync latency
+  -- Determine DP word lock based on the wb_sync - dp_sync roundtrip latency via in_clk domain
   ------------------------------------------------------------------------------
   
-  -- Measure and align the wb_sync to dp_sync latency
+  -- Measure and align the wb_sync to dp_sync roundtrip latency
   u_common_counter_wb_cnt : ENTITY common_lib.common_counter
   GENERIC MAP (
     g_width => c_wb_cnt_w
@@ -600,11 +641,14 @@ BEGIN
   
   nxt_r_dp.dp_word_req_dly(c_word_req_lat-1 DOWNTO 0) <= r_dp.dp_word_req_dly(c_word_req_lat-2 DOWNTO 0) & r_dp.dp_word_req;
   
-  p_dp_word_lock : PROCESS (r_dp, wb_cnt, fifo_rd_emp, fifo_rdusedw)
+  -- Monitor wb_cnt of roundtrip latency
+  wb_roundtrip_lock <= '1' WHEN UNSIGNED(r_dp.wb_cnt_roundtrip)=c_wb_sync_roundtrip ELSE '0';
+
+  p_dp_word_lock : PROCESS (r_dp, wb_cnt, wb_roundtrip_lock, fifo_rd_emp, fifo_rdusedw)
   BEGIN
-    nxt_r_dp.wb_cnt_clr          <= '1';
-    nxt_r_dp.wb_cnt_latency      <= (OTHERS=>'0');
-    nxt_r_dp.wb_cnt_latency_hold <= (OTHERS=>'0');
+    nxt_r_dp.wb_cnt_clr            <= '1';
+    nxt_r_dp.wb_cnt_roundtrip      <= (OTHERS=>'0');
+    nxt_r_dp.wb_cnt_roundtrip_hold <= (OTHERS=>'0');
     
     nxt_r_dp.dp_word_req         <= '1';
     nxt_r_dp.dp_word_locked      <= '0';
@@ -615,16 +659,16 @@ BEGIN
       -- Realignment enabled
       --------------------------------------------------------------------------
       IF r_dp.dp_phs_locked='1' THEN
-        -- Measure wb_sync - dp_sync latency
-        nxt_r_dp.wb_cnt_clr          <= r_dp.wb_cnt_clr;
-        nxt_r_dp.wb_cnt_latency      <= r_dp.wb_cnt_latency;
-        nxt_r_dp.wb_cnt_latency_hold <= r_dp.wb_cnt_latency_hold;
+        -- Measure wb_sync - dp_sync roundtrip latency
+        nxt_r_dp.wb_cnt_clr            <= r_dp.wb_cnt_clr;
+        nxt_r_dp.wb_cnt_roundtrip      <= r_dp.wb_cnt_roundtrip;
+        nxt_r_dp.wb_cnt_roundtrip_hold <= r_dp.wb_cnt_roundtrip_hold;
         IF r_dp.wb_sync='1' THEN
           nxt_r_dp.wb_cnt_clr <= '0';
         ELSIF r_dp.dp_sync='1' THEN
           nxt_r_dp.wb_cnt_clr <= '1';
-          nxt_r_dp.wb_cnt_latency <= wb_cnt;
-          nxt_r_dp.wb_cnt_latency_hold <= r_dp.wb_cnt_latency;
+          nxt_r_dp.wb_cnt_roundtrip <= wb_cnt;
+          nxt_r_dp.wb_cnt_roundtrip_hold <= r_dp.wb_cnt_roundtrip;
         END IF;
         
         -- Word lock control
@@ -633,35 +677,36 @@ BEGIN
         IF r_dp.dp_word_locked='0' THEN
           -- Word lock acquisition
           IF r_dp.dp_sync='1' THEN  -- dp_sync implies also that the FIFO is not empty, so no need to check fifo_rd_emp to avoid false dp_phs_val via dp_word_req_dly
-            -- Adjust wb_sync - dp_sync latency to become c_wb_sync_latency
-            IF UNSIGNED(wb_cnt) < c_wb_sync_latency THEN
+            -- Adjust wb_sync - dp_sync roundtrip latency to become c_wb_sync_roundtrip
+            IF UNSIGNED(wb_cnt) < c_wb_sync_roundtrip THEN
               nxt_r_dp.dp_word_req <= '0';                   -- too early dp_sync so slip 1 word
-            ELSIF UNSIGNED(wb_cnt) = c_wb_sync_latency THEN
+            ELSIF UNSIGNED(wb_cnt) = c_wb_sync_roundtrip THEN
               nxt_r_dp.dp_word_locked <= '1';                -- declare word locked
               
               -- Fine check FIFO fill level when lock is declared
               IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
-                nxt_r_dp.dp_word_lock_failed <= '1';         -- unexpected FIFO latency, so recover via in_rst
+                nxt_r_dp.dp_word_lock_failed <= '1';         -- unexpected change in FIFO fill level, so recover via in_rst
               END IF;
             END IF;
             
             -- Fine check that latency is incrementing properly during word lock acquisition
-            IF UNSIGNED(r_dp.wb_cnt_latency_hold)>0 THEN
-              IF UNSIGNED(r_dp.wb_cnt_latency_hold)/=UNSIGNED(r_dp.wb_cnt_latency)-1 THEN
-                nxt_r_dp.dp_word_lock_failed <= '1';         -- wrong latency increment, so recover via in_rst
+            IF UNSIGNED(r_dp.wb_cnt_roundtrip_hold)>0 THEN
+              IF UNSIGNED(r_dp.wb_cnt_roundtrip_hold)/=UNSIGNED(r_dp.wb_cnt_roundtrip)-1 THEN
+                nxt_r_dp.dp_word_lock_failed <= '1';         -- wrong roundtrip latency increment, so recover via in_rst
               END IF;
             END IF;
           END IF;
         ELSE
           -- *** Word locked, this is the correct end state for the ALIGNED data processing ***
           
-          -- Fine check latency during stable word lock
-          IF UNSIGNED(r_dp.wb_cnt_latency) /= c_wb_sync_latency THEN
+          -- Fine check roundtrip latency during stable word lock
+          IF wb_roundtrip_lock='0' AND r_dp.dp_maintain_phs = '0' THEN
+            -- After achieving dp_word_locked, but while dp_maintain_phs is still '0' the wb_cnt_roundtrip must exactly match c_wb_sync_roundtrip.
             nxt_r_dp.dp_word_lock_failed <= '1';             -- word lock lost, so recover via in_rst
           END IF;
           -- Fine check FIFO fill level during stable word lock
           IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
-            nxt_r_dp.dp_word_lock_failed <= '1';             -- unexpected FIFO latency, so recover via in_rst
+            nxt_r_dp.dp_word_lock_failed <= '1';             -- unexpected change in FIFO fill level, so recover via in_rst
           END IF;
         END IF;
       END IF;
@@ -676,7 +721,7 @@ BEGIN
         IF r_dp.dp_word_locked='0' THEN
           -- Word lock acquisition
           IF fifo_rd_emp='0' THEN  -- no dp_sync in raw mode, so need to use fifo_rd_emp to check that FIFO is not empty to avoid false dp_phs_val due to dp_word_req_dly
-            IF UNSIGNED(fifo_rdusedw) <= c_wb_fifo_latency-c_word_req_lat THEN
+            IF UNSIGNED(fifo_rdusedw) <= c_wb_fifo_fill_level-c_word_req_lat THEN
               nxt_r_dp.dp_word_req <= '0';             -- too few words in FIFO so slip 1 word
             ELSIF UNSIGNED(fifo_rdusedw) >= c_wb_fifo_fill_min THEN
               nxt_r_dp.dp_word_locked <= '1';          -- declare word locked
@@ -687,19 +732,19 @@ BEGIN
           
           -- Fine check FIFO fill level during stable word lock
           IF UNSIGNED(fifo_rdusedw) < c_wb_fifo_fill_min THEN
-            nxt_r_dp.dp_word_lock_failed <= '1';     -- unexpected FIFO latency, so recover via in_rst
+            nxt_r_dp.dp_word_lock_failed <= '1';     -- unexpected change in FIFO fill level, so recover via in_rst
           END IF;
         END IF;
       END IF;
       
     END IF;
     
-    -- Course check latency and FIFO fill level at any time
-    IF UNSIGNED(wb_cnt) > c_wb_sync_latency+1 THEN
+    -- Course check roundtrip latency and FIFO fill level at any time
+    IF UNSIGNED(wb_cnt) > c_wb_sync_roundtrip+1 THEN
       nxt_r_dp.dp_word_lock_failed <= '1';                 -- timeout dp_sync, so recover via in_rst
     END IF;
     IF UNSIGNED(fifo_rdusedw) > c_wb_fifo_fill_max THEN
-      nxt_r_dp.dp_word_lock_failed <= '1';                 -- unexpected FIFO latency, so recover via in_rst
+      nxt_r_dp.dp_word_lock_failed <= '1';                 -- unexpected change in FIFO fill level, so recover via in_rst
     END IF;
   END PROCESS;  
   
@@ -712,9 +757,10 @@ BEGIN
     -- Debug monitor status
     i_out_status               <= (OTHERS=>'0');
     i_out_status(           4) <= r_dp.dp_phs_locked;                     -- 1 bit
+    i_out_status(           5) <= wb_roundtrip_stable;                    -- 1 bit
     i_out_status( 7 DOWNTO  6) <= dp_in_clk_stable & dp_in_clk_detected;  -- 2 bit
     i_out_status(15 DOWNTO  8) <= fifo_rdusedw;                           -- c_fifo_size_w = 8
-    i_out_status(23 DOWNTO 16) <= RESIZE_UVEC(r_dp.wb_cnt_latency, 8);    -- c_wb_cnt_w <= 8
+    i_out_status(23 DOWNTO 16) <= RESIZE_UVEC(r_dp.wb_cnt_roundtrip, 8);  -- c_wb_cnt_w <= 8
     i_out_status(27 DOWNTO 24) <= TO_UVEC(r_dp.dp_phs_clk_select, 4);     -- g_nof_dp_phs_clk <= 6, fits in 4 bit
     i_out_status(31 DOWNTO 28) <= r_dp.dp_raw_phs;                        -- g_wb_factor = 4
   END PROCESS;
@@ -725,15 +771,16 @@ BEGIN
     dbg_status_0_out_word_locked       <= r_dp.dp_word_locked;
     dbg_status_1_out_word_stable       <= i_out_word_stable;
     dbg_status_4_dp_phs_locked         <= i_out_status(4);
+    dbg_status_5_wb_roundtrip_stable   <= i_out_status(5);
     dbg_status_6_dp_in_clk_detected    <= i_out_status(6);
     dbg_status_7_dp_in_clk_stable      <= i_out_status(7);
     dbg_status_15_8_fifo_rdusedw       <= i_out_status(15 DOWNTO 8);
-    dbg_status_23_16_wb_cnt_latency    <= i_out_status(23 DOWNTO 16);
+    dbg_status_23_16_wb_cnt_roundtrip  <= i_out_status(23 DOWNTO 16);
     dbg_status_27_24_dp_phs_clk_select <= i_out_status(27 DOWNTO 24);
     dbg_status_31_28_dp_raw_phs        <= i_out_status(31 DOWNTO 28) WHEN r_dp.dp_val='1' AND r_dp.le_val='1';  -- latch to view only yhe raw_phs when in lock
   END GENERATE;
   
-  u_common_stable_monitor : ENTITY common_lib.common_stable_monitor
+  u_common_stable_monitor_word_lock : ENTITY common_lib.common_stable_monitor
   PORT MAP (
     rst          => dp_rst,
     clk          => dp_clk,
@@ -742,10 +789,38 @@ BEGIN
     r_stable     => i_out_word_stable,
     r_stable_ack => out_word_stable_ack
   );
-    
+  
+  u_common_stable_monitor_wb_cnt_roundtrip : ENTITY common_lib.common_stable_monitor
+  PORT MAP (
+    rst          => dp_rst,
+    clk          => dp_clk,
+    -- MM
+    r_in         => wb_roundtrip_lock,
+    r_stable     => wb_roundtrip_stable,
+    r_stable_ack => out_word_stable_ack
+  );
+  
   out_word_locked <= r_dp.dp_word_locked;
   out_word_stable <= i_out_word_stable;
   
+  ------------------------------------------------------------------------------
+  -- Enable alignment or maintain current alignment once out_word_stable is achieved
+  ------------------------------------------------------------------------------
+  nxt_r_dp.dp_maintain_phs <= i_out_word_stable WHEN g_maintain_phs=TRUE ELSE '0';
+  
+  u_common_async_in_maintain_phs : ENTITY common_lib.common_async
+  GENERIC MAP (
+    g_rst_level => '1',
+    g_delay_len => c_delay_len
+  )
+  PORT MAP (
+    rst  => '0',
+    clk  => in_clk,
+    din  => r_dp.dp_maintain_phs,
+    dout => in_maintain_phs
+  );
+  
+  
   ------------------------------------------------------------------------------
   -- Registers
   ------------------------------------------------------------------------------
@@ -766,6 +841,7 @@ BEGIN
   BEGIN
     IF dp_rst='1' THEN
       r_dp.wb_sync_cap         <= '0';
+      r_dp.wb_sync             <= '0';
       r_dp.dp_in_rst_req       <= '1';
       r_dp.fifo_rd_req         <= '0';
       r_dp.le_sync             <= '0';
@@ -782,11 +858,12 @@ BEGIN
       r_dp.prev_dp_sync_cap    <= '0';
       r_dp.dp_sync             <= '0';
       r_dp.wb_cnt_clr          <= '1';
-      r_dp.wb_cnt_latency      <= (OTHERS=>'1');
+      r_dp.wb_cnt_roundtrip    <= (OTHERS=>'1');
       r_dp.dp_word_req         <= '1';
       r_dp.dp_word_req_dly     <= (OTHERS=>'1');
       r_dp.dp_word_locked      <= '0';
       r_dp.dp_word_lock_failed <= '0';
+      r_dp.dp_maintain_phs     <= '0';
     ELSIF rising_edge(dp_clk) THEN
       r_dp <= nxt_r_dp;
     END IF;