diff --git a/Makefile b/Makefile
index 208b0147b97b9d22425f4e61f288a30d0c716534..0a1aca45b4a9c971c21f92631d6a2183bd992420 100644
--- a/Makefile
+++ b/Makefile
@@ -20,8 +20,7 @@ tcl/sources.tcl:
 
 ###############################################################################
 # Compute interface from rdl files
-# TODO: generic rule from variables
-hdl/combpm_protocol_electron_ctrl.vhd: rdl/combpm_protocol_electron_ctrl.rdl
+hdl/%.vhd:rdl/%.rdl
 	hectare --axi-vhdl $@ $<
 
 ###############################################################################
diff --git a/hdl/combpm_protocol_electron.vhd b/hdl/combpm_protocol_electron.vhd
index 273bbb8c05c024efaf1d7db3e96e7226965c2755..32c3c05901a828d1c0207bbf62241a9f891d1b10 100644
--- a/hdl/combpm_protocol_electron.vhd
+++ b/hdl/combpm_protocol_electron.vhd
@@ -7,11 +7,13 @@ entity combpm_protocol_electron is
     port(
         rst_n              : in std_logic;
         clk                : in std_logic;
+        pps                : in std_logic;
+
+        mc_time            : in std_logic_vector(39 downto 0);
 
         -- GT interface
         gt_datarx          : in std_logic_vector(15 downto 0);
-        gt_rxresetdone     : in std_logic;
-        gt_rxbyteisaligned : in std_logic;
+        gt_interfaceready  : in std_logic;
 
         -- AXIS interface
         m_axi_tid          : out std_logic_vector(0 downto 0);
@@ -26,7 +28,13 @@ entity combpm_protocol_electron is
 
         -- Status and control interface
         soft_reset         : in std_logic;
-        frame_counter      : out std_logic_vector(15 downto 0);
+        frame_seq_cnt      : out std_logic_vector(15 downto 0);
+        frame_valid_cnt    : out std_logic_vector(15 downto 0);
+        frame_invalid_cnt  : out std_logic_vector(15 downto 0);
+        frame_valid_rate   : out std_logic_vector(15 downto 0);
+        frame_invalid_rate : out std_logic_vector(15 downto 0);
+        cnt_seq_mismatch   : out std_logic;
+        seq_discontinuity  : out std_logic;
         frame_error        : out std_logic
     );
 end entity combpm_protocol_electron;
@@ -71,10 +79,14 @@ architecture rtl of combpm_protocol_electron is
     signal crc_cnt           :  unsigned(3 downto 0);
     signal d                 :  std_logic_vector(15 downto 0);
 
-    signal frame_counter_r   :  unsigned(15 downto 0);
-    signal gt_rxcommadeten_s : std_logic;
+    signal last_seq          :  std_logic_vector(15 downto 0);
 
-    signal itf_ready    : std_logic;
+    signal last_cnt_seq_r    :  unsigned(15 downto 0);
+    signal cnt_frame_seq_r   :  unsigned(15 downto 0);
+    signal cnt_valid_r       :  unsigned(15 downto 0);
+    signal cnt_invalid_r     :  unsigned(15 downto 0);
+    signal rate_valid_r      :  unsigned(15 downto 0);
+    signal rate_invalid_r    :  unsigned(15 downto 0);
 
 
 begin
@@ -119,8 +131,8 @@ begin
                            '0';
 
     -- Any and all flag
-    flag_all            <= flag_sop and flag_eop and flag_dummy and flag_rsvd and flag_crc and itf_ready;
-    flag_any            <= flag_sop or flag_eop or flag_crc;
+    flag_all            <= flag_sop and flag_eop and flag_dummy and flag_rsvd and flag_crc and gt_interfaceready;
+    flag_any            <= (flag_sop or flag_eop or flag_crc) and gt_interfaceready;
 
     ----------------------------
     -- FRAME FIELD EXTRACTION --
@@ -244,8 +256,8 @@ begin
                 -- Make AXIS packet
                 m_axi_tdata(31 downto 0)    <= packet_ypos;
                 m_axi_tdata(63 downto 32)   <= packet_xpos;
-                m_axi_tdata(95 downto 64)   <= x"0000" & packet_timestamp;
-                m_axi_tdata(111 downto 96)  <= (others                  => '0');
+                m_axi_tdata(103 downto 64)  <= mc_time;
+                m_axi_tdata(111 downto 104) <= packet_timestamp(7 downto 0);
                 m_axi_tdata(127 downto 112) <= "000000" & packet_bpmid;
 
                 -- AXIS ancillary data
@@ -268,22 +280,82 @@ begin
     ------------------------
     -- CONTROL AND STATUS --
     ------------------------
-    frame_error     <= flag_any xor flag_all;
-    frame_counter   <= std_logic_vector(frame_counter_r);
-    itf_ready       <= gt_rxresetdone and gt_rxbyteisaligned;
+    frame_error         <= flag_all xor flag_any;
+    frame_valid_cnt     <= std_logic_vector(cnt_valid_r);
+    frame_invalid_cnt   <= std_logic_vector(cnt_invalid_r);
+    frame_seq_cnt       <= std_logic_vector(last_cnt_seq_r);
 
     -- frame counter
     p_framecnt:process(clk, rst_n)
     begin
         if rst_n = '0' then
-            frame_counter_r <= (others => '0');
+            cnt_frame_seq_r <= (others => '0');
+            cnt_valid_r     <= (others => '0');
+            cnt_invalid_r   <= (others => '0');
+            rate_valid_r    <= (others => '0');
+            rate_invalid_r  <= (others => '0');
         elsif rising_edge(clk) then
+
             if soft_reset = '1' then
-                frame_counter_r <= (others => '0');
+                cnt_frame_seq_r <= (others => '0');
+                cnt_valid_r     <= (others => '0');
+                cnt_invalid_r   <= (others => '0');
+                rate_valid_r    <= (others => '0');
+                rate_invalid_r  <= (others => '0');
             else
+                -- Valid frame counter
                 if flag_all = '1' then
-                    frame_counter_r <= frame_counter_r+1;
+                    cnt_valid_r <= cnt_valid_r+1;
+                end if;
+
+                -- Invalid frame counter
+                if (flag_all xor flag_any) = '1' then
+                    cnt_invalid_r <= cnt_invalid_r+1;
                 end if;
+
+                -- Rate counter
+                if pps = '1' then
+                    frame_valid_rate     <= std_logic_vector(rate_valid_r);
+                    frame_invalid_rate   <= std_logic_vector(rate_invalid_r);
+                    rate_valid_r    <= (others => '0');
+                    rate_invalid_r  <= (others => '0');
+                else
+                    -- Valid frame rate counter
+                    if flag_all = '1' then
+                        rate_valid_r <= rate_valid_r+1;
+                    end if;
+
+                    -- Invalid frame rate counter
+                    if (flag_all xor flag_any) = '1' then
+                        rate_invalid_r <= rate_invalid_r+1;
+                    end if;
+                end if;
+
+                -- Sequence detection
+                cnt_seq_mismatch    <= '0'; -- Supercharged in logic below
+                seq_discontinuity   <= '0'; -- Supercharged in logic below
+                if flag_all = '1' then
+                    if last_seq  = packet_timestamp then
+                        -- Same sequence
+                        cnt_frame_seq_r  <= cnt_frame_seq_r+1;
+                    else
+                        -- New sequence
+                        cnt_frame_seq_r <= (others => '0');
+                        last_seq        <= packet_timestamp;
+                        last_cnt_seq_r  <= cnt_frame_seq_r;
+
+                        -- Check sequence increment
+                        if unsigned(packet_timestamp) - unsigned(last_seq) /= 1 then
+                            seq_discontinuity   <= '1';
+                        end if;
+
+                        -- Check number of frame in sequence
+                        if last_cnt_seq_r /= cnt_frame_seq_r then
+                            cnt_seq_mismatch <= '1';
+                        end if;
+                    end if;
+                end if;
+
             end if;
         end if;
     end process p_framecnt;
diff --git a/hdl/top_combpm_electron.vhd b/hdl/top_combpm_electron.vhd
index 30789d71fe0d767b9c3125efe33b810033b5c129..fe7b8adef5763326ea79a65bcaa3884780515869 100644
--- a/hdl/top_combpm_electron.vhd
+++ b/hdl/top_combpm_electron.vhd
@@ -15,7 +15,9 @@ entity top_combpm_electron is
 
         rst_n                : in std_logic;    -- Asynchronous reset
         free_100_clk         : in std_logic;    -- Freerunning clock for GT
+        pps                  : in std_logic;    -- A pulse per second signal, sync to clk domain
         clk                  : out std_logic;   -- main clock (AXIS and AXI-MM)
+        mc_time              : in std_logic_vector(39 downto 0);
 
         -- Transceiver QPLL interface
         qpll_out_clk         : in std_logic;    -- QPLL clock for transceivers
@@ -162,10 +164,17 @@ architecture struct of top_combpm_electron is
     signal sync_reset    : std_logic;
     signal usrclk        : std_logic;
     signal rst           : std_logic;
-    signal frame_counter : std_logic_vector(15 downto 0);
-    signal frame_error   : std_logic;
     signal soft_reset    : std_logic;
 
+    signal frame_seq_cnt      : std_logic_vector(15 downto 0);
+    signal frame_valid_cnt    : std_logic_vector(15 downto 0);
+    signal frame_invalid_cnt  : std_logic_vector(15 downto 0);
+    signal frame_valid_rate   : std_logic_vector(15 downto 0);
+    signal frame_invalid_rate : std_logic_vector(15 downto 0);
+    signal cnt_seq_mismatch   : std_logic;
+    signal seq_discontinuity  : std_logic;
+    signal frame_error        : std_logic;
+
     signal gt_datarx          : std_logic_vector(15 downto 0);
     signal gt_powergood       : std_logic;
     signal gt_rxclkactive     : std_logic;
@@ -178,6 +187,8 @@ architecture struct of top_combpm_electron is
     signal gt_rxresetdatapath : std_logic;
     signal gt_rxresetplldatapath : std_logic;
 
+    signal interface_ready :  std_logic;
+
 begin
 
 
@@ -211,6 +222,8 @@ begin
     -- SFP direct connexion
     sfp_tx_disable  <= '1';
 
+    -- Interface Ready signal combinatorial
+    interface_ready <= gt_powergood and gt_rxresetdone and gt_rxbyteisaligned and qpll_lock;
 
     ----------------------
     -- AXI-MM INTERFACE --
@@ -233,10 +246,16 @@ begin
         gt_rxcommadeten_o     => gt_rxcommadeten,
         gt_rxrstdatapath_o    => gt_rxresetdatapath,
         gt_rxrstplldatapath_o => gt_rxresetplldatapath,
-        protocol_framecnt_i   => frame_counter,
-        protocol_frameerror_i => frame_error,
         protocol_softreset_o  => soft_reset,
 
+        protocol_frameerror_i => frame_error,
+        protocol_seqframecnterror_i => cnt_seq_mismatch,
+        protocol_seqframediscont_i => seq_discontinuity,
+        framecnt_validframecnt_i => frame_valid_cnt,
+        framecnt_invalidframecnt_i => frame_invalid_cnt,
+        framerate_validframerate_i => frame_valid_rate,
+        framerate_invalidframerate_i => frame_invalid_rate,
+
         clk                   => usrclk,
         reset                 => sync_reset,
         S_AXI_AWADDR          => S_AXI_AWADDR,
@@ -267,9 +286,9 @@ begin
     port map(
         rst_n              => sync_resetn,
         clk                => usrclk,
+        pps                => pps,
         gt_datarx          => gt_datarx,
-        gt_rxresetdone     => gt_rxresetdone,
-        gt_rxbyteisaligned => gt_rxbyteisaligned,
+        gt_interfaceready  => interface_ready,
 
         m_axi_tid          => m_axis_tid,
         m_axi_tdest        => m_axis_tdest,
@@ -281,10 +300,16 @@ begin
         m_axi_tvalid       => m_axis_tvalid,
         m_axi_tready       => m_axis_tready,
 
+        mc_time            => mc_time,
         soft_reset         => soft_reset,
-        frame_counter      => frame_counter,
+        frame_seq_cnt      => frame_seq_cnt,
+        frame_valid_cnt    => frame_valid_cnt,
+        frame_invalid_cnt  => frame_invalid_cnt,
+        frame_valid_rate   => frame_valid_rate,
+        frame_invalid_rate => frame_invalid_rate,
+        cnt_seq_mismatch   => cnt_seq_mismatch,
+        seq_discontinuity  => seq_discontinuity,
         frame_error        => frame_error
-
     );
 
     ---------------
diff --git a/rdl/combpm_protocol_electron_ctrl.rdl b/rdl/combpm_ctrl.rdl
similarity index 70%
rename from rdl/combpm_protocol_electron_ctrl.rdl
rename to rdl/combpm_ctrl.rdl
index 559c0b5ee70ae504a9e9f177a40cd9903c46912b..98745d9cc596d4f899bf6752c8ddda3a584dc06c 100644
--- a/rdl/combpm_protocol_electron_ctrl.rdl
+++ b/rdl/combpm_ctrl.rdl
@@ -96,24 +96,55 @@ addrmap combpm_ctrl {
     reg {
         name="Protocol status and control";
 
-        field {
-            desc="Frame counter";
-            hw=w;
-            sw=r;
-        } FRAMECNT[16];
-
         field {
             desc="Frame error";
-            hw=w;
-            sw=r;
+            hw=w;sw=r;
         } FRAMEERROR;
 
+        field {
+            desc="Sequence frame count mismatch";
+            hw=w;sw=r;
+        } SEQFRAMECNTERROR;
+
+        field {
+            desc="Sequence frame discontinuity";
+            hw=w;sw=r;
+        } SEQFRAMEDISCONT;
+
         field {
             desc="Soft reset";
-            hw=r;
-            sw=rw;
+            hw=r;sw=rw;
         } SOFTRESET;
 
     } PROTOCOL;
 
+    reg {
+        name="Protocol frame counters";
+
+        field {
+            desc="Valid frame counter";
+            hw=w;sw=r;
+        } VALIDFRAMECNT[16];
+
+        field {
+            desc="Invalid frame counter";
+            hw=w;sw=r;
+        } INVALIDFRAMECNT[16];
+    } FRAMECNT;
+
+    reg {
+        name="Protocol frame rate";
+
+        field {
+            desc="Valid frame rate";
+            hw=w;sw=r;
+        } VALIDFRAMERATE[16];
+
+        field {
+            desc="Invalid frame rate";
+            hw=w;sw=r;
+        } INVALIDFRAMERATE[16];
+    } FRAMERATE;
+
+
 };