diff --git a/modules/Manifest.py b/modules/Manifest.py
index 368277410609e7d7727747773a35f3385381dbea..f1a3ef004bc7fb932313ea41f7b25bc8189c5b17 100644
--- a/modules/Manifest.py
+++ b/modules/Manifest.py
@@ -16,5 +16,6 @@ modules =  {
         "wr_streamers",
         "wr_nic",
         "wr_txtsu",
+        "wr_irig",
     ]
 }
diff --git a/modules/wr_irig/Manifest.py b/modules/wr_irig/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..38e6d03089f25878fc8989a35bee193309a178c9
--- /dev/null
+++ b/modules/wr_irig/Manifest.py
@@ -0,0 +1 @@
+files = ["wr_irig_slave.vhd", "xwr_irig_slave.vhd", "irig_slave_regs.vhd"]
diff --git a/modules/wr_irig/generate_cheby_files.sh b/modules/wr_irig/generate_cheby_files.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a17adf479aae01db445a14724962a4140b4bb8fc
--- /dev/null
+++ b/modules/wr_irig/generate_cheby_files.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+cheby -i irig_slave_regs.cheby --gen-hdl irig_slave_regs.vhd
+cheby -i irig_slave_regs.cheby --gen-c irig_slave_regs.h
\ No newline at end of file
diff --git a/modules/wr_irig/irig_slave_regs.cheby b/modules/wr_irig/irig_slave_regs.cheby
new file mode 100644
index 0000000000000000000000000000000000000000..79e5be0c0f525e542ecafcfc2bdf505e3b972c81
--- /dev/null
+++ b/modules/wr_irig/irig_slave_regs.cheby
@@ -0,0 +1,130 @@
+##############################################################################;
+## Title      : IRIG-B Register Block (slave)
+## Project    : White Rabbit Switch
+##############################################################################;
+## File       : irig_slave_regs.cheby
+## Author     : Harvey Leicester
+## Company    : CERN BE-CEM-EDL
+## Created    : 2024-10-17
+## Last update: 2024-10-17
+##############################################################################
+## Description: register interface for irig slave
+##############################################################################
+##
+## Copyright (c) 2024 CERN / BE-CEM-EDL
+##
+## This source file is free software; you can redistribute it
+## and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation;
+## either version 2.1 of the License, or (at your option) any
+## later version.
+##
+## This source is distributed in the hope that it will be
+## useful, but WITHOUT ANY WARRANTY; without even the implied
+## warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+## PURPOSE.  See the GNU Lesser General Public License for more
+## details.
+##
+## You should have received a copy of the GNU Lesser General
+## Public License along with this source; if not, download it
+## from http://www.gnu.org/licenses/lgpl-2.1l.html
+##
+##############################################################################-
+
+memory-map:
+  name: irig_slave
+  description: IRIG-B slave register block
+  bus: wb-32-be
+  x-hdl:
+    iogroup: irig_regs
+    name-suffix: _regs
+  schema-version:
+    core: 2.0.0
+    x-conversions: 1.0.0
+    x-hdl: 1.0.0
+    x-map-info: 1.0.0
+    x-wbgen: 1.0.0
+  children:
+  - reg:
+      name: CR
+      description: Control Register
+      width: 32
+      access: rw
+      address: 0x0
+      children:
+      - field:
+          name: enable
+          description: enable flag
+          range: 0
+  - reg:
+      name: TOD
+      description: Time of day hr:min:sec
+      width: 32
+      access: ro
+      children:
+      - field:
+          name: seconds
+          description: seconds from irig frame
+          range: 7-0
+      - field:
+          name: minutes
+          description: minutes from irig frame
+          range: 16-8
+      - field:
+          name: hours
+          description: hours from irig frame
+          range: 28-20
+      - field:
+          name: valid
+          description: valid flag
+          range: 31
+  - reg:
+      name: DATE
+      description: Date, Years / Days
+      width: 32
+      access: ro
+      children:
+      - field:
+          name: days
+          description: days from irig frame
+          range: 10-0
+      - field:
+          name: years
+          description: years from irig frame
+          range: 24-16
+      - field:
+          name: valid
+          description: valid flag
+          range: 31
+  - reg:
+      name: CTRL
+      description: Control functions 0 & 1
+      width: 32
+      access: ro
+      children:
+      - field:
+          name: fcn0
+          description: control function 0
+          range: 8-0
+      - field:
+          name: fcn1
+          description: control function 1
+          range: 24-16
+      - field:
+          name: valid
+          description: valid flag
+          range: 31
+  - reg:
+      name: SBS
+      description: Straight Binary Seconds
+      width: 32
+      access: ro
+      children:
+      - field:
+          name: sbs
+          description: sbs from irig frame
+          range: 17-0
+      - field:
+          name: valid
+          description: valid flag
+          range: 31
\ No newline at end of file
diff --git a/modules/wr_irig/irig_slave_regs.vhd b/modules/wr_irig/irig_slave_regs.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..877bb9ad7117d49249f832f591e8cdbc1abc46ea
--- /dev/null
+++ b/modules/wr_irig/irig_slave_regs.vhd
@@ -0,0 +1,228 @@
+-- Do not edit.  Generated by cheby 1.6.dev0 using these options:
+--  -i irig_slave_regs.cheby --gen-hdl irig_slave_regs.vhd
+-- Generated on Thu Oct 24 14:19:28 2024 by harvey
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+package irig_slave_regs_pkg is
+  type t_irig_regs_master_out is record
+    CR_enable        : std_logic;
+  end record t_irig_regs_master_out;
+  subtype t_irig_regs_slave_in is t_irig_regs_master_out;
+
+  type t_irig_regs_slave_out is record
+    TOD_seconds      : std_logic_vector(7 downto 0);
+    TOD_minutes      : std_logic_vector(8 downto 0);
+    TOD_hours        : std_logic_vector(8 downto 0);
+    TOD_valid        : std_logic;
+    DATE_days        : std_logic_vector(10 downto 0);
+    DATE_years       : std_logic_vector(8 downto 0);
+    DATE_valid       : std_logic;
+    CTRL_fcn0        : std_logic_vector(8 downto 0);
+    CTRL_fcn1        : std_logic_vector(8 downto 0);
+    CTRL_valid       : std_logic;
+    SBS_sbs          : std_logic_vector(17 downto 0);
+    SBS_valid        : std_logic;
+  end record t_irig_regs_slave_out;
+  subtype t_irig_regs_master_in is t_irig_regs_slave_out;
+
+end irig_slave_regs_pkg;
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.irig_slave_regs_pkg.all;
+
+entity irig_slave_regs is
+  port (
+    rst_n_i              : in    std_logic;
+    clk_i                : in    std_logic;
+    wb_cyc_i             : in    std_logic;
+    wb_stb_i             : in    std_logic;
+    wb_adr_i             : in    std_logic_vector(4 downto 2);
+    wb_sel_i             : in    std_logic_vector(3 downto 0);
+    wb_we_i              : in    std_logic;
+    wb_dat_i             : in    std_logic_vector(31 downto 0);
+    wb_ack_o             : out   std_logic;
+    wb_err_o             : out   std_logic;
+    wb_rty_o             : out   std_logic;
+    wb_stall_o           : out   std_logic;
+    wb_dat_o             : out   std_logic_vector(31 downto 0);
+    -- Wires and registers
+    irig_regs_i          : in    t_irig_regs_master_in;
+    irig_regs_o          : out   t_irig_regs_master_out
+  );
+end irig_slave_regs;
+
+architecture syn of irig_slave_regs is
+  signal rd_req_int                     : std_logic;
+  signal wr_req_int                     : std_logic;
+  signal rd_ack_int                     : std_logic;
+  signal wr_ack_int                     : std_logic;
+  signal wb_en                          : std_logic;
+  signal ack_int                        : std_logic;
+  signal wb_rip                         : std_logic;
+  signal wb_wip                         : std_logic;
+  signal CR_enable_reg                  : std_logic;
+  signal CR_wreq                        : std_logic;
+  signal CR_wack                        : std_logic;
+  signal rd_ack_d0                      : std_logic;
+  signal rd_dat_d0                      : std_logic_vector(31 downto 0);
+  signal wr_req_d0                      : std_logic;
+  signal wr_adr_d0                      : std_logic_vector(4 downto 2);
+  signal wr_dat_d0                      : std_logic_vector(31 downto 0);
+begin
+
+  -- WB decode signals
+  wb_en <= wb_cyc_i and wb_stb_i;
+
+  process (clk_i) begin
+    if rising_edge(clk_i) then
+      if rst_n_i = '0' then
+        wb_rip <= '0';
+      else
+        wb_rip <= (wb_rip or (wb_en and not wb_we_i)) and not rd_ack_int;
+      end if;
+    end if;
+  end process;
+  rd_req_int <= (wb_en and not wb_we_i) and not wb_rip;
+
+  process (clk_i) begin
+    if rising_edge(clk_i) then
+      if rst_n_i = '0' then
+        wb_wip <= '0';
+      else
+        wb_wip <= (wb_wip or (wb_en and wb_we_i)) and not wr_ack_int;
+      end if;
+    end if;
+  end process;
+  wr_req_int <= (wb_en and wb_we_i) and not wb_wip;
+
+  ack_int <= rd_ack_int or wr_ack_int;
+  wb_ack_o <= ack_int;
+  wb_stall_o <= not ack_int and wb_en;
+  wb_rty_o <= '0';
+  wb_err_o <= '0';
+
+  -- pipelining for wr-in+rd-out
+  process (clk_i) begin
+    if rising_edge(clk_i) then
+      if rst_n_i = '0' then
+        rd_ack_int <= '0';
+        wb_dat_o <= "00000000000000000000000000000000";
+        wr_req_d0 <= '0';
+        wr_adr_d0 <= "000";
+        wr_dat_d0 <= "00000000000000000000000000000000";
+      else
+        rd_ack_int <= rd_ack_d0;
+        wb_dat_o <= rd_dat_d0;
+        wr_req_d0 <= wr_req_int;
+        wr_adr_d0 <= wb_adr_i;
+        wr_dat_d0 <= wb_dat_i;
+      end if;
+    end if;
+  end process;
+
+  -- Register CR
+  irig_regs_o.CR_enable <= CR_enable_reg;
+  process (clk_i) begin
+    if rising_edge(clk_i) then
+      if rst_n_i = '0' then
+        CR_enable_reg <= '0';
+        CR_wack <= '0';
+      else
+        if CR_wreq = '1' then
+          CR_enable_reg <= wr_dat_d0(0);
+        end if;
+        CR_wack <= CR_wreq;
+      end if;
+    end if;
+  end process;
+
+  -- Register TOD
+
+  -- Register DATE
+
+  -- Register CTRL
+
+  -- Register SBS
+
+  -- Process for write requests.
+  process (wr_adr_d0, wr_req_d0, CR_wack) begin
+    CR_wreq <= '0';
+    case wr_adr_d0(4 downto 2) is
+    when "000" =>
+      -- Reg CR
+      CR_wreq <= wr_req_d0;
+      wr_ack_int <= CR_wack;
+    when "001" =>
+      -- Reg TOD
+      wr_ack_int <= wr_req_d0;
+    when "010" =>
+      -- Reg DATE
+      wr_ack_int <= wr_req_d0;
+    when "011" =>
+      -- Reg CTRL
+      wr_ack_int <= wr_req_d0;
+    when "100" =>
+      -- Reg SBS
+      wr_ack_int <= wr_req_d0;
+    when others =>
+      wr_ack_int <= wr_req_d0;
+    end case;
+  end process;
+
+  -- Process for read requests.
+  process (wb_adr_i, rd_req_int, CR_enable_reg, irig_regs_i.TOD_seconds,
+           irig_regs_i.TOD_minutes, irig_regs_i.TOD_hours,
+           irig_regs_i.TOD_valid, irig_regs_i.DATE_days,
+           irig_regs_i.DATE_years, irig_regs_i.DATE_valid,
+           irig_regs_i.CTRL_fcn0, irig_regs_i.CTRL_fcn1,
+           irig_regs_i.CTRL_valid, irig_regs_i.SBS_sbs, irig_regs_i.SBS_valid) begin
+    -- By default ack read requests
+    rd_dat_d0 <= (others => 'X');
+    case wb_adr_i(4 downto 2) is
+    when "000" =>
+      -- Reg CR
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(0) <= CR_enable_reg;
+      rd_dat_d0(31 downto 1) <= (others => '0');
+    when "001" =>
+      -- Reg TOD
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(7 downto 0) <= irig_regs_i.TOD_seconds;
+      rd_dat_d0(16 downto 8) <= irig_regs_i.TOD_minutes;
+      rd_dat_d0(19 downto 17) <= (others => '0');
+      rd_dat_d0(28 downto 20) <= irig_regs_i.TOD_hours;
+      rd_dat_d0(30 downto 29) <= (others => '0');
+      rd_dat_d0(31) <= irig_regs_i.TOD_valid;
+    when "010" =>
+      -- Reg DATE
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(10 downto 0) <= irig_regs_i.DATE_days;
+      rd_dat_d0(15 downto 11) <= (others => '0');
+      rd_dat_d0(24 downto 16) <= irig_regs_i.DATE_years;
+      rd_dat_d0(30 downto 25) <= (others => '0');
+      rd_dat_d0(31) <= irig_regs_i.DATE_valid;
+    when "011" =>
+      -- Reg CTRL
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(8 downto 0) <= irig_regs_i.CTRL_fcn0;
+      rd_dat_d0(15 downto 9) <= (others => '0');
+      rd_dat_d0(24 downto 16) <= irig_regs_i.CTRL_fcn1;
+      rd_dat_d0(30 downto 25) <= (others => '0');
+      rd_dat_d0(31) <= irig_regs_i.CTRL_valid;
+    when "100" =>
+      -- Reg SBS
+      rd_ack_d0 <= rd_req_int;
+      rd_dat_d0(17 downto 0) <= irig_regs_i.SBS_sbs;
+      rd_dat_d0(30 downto 18) <= (others => '0');
+      rd_dat_d0(31) <= irig_regs_i.SBS_valid;
+    when others =>
+      rd_ack_d0 <= rd_req_int;
+    end case;
+  end process;
+end syn;
diff --git a/modules/wr_irig/wr_irig_slave.vhd b/modules/wr_irig/wr_irig_slave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..97fba7dc020881b6adb817fad97439f9719abbc9
--- /dev/null
+++ b/modules/wr_irig/wr_irig_slave.vhd
@@ -0,0 +1,358 @@
+-------------------------------------------------------------------------------
+-- Title      : WR Switch IRIG slave module
+-- Project    : White Rabbit Switch
+-------------------------------------------------------------------------------
+-- File       : wr_irig_slave.vhd
+-- Author     : Harvey Leicester
+-- Company    : CERN BE-CEM-EDL
+-- Created    : 2024-10-23
+-- Last update: 2024-10-23
+-- Platform   : FPGA-generic
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- IRIG-B004 slave interface
+-------------------------------------------------------------------------------
+--
+-- Copyright (c) 2012 - 2024 CERN / BE-CEM-EDL
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE.  See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.gnu.org/licenses/lgpl-2.1.html
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.gencores_pkg.all;
+
+entity wr_irig_slave is
+  generic (
+    g_clks_per_ms : integer := 62500
+  );
+  port (
+    clk_sys_i     : in std_logic;   --sys / sampling clock
+    rst_sys_n_i   : in std_logic;   --sys rst
+    irig_i        : in std_logic;   --irig data in
+
+    secs_o        : out std_logic_vector(7 downto 0);  --seconds
+    mins_o        : out std_logic_vector(8 downto 0);  --minutes
+    hrs_o         : out std_logic_vector(8 downto 0);  --hours
+    days_o        : out std_logic_vector(10 downto 0); --day of year
+    year_o        : out std_logic_vector(8 downto 0);  --year
+    ctrl0_o       : out std_logic_vector(8 downto 0);  --control function 0
+    ctrl1_o       : out std_logic_vector(8 downto 0);  --contorl function 1
+    sbs_o         : out std_logic_vector(17 downto 0); --straight binary seconds
+    valid_o       : out std_logic;                     --output valid
+    pps_o         : out std_logic  --pps out, generated from start of irig frame
+  );
+end entity wr_irig_slave;
+
+architecture rtl of wr_irig_slave is
+
+  constant c_MARKER_MS : integer := 8;
+  constant c_HIGH_MS   : integer := 5;
+  constant c_LOW_MS    : integer := 2;
+  constant c_NUM_FIELDS : integer := 10;
+  constant c_TICK_CNT_SOF : integer := 10;
+  constant c_TICK_CNT_FRAME : integer := 1000;
+  constant c_TICK_CNT_PREF  : integer := 991;
+
+  type t_irig_frame_state is
+  (
+    S_IDLE,
+    S_PARSE8B,
+    S_WAITMARKER,
+    S_PARSE9B
+  );
+
+  type t_irig_smpl_state is
+  (
+    S_IDLE,
+    S_SMPL
+  );
+
+  type t_frame_sof_state is
+  (
+    S_IDLE,
+    S_CHECKSOF
+  );
+
+  signal irig_frame_state : t_irig_frame_state := S_IDLE;
+  signal irig_smpl_state  : t_irig_smpl_state  := S_IDLE;
+  signal frame_sof_state  : t_frame_sof_state  := S_IDLE;
+
+  type t_field_array is array (0 to c_NUM_FIELDS-1) of std_logic_vector(8 downto 0);
+
+  signal field : t_field_array;
+  signal d_synced, d_rising, d_falling  : std_logic;
+  signal sreg : std_logic_vector(8 downto 0);
+  signal high_cnt, field_cnt : unsigned(3 downto 0);
+  signal tick : std_logic;
+  signal clk_cnt  : unsigned(15 downto 0);
+  signal count_ms : unsigned(3 downto 0);
+  signal bit_count : unsigned(3 downto 0);
+  signal tick_cnt : unsigned(9 downto 0);
+
+  signal sof, synced : std_logic;
+  signal marker, irig_data : std_logic;
+  signal d_valid, field_valid, smpl_err : std_logic;
+  signal secs : std_logic_vector(7 downto 0);
+  signal mins, hrs, days0, days1, yrs, ctrl0, ctrl1, sbs0, sbs1 : std_logic_vector(8 downto 0);
+
+begin
+
+  U_sync_data: gc_sync_ffs
+  port map
+  (
+    clk_i    => clk_sys_i,
+    rst_n_i  => '1',
+    data_i   => irig_i,
+    synced_o => d_synced,
+    npulse_o => d_falling,
+    ppulse_o => d_rising
+  );
+
+  p_tick_gen: process(clk_sys_i) is 
+  begin 
+    if rising_edge(clk_sys_i) then 
+      if (rst_sys_n_i = '0' or d_rising = '1') then 
+        clk_cnt <= to_unsigned(g_clks_per_ms/2, clk_cnt'length);
+      else 
+        clk_cnt <= clk_cnt+1;
+        if(clk_cnt >=(g_clks_per_ms)-1) then
+          clk_cnt <= (others => '0');
+        end if;
+      end if;
+    end if;
+  end process;
+
+  --sample tick
+  tick <= '1' when (clk_cnt = g_clks_per_ms-1) else '0';
+
+  p_smpl_sm: process(clk_sys_i) is 
+  begin 
+    if rising_edge(clk_sys_i) then 
+      if (rst_sys_n_i = '0') then 
+        irig_smpl_state <= S_IDLE;
+      else 
+
+        irig_data <= '0';
+        d_valid   <= '0';
+        marker    <= '0';
+        smpl_err  <= '0';
+
+        case irig_smpl_state is
+
+          when S_IDLE =>  high_cnt <= (others => '0');
+                          if(tick = '1') then 
+                            if(d_synced = '1') then 
+                              high_cnt <= high_cnt+1;
+                              irig_smpl_state <= S_SMPL;
+                            end if;
+                          end if;
+
+          when S_SMPL =>  if(tick = '1') then 
+                            if(d_synced = '1') then
+                              high_cnt <= high_cnt+1;
+                            else
+                              irig_smpl_state <= S_IDLE;
+                              if(high_cnt = c_HIGH_MS) then
+                                irig_data <= '1';
+                                d_valid   <= '1';
+                              elsif(high_cnt = c_LOW_MS) then
+                                irig_data <= '0';
+                                d_valid   <= '1';
+                              elsif(high_cnt = c_MARKER_MS) then
+                                marker    <= '1';
+                              else
+                                smpl_err <= '1';  --something gone wrong
+                              end if;
+                            end if;
+                          end if;
+
+          when others => irig_smpl_state <= S_IDLE;
+
+        end case;
+      end if;
+    end if;
+  end process;
+
+  p_sof_detect: process(clk_sys_i) is
+  begin
+    if rising_edge(clk_sys_i) then
+      if(rst_sys_n_i = '0') then
+        frame_sof_state <= S_IDLE;
+      else
+
+        sof <= '0';
+
+        case frame_sof_state is
+
+          when S_IDLE => if(marker = '1') then
+                            frame_sof_state <= S_CHECKSOF;
+                         end if;
+
+          when S_CHECKSOF   =>  if(d_valid = '1' or smpl_err = '1') then
+                                  frame_sof_state <= S_IDLE;
+                                elsif(marker = '1') then  --got 2 markers in a row
+                                  sof <= '1';
+                                  frame_sof_state <= S_IDLE;
+                                end if;
+
+          when others => frame_sof_state <= S_IDLE;
+
+        end case;
+      end if;
+    end if;
+  end process;
+
+  --counter synced to sof
+  p_tick_cnt: process(clk_sys_i) is
+  begin
+    if rising_edge(clk_sys_i) then
+      if (rst_sys_n_i = '0' or sof = '1') then
+        tick_cnt <= (others => '0');
+      else
+          if(tick = '1') then
+            tick_cnt <= tick_cnt + 1;
+          end if;
+        end if;
+    end if;
+  end process;
+
+  --check got sof when expected, used to generate valid and gate pps
+  p_sync_gen: process(clk_sys_i) is
+  begin
+    if rising_edge(clk_sys_i) then
+      if(rst_sys_n_i = '0') then
+        synced <= '0';
+      else
+        if (tick_cnt >= c_TICK_CNT_FRAME) then
+          synced <= '0';
+          if(sof = '1') then
+            synced <= '1';
+          end if;
+        end if;
+      end if;
+    end if;
+  end process;
+
+  --parse the frame
+  p_frame_sm: process(clk_sys_i) is 
+  begin
+    if rising_edge(clk_sys_i) then 
+      if(rst_sys_n_i = '0') then 
+        field <= (others => (others => '0'));
+        irig_frame_state <= S_IDLE;
+      else
+
+        field_valid <= '0';
+
+        case irig_frame_state is
+
+          when S_IDLE =>  field_cnt <= (others => '0');
+                          if(sof = '1') then
+                            irig_frame_state <= S_PARSE8B;  --first field (seconds) is 8 bits, others are 9
+                          end if;
+
+          when S_PARSE8B => if(tick = '1') then
+                              if (bit_count >= 8) then
+                                irig_frame_state <= S_WAITMARKER;
+                              end if;
+                            end if;
+
+          when S_WAITMARKER =>  if(marker = '1') then
+                                  irig_frame_state <= S_PARSE9B;
+                                  field(to_integer(field_cnt)) <= sreg;
+                                  field_cnt <= field_cnt + 1;
+                                  if(field_cnt >= c_NUM_FIELDS-1) then
+                                    irig_frame_state <= S_IDLE;
+                                    field_valid <= '1';
+                                  end if;
+                                elsif(smpl_err = '1') then
+                                    irig_frame_state <= S_IDLE;
+                                end if;
+
+          when S_PARSE9B => if(tick = '1') then
+                              if (bit_count >= 9) then
+                                irig_frame_state <= S_WAITMARKER;
+                              end if;
+                            end if;
+
+          when others => irig_frame_state <= S_IDLE;
+
+        end case;
+      end if;
+    end if;
+  end process;
+
+  --generate pps on first edge of p0 marker
+  pps_o <= d_rising when tick_cnt = c_TICK_CNT_PREF and synced = '1' else '0';
+
+  p_bit_count: process(clk_sys_i) is 
+  begin 
+    if rising_edge(clk_sys_i) then
+      if(rst_sys_n_i='0' or marker='1') then
+        bit_count <= (others => '0');
+      elsif (d_valid = '1') then
+        bit_count <= bit_count+1;
+      end if;      
+    end if;
+  end process;
+
+  p_shift_reg: process(clk_sys_i) is
+  begin 
+    if rising_edge(clk_sys_i) then 
+      if (marker = '1') then
+        sreg <= (others => '0');
+      elsif (d_valid = '1') then
+        sreg <= irig_data & sreg(sreg'length-1 downto 1);
+      end if;        
+    end if;
+  end process;
+
+  p_outputs: process(clk_sys_i) is
+  begin
+    if rising_edge(clk_sys_i) then
+      if(rst_sys_n_i = '0') then
+        secs_o  <= (others => '0');
+        mins_o  <= (others => '0');
+        hrs_o   <= (others => '0');
+        days_o  <= (others => '0');
+        year_o  <= (others => '0');
+        ctrl0_o <= (others => '0');
+        ctrl1_o <= (others => '0');
+        sbs_o   <= (others => '0');
+      else
+        if(field_valid = '1') then
+          secs_o  <= field(0)(8 downto 1);
+          mins_o  <= field(1);
+          hrs_o   <= field(2);
+          days_o  <= field(4)(1 downto 0) & field(3);
+          year_o  <= field(5);
+          ctrl0_o <= field(6);
+          ctrl1_o <= field(7);
+          sbs_o   <= field(9) & field(8);
+        end if;
+      end if;
+    end if;
+  end process;
+
+  valid_o <= synced;
+
+end architecture;
diff --git a/modules/wr_irig/xwr_irig_slave.vhd b/modules/wr_irig/xwr_irig_slave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..45abc065873385ff01f9b147899f32ec2072f184
--- /dev/null
+++ b/modules/wr_irig/xwr_irig_slave.vhd
@@ -0,0 +1,186 @@
+-------------------------------------------------------------------------------
+-- Title      : WR Switch IRIG slave module
+-- Project    : White Rabbit Switch
+-------------------------------------------------------------------------------
+-- File       : xwr_irig_slave.vhd
+-- Author     : Harvey Leicester
+-- Company    : CERN BE-CEM-EDL
+-- Created    : 2024-10-23
+-- Last update: 2024-10-23
+-- Platform   : FPGA-generic
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- IRIG-B004 slave interface wrapper
+-------------------------------------------------------------------------------
+--
+-- Copyright (c) 2012 - 2024 CERN / BE-CEM-EDL
+--
+-- This source file is free software; you can redistribute it
+-- and/or modify it under the terms of the GNU Lesser General
+-- Public License as published by the Free Software Foundation;
+-- either version 2.1 of the License, or (at your option) any
+-- later version.
+--
+-- This source is distributed in the hope that it will be
+-- useful, but WITHOUT ANY WARRANTY; without even the implied
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+-- PURPOSE.  See the GNU Lesser General Public License for more
+-- details.
+--
+-- You should have received a copy of the GNU Lesser General
+-- Public License along with this source; if not, download it
+-- from http://www.gnu.org/licenses/lgpl-2.1.html
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.wishbone_pkg.all;
+use work.gencores_pkg.all;
+use work.irig_slave_regs_pkg.all;
+
+entity xwr_irig_slave is
+  generic
+  (
+    g_interface_mode      : t_wishbone_interface_mode      := PIPELINED;
+    g_address_granularity : t_wishbone_address_granularity := BYTE;
+    g_clks_per_ms         : integer := 62500
+  );
+  port
+  (
+    clk_i   : in std_logic;
+    rst_n_i : in std_logic;
+
+    irig_i    : in std_logic;
+    pps_o     : out std_logic;
+    enable_o  : out std_logic;  --enable flag out, used for muxing pps in top level
+
+    wb_i : in  t_wishbone_slave_in;
+    wb_o : out t_wishbone_slave_out
+  );
+end entity xwr_irig_slave;
+
+architecture wrapper of xwr_irig_slave is
+
+  component wr_irig_slave
+    generic (
+      g_clks_per_ms : integer := 62500
+    );
+    port (
+      clk_sys_i     : in std_logic;  --sys clock
+      rst_sys_n_i   : in std_logic;  --sys rst
+      irig_i        : in std_logic;  --irig data in
+
+      secs_o        : out std_logic_vector(7 downto 0);  --seconds out, 0-59
+      mins_o        : out std_logic_vector(8 downto 0);  --minutes out, 0-59
+      hrs_o         : out std_logic_vector(8 downto 0);  --hours out, 0-23
+      days_o        : out std_logic_vector(10 downto 0); --day of year, 1-366
+      year_o        : out std_logic_vector(8 downto 0);  --year, 0-99
+      ctrl0_o       : out std_logic_vector(8 downto 0);  --control function 0
+      ctrl1_o       : out std_logic_vector(8 downto 0);  --contorl function 1
+      sbs_o         : out std_logic_vector(17 downto 0); --straight binary seconds
+      valid_o       : out std_logic;                     --output valid
+      pps_o         : out std_logic  --pps out, generated from start of irig frame
+    );
+  end component;
+
+  signal wb_in : t_wishbone_slave_in;
+  signal wb_out : t_wishbone_slave_out;
+  signal irig_regs_in : t_irig_regs_master_in;
+  signal irig_regs_out : t_irig_regs_master_out;
+
+  signal secs : std_logic_vector(7 downto 0);
+  signal mins : std_logic_vector(8 downto 0);
+  signal hrs  : std_logic_vector(8 downto 0);
+  signal days : std_logic_vector(10 downto 0);
+  signal tos  : std_logic_vector(3 downto 0);
+  signal yrs  : std_logic_vector(8 downto 0);
+  signal ctrl0 : std_logic_vector(8 downto 0);
+  signal ctrl1 : std_logic_vector(8 downto 0);
+  signal sbs   : std_logic_vector(17 downto 0);
+  signal valid : std_logic;
+
+begin
+
+  U_Adapter : wb_slave_adapter
+  generic map
+  (
+    g_master_use_struct  => true,
+    g_master_mode        => CLASSIC,
+    g_master_granularity => WORD,
+    g_slave_use_struct   => true,
+    g_slave_mode         => g_interface_mode,
+    g_slave_granularity  => g_address_granularity
+  )
+  port map
+  (
+    clk_sys_i => clk_i,
+    rst_n_i   => rst_n_i,
+    slave_i   => wb_i,
+    slave_o   => wb_o,
+    master_i  => wb_out,
+    master_o  => wb_in
+  );
+
+  U_irig_slave_regs: entity work.irig_slave_regs
+  port map
+  (
+    rst_n_i => rst_n_i,
+    clk_i   => clk_i,
+    wb_cyc_i  => wb_in.cyc,
+    wb_stb_i  => wb_in.stb,
+    wb_adr_i  => wb_in.adr(2 downto 0),
+    wb_sel_i  => wb_in.sel,
+    wb_we_i   => wb_in.we,
+    wb_dat_i  => wb_in.dat,
+    wb_ack_o  => wb_out.ack,
+    wb_err_o  => wb_out.err,
+    wb_rty_o  => wb_out.rty,
+    wb_stall_o   => wb_out.stall,
+    wb_dat_o     => wb_out.dat,
+    irig_regs_i => irig_regs_in
+  );
+
+  U_irig_slave: wr_irig_slave
+  generic map
+  (
+    g_clks_per_ms => g_clks_per_ms
+  )
+  port map
+  (
+    clk_sys_i   => clk_i,
+    rst_sys_n_i => rst_n_i,
+    irig_i      => irig_i,
+
+    secs_o  => secs,
+    mins_o  => mins,
+    hrs_o   => hrs,
+    days_o  => days,
+    year_o  => yrs,
+    ctrl0_o => ctrl0,
+    ctrl1_o => ctrl1,
+    sbs_o   => sbs,
+    valid_o => valid,
+    pps_o   => pps_o
+  );
+
+  irig_regs_in.TOD_seconds    <= secs;
+  irig_regs_in.TOD_minutes    <= mins;
+  irig_regs_in.TOD_hours      <= hrs;
+  irig_regs_in.TOD_valid      <= valid;
+  irig_regs_in.DATE_days      <= days;
+  irig_regs_in.DATE_years     <= yrs;
+  irig_regs_in.DATE_valid     <= valid;
+  irig_regs_in.CTRL_fcn0      <= ctrl0;
+  irig_regs_in.CTRL_fcn1      <= ctrl1;
+  irig_regs_in.CTRL_valid     <= valid;
+  irig_regs_in.SBS_sbs        <= sbs;
+  irig_regs_in.SBS_valid      <= valid;
+
+  enable_o <= irig_regs_out.CR_enable;
+
+end architecture;
+