diff --git a/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd b/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd
index 407223ebefa07cf14118ebb415bf87e17cbf06af..b9a44ad727df7423db06f33781fcbfddcd027c2d 100644
--- a/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd
+++ b/libraries/io/ppsh/src/vhdl/mms_ppsh.vhd
@@ -65,6 +65,7 @@ ARCHITECTURE str OF mms_ppsh IS
   SIGNAL st_pps_toggle      : STD_LOGIC;
   SIGNAL st_pps_stable      : STD_LOGIC;
   SIGNAL st_capture_cnt     : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);  -- counts the number of clk clock cycles between subsequent pps_ext pulses
+  SIGNAL st_offset_cnt      : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);  -- counts the number of clk clock cycles between now and last pps_ext pulse
   
   SIGNAL st_pps_stable_ack  : STD_LOGIC;
   
@@ -96,6 +97,7 @@ BEGIN
     pps_toggle       => st_pps_toggle,
     pps_stable       => st_pps_stable,
     capture_cnt      => st_capture_cnt,
+    offset_cnt       => st_offset_cnt,
     pps_stable_ack   => st_pps_stable_ack,
     capture_edge     => st_capture_edge,
     expected_cnt     => st_expected_cnt
@@ -126,6 +128,7 @@ BEGIN
     st_pps_stable       => st_pps_stable,
     st_pps_stable_ack   => st_pps_stable_ack,
     st_capture_cnt      => st_capture_cnt,
+    st_offset_cnt       => st_offset_cnt,
     st_capture_edge     => st_capture_edge,
     st_expected_cnt     => st_expected_cnt
   );
diff --git a/libraries/io/ppsh/src/vhdl/ppsh.vhd b/libraries/io/ppsh/src/vhdl/ppsh.vhd
index 9a6332cdd961f9006dc1aa9d7dd1b95f7c0342d6..30128bf029d01e798abdc99080609adde76761f3 100644
--- a/libraries/io/ppsh/src/vhdl/ppsh.vhd
+++ b/libraries/io/ppsh/src/vhdl/ppsh.vhd
@@ -68,6 +68,7 @@ ENTITY ppsh IS
     pps_toggle     : OUT STD_LOGIC;           -- pps toggle level signal in clk domain (i.e. 0.5 Hz square wave)
     pps_stable     : OUT STD_LOGIC;           -- pps stable signal in clk domain
     capture_cnt    : OUT STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)-1 DOWNTO 0);  -- counts the number of clk clock cycles between subsequent pps_ext pulses
+    offset_cnt     : OUT STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)+1 DOWNTO 0);  -- counts the number of clk clock cycles between now and last pps_ext pulse
     pps_stable_ack : IN  STD_LOGIC := '0';    -- pps stable acknowledge in clk domain
     capture_edge   : IN  STD_LOGIC := '0';                                    -- when '0' then clock pps_ext on rising edge of clk, else use falling edge of clk
     expected_cnt   : IN  STD_LOGIC_VECTOR(ceil_log2(g_clk_freq)-1 DOWNTO 0) := (OTHERS=> '1') -- expected number of clk clock cycles between subsequent pps_ext pulses
@@ -92,6 +93,8 @@ ARCHITECTURE rtl OF ppsh IS
   
   SIGNAL i_capture_cnt     : STD_LOGIC_VECTOR(capture_cnt'RANGE) := (OTHERS=>'1');
 
+  SIGNAL i_offset_cnt      : STD_LOGIC_VECTOR(offset_cnt'RANGE) := (OTHERS=>'1');
+
   SIGNAL pps_sys_buf       : STD_LOGIC;
   SIGNAL i_pps_toggle      : STD_LOGIC;
   SIGNAL nxt_pps_toggle    : STD_LOGIC;
@@ -102,7 +105,8 @@ ARCHITECTURE rtl OF ppsh IS
 BEGIN
 
   capture_cnt <= i_capture_cnt;
-  pps_toggle <= i_pps_toggle;
+  offset_cnt  <= i_offset_cnt;
+  pps_toggle  <= i_pps_toggle;
 
   pps_ext_delayed(0) <= pps_ext;  -- no input delay support
   
@@ -174,6 +178,17 @@ BEGIN
     interval_cnt  => i_capture_cnt
   );
   
+  u_offset_cnt : ENTITY common_lib.common_counter
+  GENERIC MAP (
+    g_width => offset_cnt'LENGTH
+  )
+  PORT MAP (
+    rst           => rst,
+    clk           => clk,
+    cnt_clr       => pps_ext_revt,
+    count         => i_offset_cnt
+  );
+
   -- Output the pps_sys with extra pipelining to ease timing of pps_sys fan out
   u_pps_sys : ENTITY common_lib.common_pipeline_sl
   GENERIC MAP (
diff --git a/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd b/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd
index 51efde2ff71ddcd645f5445a3b39a4e1197137a7..87d86595a84d2630e61c590951d20a595aaae9c1 100644
--- a/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd
+++ b/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd
@@ -32,6 +32,21 @@
 --  |edge[31],                xxx                       expected_cnt = [n:0]|  1
 --  |-----------------------------------------------------------------------|
 
+
+-- Info from L2SDP-78 ticket.
+-- Add a new offset_cnt field to the PPSH register that reports the current capture_cnt value at the moment that this MM read access occurs.
+-- The offset_cnt reports the time since last PPSH in units of the dp_clk, so 5 ns (at 200MHz). The host can use this offset_cnt value to
+-- determine the alignment between its local Time of Day and the PPS in the FPGA.
+-- 
+-- The offset_cnt needs to be supported in the pi_ppsh.py and util_ppsh.py. Please also use the option --rep to quickly repeat the reading
+-- of the PPSH registers. This is useful to show that the offset_cnt increases and then restarts after every new PPS. The PPS in the FPGA is
+-- also represented by the pps_toggle field in the PPSH registers.
+-- 
+-- The PPSH is part of unb2_minimal. To fit the PPSH register the span in QSYS and in the mmm file needs to be increased from 2 words to 4 words.
+--  
+-- Also prepare unb2c_minimal by updating the PPSH register span there.
+
+
 LIBRARY IEEE, common_lib;
 USE IEEE.STD_LOGIC_1164.ALL;
 USE common_lib.common_pkg.ALL;
@@ -57,6 +72,7 @@ ENTITY ppsh_reg IS
     st_pps_toggle     : IN  STD_LOGIC;
     st_pps_stable     : IN  STD_LOGIC;
     st_capture_cnt    : IN  STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);  -- counts the number of clk clock cycles between subsequent pps_ext pulses
+    st_offset_cnt     : IN  STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)+1 DOWNTO 0);  -- counts the number of clk clock cycles between now and last pps_ext pulse
     
     st_pps_stable_ack : OUT STD_LOGIC;
     
@@ -70,9 +86,9 @@ ARCHITECTURE rtl OF ppsh_reg IS
 
   -- Define the actual size of the MM slave register
   CONSTANT c_mm_reg : t_c_mem := (latency  => 1,
-                                  adr_w    => ceil_log2(2),
+                                  adr_w    => ceil_log2(4),
                                   dat_w    => c_word_w,       -- Use MM bus data width = c_word_w = 32 for all MM registers
-                                  nof_dat  => 2,
+                                  nof_dat  => 4,
                                   init_sl  => '0');
                                                
   -- Register access control signal in mm_clk domain
@@ -85,6 +101,7 @@ ARCHITECTURE rtl OF ppsh_reg IS
   
   SIGNAL mm_capture_cnt    : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);
   SIGNAL mm_expected_cnt   : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);
+  SIGNAL mm_offset_cnt     : STD_LOGIC_VECTOR(ceil_log2(g_st_clk_freq)-1 DOWNTO 0);
     
 BEGIN
 
@@ -139,6 +156,9 @@ BEGIN
             -- Read back PPSH control
             sla_out.rddata(31)          <= mm_capture_edge;
             sla_out.rddata(29 DOWNTO 0) <= RESIZE_UVEC(mm_expected_cnt, 30);
+          WHEN 2 =>
+            -- Read PPSH offset count
+            sla_out.rddata(31 DOWNTO 0) <= RESIZE_UVEC(mm_offset_cnt, 32);
           WHEN OTHERS => NULL;  -- not used MM addresses
         END CASE;
       END IF;
@@ -166,6 +186,7 @@ BEGIN
     mm_pps_toggle      <= st_pps_toggle;
     mm_pps_stable      <= st_pps_stable;
     mm_capture_cnt     <= st_capture_cnt;
+    mm_offset_cnt      <= st_offset_cnt;
     
     st_pps_stable_ack  <= mm_pps_stable_ack;
     
@@ -209,6 +230,18 @@ BEGIN
       out_new     => OPEN
     );
 
+  u_offset_cnt : ENTITY common_lib.common_reg_cross_domain
+    PORT MAP (
+      in_rst      => st_rst,
+      in_clk      => st_clk,
+      in_dat      => st_offset_cnt,
+      in_done     => OPEN,
+      out_rst     => mm_rst,
+      out_clk     => mm_clk,
+      out_dat     => mm_offset_cnt,
+      out_new     => OPEN
+    );
+
     -- MM --> ST
     u_pps_stable_ack : ENTITY common_lib.common_spulse
     PORT MAP (