diff --git a/modules/common/Manifest.py b/modules/common/Manifest.py
index ccf1c82b0c17a7dc93a6347b4d2e7b41a85bb8c1..9c368339be646ecb8a36828bb66039ddb20e89d2 100644
--- a/modules/common/Manifest.py
+++ b/modules/common/Manifest.py
@@ -32,4 +32,5 @@ files = [
     "gc_dyn_extend_pulse.vhd",
     "gc_ds182x_interface.vhd",
     "gc_ds182x_readout.vhd",
+    "gc_sfp_i2c_adapter.vhd",
 ];
diff --git a/modules/common/gc_sfp_i2c_adapter.vhd b/modules/common/gc_sfp_i2c_adapter.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..3c4a3086e76c313d0d9d882e4c372d96b0ae0cdd
--- /dev/null
+++ b/modules/common/gc_sfp_i2c_adapter.vhd
@@ -0,0 +1,159 @@
+--------------------------------------------------------------------------------
+-- CERN BE-CO-HT
+-- General Cores Library
+-- https://www.ohwr.org/projects/general-cores
+--------------------------------------------------------------------------------
+--
+-- unit name:   gc_sfp_i2c_adapter
+--
+-- description: A simple I2C adapter that emulates the SFP DDM and provides
+-- access to the vendor id. Useful for when the SFP is not directly accessible
+-- over I2C.
+--
+--------------------------------------------------------------------------------
+-- Copyright CERN 2016-2019
+--------------------------------------------------------------------------------
+-- Copyright and related rights are licensed under the Solderpad Hardware
+-- License, Version 2.0 (the "License"); you may not use this file except
+-- in compliance with the License. You may obtain a copy of the License at
+-- http://solderpad.org/licenses/SHL-2.0.
+-- Unless required by applicable law or agreed to in writing, software,
+-- hardware and materials distributed under this License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+-- or implied. See the License for the specific language governing permissions
+-- and limitations under the License.
+--------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.gencores_pkg.all;
+
+entity gc_sfp_i2c_adapter is
+  port (
+
+    -- Clock, reset ports
+    clk_i   : in std_logic;
+    rst_n_i : in std_logic;
+
+    -- I2C lines
+    scl_i    : in  std_logic;
+    sda_i    : in  std_logic;
+    sda_en_o : out std_logic;
+
+    -- HIGH if both of the following are true:
+    -- 1. SFP is detected (plugged in)
+    -- 2. The part number has been successfully read after the SFP detection
+    sfp_det_valid_i : in std_logic;
+    -- 16 byte vendor Part Number (PN)
+    -- (ASCII encoded, first character byte in bits 127 downto 120)
+    sfp_data_i      : in std_logic_vector (127 downto 0)
+    );
+end entity gc_sfp_i2c_adapter;
+
+architecture rtl of gc_sfp_i2c_adapter is
+
+  -----------------------------------------------------------------------------
+  -- Types
+  -----------------------------------------------------------------------------
+
+  -- 64-byte array representing the DDM serial ID area of the SFP management
+  type t_sfp_ddm_serial_id is array (0 to 63) of std_logic_vector(7 downto 0);
+
+  -----------------------------------------------------------------------------
+  -- Signals
+  -----------------------------------------------------------------------------
+
+  signal sfp_i2c_tx_byte : std_logic_vector(7 downto 0);
+  signal sfp_i2c_rx_byte : std_logic_vector(7 downto 0);
+  signal sfp_i2c_r_done  : std_logic;
+  signal sfp_i2c_w_done  : std_logic;
+  signal sfp_ddm_din     : t_sfp_ddm_serial_id := (others => (others => '0'));
+  signal sfp_ddm_reg     : t_sfp_ddm_serial_id := (others => (others => '0'));
+  signal sfp_ddm_addr    : unsigned(5 downto 0);
+  signal sfp_ddm_sum     : unsigned(7 downto 0);
+
+begin  -- architecture rtl
+
+  cmp_gc_i2c_slave : gc_i2c_slave
+    generic map (
+      g_auto_addr_ack => TRUE)
+    port map (
+      clk_i         => clk_i,
+      rst_n_i       => rst_n_i,
+      scl_i         => scl_i,
+      -- clock streching not implemented by module
+      scl_o         => open,
+      scl_en_o      => open,
+      sda_i         => sda_i,
+      -- sda_o is not necessary, sda_en has all the info that we need
+      sda_o         => open,
+      sda_en_o      => sda_en_o,
+      -- standard SFP management I2C address
+      i2c_addr_i    => "1010000",
+      -- no need to ACK, we use auto address ACK
+      -- and only use one byte writes
+      ack_i         => '0',
+      tx_byte_i     => sfp_i2c_tx_byte,
+      rx_byte_o     => sfp_i2c_rx_byte,
+      -- we only care about r_done (new address)
+      -- and w_done (load next byte from serial_id)
+      i2c_sta_p_o   => open,
+      i2c_sto_p_o   => open,
+      addr_good_p_o => open,
+      r_done_p_o    => sfp_i2c_r_done,
+      w_done_p_o    => sfp_i2c_w_done,
+      op_o          => open);
+
+  -- Populate the sfp_ddm Vendor PN using the sfp_data_i input
+  gen_sfp_ddm_data : for i in 0 to 15 generate
+    sfp_ddm_din(40+i) <= sfp_data_i(127-i*8 downto 120-i*8);
+  end generate gen_sfp_ddm_data;
+
+  -- Calculate CC_BASE for the last byte of the sfp_ddm.
+  -- We only sum the 16 bytes, all other bytes are zero anyway.
+  sfp_ddm_sum <=
+    (((unsigned(sfp_data_i(127 downto 120)) + unsigned(sfp_data_i(119 downto 112))) +
+      (unsigned(sfp_data_i(111 downto 104)) + unsigned(sfp_data_i(103 downto 96)))) +
+     ((unsigned(sfp_data_i(95 downto 88)) + unsigned(sfp_data_i(87 downto 80))) +
+      (unsigned(sfp_data_i(79 downto 72)) + unsigned(sfp_data_i(71 downto 64))))) +
+    (((unsigned(sfp_data_i(63 downto 56)) + unsigned(sfp_data_i(55 downto 48))) +
+      (unsigned(sfp_data_i(47 downto 40)) + unsigned(sfp_data_i(39 downto 32)))) +
+     ((unsigned(sfp_data_i(31 downto 24)) + unsigned(sfp_data_i(23 downto 16))) +
+      (unsigned(sfp_data_i(15 downto 8)) + unsigned(sfp_data_i(7 downto 0)))));
+
+  sfp_ddm_din(63) <= std_logic_vector(sfp_ddm_sum);
+
+  -- always offer to send the next byte pointed to by the address counter
+  sfp_i2c_tx_byte <= sfp_ddm_reg(to_integer(sfp_ddm_addr));
+
+  -- Drive the SFP DDM based on the r_done/w_done pulses
+  p_sfp_ddm_addr_counter : process (clk_i) is
+  begin
+    if rising_edge(clk_i) then
+      if rst_n_i = '0' then
+        sfp_ddm_addr <= (others => '0');
+        sfp_ddm_reg  <= (others => (others => '0'));
+      else
+        -- check valid flag to load DDM register
+        if sfp_det_valid_i = '1' then
+          sfp_ddm_reg <= sfp_ddm_din;
+        else
+          sfp_ddm_reg <= (others => (others => '0'));
+        end if;
+
+        if sfp_i2c_r_done = '1' then
+          -- update address pointer with new value
+          sfp_ddm_addr <= unsigned(sfp_i2c_rx_byte(5 downto 0));
+        elsif sfp_i2c_w_done = '1' then
+          -- increase address pointer
+          sfp_ddm_addr <= sfp_ddm_addr + 1;
+        end if;
+      end if;
+    end if;
+  end process p_sfp_ddm_addr_counter;
+
+
+end architecture rtl;
diff --git a/modules/common/gencores_pkg.vhd b/modules/common/gencores_pkg.vhd
index ce52e7d9d68273227d0d3734d5dcd7684a3d7a73..e5b0027c88c6f033ef974489650c73d77dbfe4db 100644
--- a/modules/common/gencores_pkg.vhd
+++ b/modules/common/gencores_pkg.vhd
@@ -608,6 +608,21 @@ package gencores_pkg is
       id_ok_o   : out   std_logic);
   end component gc_ds182x_readout;
 
+  ------------------------------------------------------------------------------
+  -- SFP I2C Adapter
+  ------------------------------------------------------------------------------
+
+  component gc_sfp_i2c_adapter is
+    port (
+      clk_i           : in  std_logic;
+      rst_n_i         : in  std_logic;
+      scl_i           : in  std_logic;
+      sda_i           : in  std_logic;
+      sda_en_o        : out std_logic;
+      sfp_det_valid_i : in  std_logic;
+      sfp_data_i      : in  std_logic_vector (127 downto 0));
+  end component gc_sfp_i2c_adapter;
+
   --============================================================================
   -- Procedures and functions
   --============================================================================
diff --git a/modules/genrams/common/inferred_async_fifo.vhd b/modules/genrams/common/inferred_async_fifo.vhd
index 8b1ba6310afc294fb6dd21a92485ee5264f256da..949661680bab602c431b9c18c340ed5919f9a95a 100644
--- a/modules/genrams/common/inferred_async_fifo.vhd
+++ b/modules/genrams/common/inferred_async_fifo.vhd
@@ -37,20 +37,20 @@ entity inferred_async_fifo is
   generic (
     g_data_width : natural;
     g_size       : natural;
-    g_show_ahead : boolean := false;
+    g_show_ahead : boolean := FALSE;
 
     -- Read-side flag selection
-    g_with_rd_empty        : boolean := true;   -- with empty flag
-    g_with_rd_full         : boolean := false;  -- with full flag
-    g_with_rd_almost_empty : boolean := false;
-    g_with_rd_almost_full  : boolean := false;
-    g_with_rd_count        : boolean := false;  -- with words counter
-
-    g_with_wr_empty        : boolean := false;
-    g_with_wr_full         : boolean := true;
-    g_with_wr_almost_empty : boolean := false;
-    g_with_wr_almost_full  : boolean := false;
-    g_with_wr_count        : boolean := false;
+    g_with_rd_empty        : boolean := TRUE;   -- with empty flag
+    g_with_rd_full         : boolean := FALSE;  -- with full flag
+    g_with_rd_almost_empty : boolean := FALSE;
+    g_with_rd_almost_full  : boolean := FALSE;
+    g_with_rd_count        : boolean := FALSE;  -- with words counter
+
+    g_with_wr_empty        : boolean := FALSE;
+    g_with_wr_full         : boolean := TRUE;
+    g_with_wr_almost_empty : boolean := FALSE;
+    g_with_wr_almost_full  : boolean := FALSE;
+    g_with_wr_count        : boolean := FALSE;
 
     g_almost_empty_threshold : integer;  -- threshold for almost empty flag
     g_almost_full_threshold  : integer   -- threshold for almost full flag
@@ -67,7 +67,7 @@ entity inferred_async_fifo is
 
     wr_empty_o        : out std_logic;
     wr_full_o         : out std_logic;
-    wr_almost_empty_o : out std_logic; -- TODO: assign
+    wr_almost_empty_o : out std_logic;
     wr_almost_full_o  : out std_logic;
     wr_count_o        : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
 
@@ -79,7 +79,7 @@ entity inferred_async_fifo is
     rd_empty_o        : out std_logic;
     rd_full_o         : out std_logic;
     rd_almost_empty_o : out std_logic;
-    rd_almost_full_o  : out std_logic; -- TODO: assign
+    rd_almost_full_o  : out std_logic;
     rd_count_o        : out std_logic_vector(f_log2_size(g_size)-1 downto 0)
     );
 
@@ -88,50 +88,49 @@ end inferred_async_fifo;
 
 architecture syn of inferred_async_fifo is
 
-  function f_bin2gray(bin : std_logic_vector) return std_logic_vector is
-  begin
-    return bin(bin'left) & (bin(bin'left-1 downto 0) xor bin(bin'left downto 1));
-  end f_bin2gray;
-
-  function f_gray2bin(gray : std_logic_vector) return std_logic_vector is
-    variable bin : std_logic_vector(gray'left downto 0);
-  begin
-    -- gray to binary
-    for i in 0 to gray'left loop
-      bin(i) := '0';
-      for j in i to gray'left loop
-        bin(i) := bin(i) xor gray(j);
-      end loop;  -- j
-    end loop;  -- i
-    return bin;
-  end f_gray2bin;
-
+  -- We use one more bit to be able to differentiate between an empty FIFO
+  -- (where rcb = wcb) and a full FIFO (where rcb = wcb except from the most
+  -- significant extra bit).
+  -- This extra bit is not used of course for actual addressing of the memory.
   constant c_counter_bits : integer := f_log2_size(g_size) + 1;
+
   subtype t_counter is std_logic_vector(c_counter_bits-1 downto 0);
 
+  -- bin: binary counter
+  -- bin_next: bin + 1
+  -- bin_x: cross-clock domain version of bin
+  -- gray: gray code of bin
+  -- gray_next: gray code of bin_next
+  -- gray_x: gray code of bin_x
+  --
+  -- We use gray codes for safe cross-clock domain crossing of counters. Thus,
+  -- a binary counter is converted to gray before crossing, and then it is
+  -- converted back to binary after crossing.
   type t_counter_block is record
-    bin, bin_next, gray, gray_next : t_counter;
-    bin_x, gray_x, gray_xm         : t_counter;
+    bin, bin_next   : t_counter;
+    gray, gray_next : t_counter;
+    bin_x, gray_x   : t_counter;
   end record;
 
-  type   t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
-  signal mem : t_mem_type;
+  type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
+  signal mem : t_mem_type := (others => (others => '0'));
+
+  signal rcb, wcb : t_counter_block;
 
-  signal rcb, wcb                          : t_counter_block;
+  signal rd_ptr_muxed : t_counter;
 
-  
   signal full_int, empty_int               : std_logic;
   signal almost_full_int, almost_empty_int : std_logic;
   signal going_full                        : std_logic;
 
   signal wr_count, rd_count : t_counter;
-  signal rd_int, we_int : std_logic;
+  signal rd_int, we_int     : std_logic;
 
-  signal wr_empty_xm, wr_empty_x : std_logic;
-  signal rd_full_xm, rd_full_x   : std_logic;
+  signal wr_empty_x : std_logic;
+  signal rd_full_x  : std_logic;
 
-  signal almost_full_x, almost_full_xm   : std_logic;
-  signal almost_empty_x, almost_empty_xm : std_logic;
+  signal almost_full_x  : std_logic;
+  signal almost_empty_x : std_logic;
 
   signal q_int : std_logic_vector(g_data_width-1 downto 0) := (others => '0');
 
@@ -140,28 +139,37 @@ begin  -- syn
   rd_int <= rd_i and not empty_int;
   we_int <= we_i and not full_int;
 
+  p_rd_ptr_mux : process(rcb, rd_int)
+  begin
+    if(rd_int = '1' and g_show_ahead) then
+      rd_ptr_muxed <= rcb.bin_next;
+    elsif((rd_int = '1' and not g_show_ahead) or (g_show_ahead)) then
+      rd_ptr_muxed <= rcb.bin;
+    end if;
+  end process p_rd_ptr_mux;
+
   p_mem_write : process(clk_wr_i)
   begin
     if rising_edge(clk_wr_i) then
       if(we_int = '1') then
-        mem(to_integer(unsigned(wcb.bin(wcb.bin'left-1 downto 0)))) <= d_i;
+        mem(to_integer(unsigned(wcb.bin(wcb.bin'LEFT-1 downto 0)))) <= d_i;
       end if;
     end if;
-  end process;
+  end process p_mem_write;
 
   p_mem_read : process(clk_rd_i)
   begin
     if rising_edge(clk_rd_i) then
-      if(rd_int = '1') then
-        q_int <= mem(to_integer(unsigned(rcb.bin(rcb.bin'left-1 downto 0))));
+      if(rd_int = '1' or g_show_ahead) then
+        q_int <= mem(to_integer(unsigned(rd_ptr_muxed(rd_ptr_muxed'LEFT-1 downto 0))));
       end if;
     end if;
-  end process;
+  end process p_mem_read;
 
   q_o <= q_int;
 
   wcb.bin_next  <= std_logic_vector(unsigned(wcb.bin) + 1);
-  wcb.gray_next <= f_bin2gray(wcb.bin_next);
+  wcb.gray_next <= f_gray_encode(wcb.bin_next);
 
   p_write_ptr : process(clk_wr_i, rst_n_i)
   begin
@@ -174,10 +182,10 @@ begin  -- syn
         wcb.gray <= wcb.gray_next;
       end if;
     end if;
-  end process;
+  end process p_write_ptr;
 
   rcb.bin_next  <= std_logic_vector(unsigned(rcb.bin) + 1);
-  rcb.gray_next <= f_bin2gray(rcb.bin_next);
+  rcb.gray_next <= f_gray_encode(rcb.bin_next);
 
   p_read_ptr : process(clk_rd_i, rst_n_i)
   begin
@@ -190,28 +198,28 @@ begin  -- syn
         rcb.gray <= rcb.gray_next;
       end if;
     end if;
-  end process;
+  end process p_read_ptr;
 
-    U_Sync1: gc_sync_register
+  U_Sync1 : gc_sync_register
     generic map (
       g_width => c_counter_bits)
     port map (
-      clk_i    => clk_wr_i,
-      rst_n_a_i  => rst_n_i,
-      d_i  => rcb.gray,
-      q_o => rcb.gray_x);
+      clk_i     => clk_wr_i,
+      rst_n_a_i => rst_n_i,
+      d_i       => rcb.gray,
+      q_o       => rcb.gray_x);
 
-    U_Sync2: gc_sync_register
+  U_Sync2 : gc_sync_register
     generic map (
       g_width => c_counter_bits)
     port map (
-      clk_i    => clk_rd_i,
-      rst_n_a_i  => rst_n_i,
-      d_i   => wcb.gray,
-      q_o => wcb.gray_x);
+      clk_i     => clk_rd_i,
+      rst_n_a_i => rst_n_i,
+      d_i       => wcb.gray,
+      q_o       => wcb.gray_x);
 
-  wcb.bin_x <= f_gray2bin(wcb.gray_x);
-  rcb.bin_x <= f_gray2bin(rcb.gray_x);
+  wcb.bin_x <= f_gray_decode(wcb.gray_x, 1);
+  rcb.bin_x <= f_gray_decode(rcb.gray_x, 1);
 
   p_gen_empty : process(clk_rd_i, rst_n_i)
   begin
@@ -224,9 +232,9 @@ begin  -- syn
         empty_int <= '0';
       end if;
     end if;
-  end process;
+  end process p_gen_empty;
 
-  U_Sync_Empty: gc_sync_ffs
+  U_Sync_Empty : gc_sync_ffs
     generic map (
       g_sync_edge => "positive")
     port map (
@@ -235,7 +243,7 @@ begin  -- syn
       data_i   => empty_int,
       synced_o => wr_empty_x);
 
-  U_Sync_Full: gc_sync_ffs
+  U_Sync_Full : gc_sync_ffs
     generic map (
       g_sync_edge => "positive")
     port map (
@@ -243,25 +251,23 @@ begin  -- syn
       rst_n_i  => rst_n_i,
       data_i   => full_int,
       synced_o => rd_full_x);
- 
-  
 
   rd_empty_o <= empty_int;
   wr_empty_o <= wr_empty_x;
 
   p_gen_going_full : process(we_int, wcb, rcb)
   begin
-    if ((wcb.bin (wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0))
-        and (wcb.bin(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then
+    if ((wcb.bin (wcb.bin'LEFT-1 downto 0) = rcb.bin_x(rcb.bin_x'LEFT-1 downto 0))
+        and (wcb.bin(wcb.bin'LEFT) /= rcb.bin_x(rcb.bin_x'LEFT))) then
       going_full <= '1';
     elsif (we_int = '1'
-           and (wcb.bin_next(wcb.bin'left-1 downto 0) = rcb.bin_x(rcb.bin_x'left-1 downto 0))
-           and (wcb.bin_next(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then
+           and (wcb.bin_next(wcb.bin'LEFT-1 downto 0) = rcb.bin_x(rcb.bin_x'LEFT-1 downto 0))
+           and (wcb.bin_next(wcb.bin'LEFT) /= rcb.bin_x(rcb.bin_x'LEFT))) then
       going_full <= '1';
     else
       going_full <= '0';
     end if;
-  end process;
+  end process p_gen_going_full;
 
   p_register_full : process(clk_wr_i, rst_n_i)
   begin
@@ -270,7 +276,7 @@ begin  -- syn
     elsif rising_edge (clk_wr_i) then
       full_int <= going_full;
     end if;
-  end process;
+  end process p_register_full;
 
   wr_full_o <= full_int;
   rd_full_o <= rd_full_x;
@@ -287,9 +293,9 @@ begin  -- syn
         almost_full_int <= '0';
       end if;
     end if;
-  end process;
+  end process p_reg_almost_full;
 
-  U_Sync_AlmostFull: gc_sync_ffs
+  U_Sync_AlmostFull : gc_sync_ffs
     generic map (
       g_sync_edge => "positive")
     port map (
@@ -298,24 +304,24 @@ begin  -- syn
       data_i   => almost_full_int,
       synced_o => almost_full_x);
 
-  wr_almost_full_o  <= almost_full_int;
-  rd_almost_full_o  <= almost_full_x;
+  wr_almost_full_o <= almost_full_int;
+  rd_almost_full_o <= almost_full_x;
 
   p_reg_almost_empty : process(clk_rd_i, rst_n_i)
   begin
     if rst_n_i = '0' then
       almost_empty_int <= '1';
     elsif rising_edge(clk_rd_i) then
-      rd_count     <= std_logic_vector(unsigned(wcb.bin_x) - unsigned(rcb.bin));
+      rd_count               <= std_logic_vector(unsigned(wcb.bin_x) - unsigned(rcb.bin));
       if (unsigned(rd_count) <= g_almost_empty_threshold) then
         almost_empty_int <= '1';
       else
         almost_empty_int <= '0';
       end if;
     end if;
-  end process;
+  end process p_reg_almost_empty;
 
-  U_Sync_AlmostEmpty: gc_sync_ffs
+  U_Sync_AlmostEmpty : gc_sync_ffs
     generic map (
       g_sync_edge => "positive")
     port map (
diff --git a/modules/genrams/common/inferred_async_fifo_dual_rst.vhd b/modules/genrams/common/inferred_async_fifo_dual_rst.vhd
index 0cb8657f90fa889f73a06b3a0d3e0385157ec02d..be6b94d4deac3f5e6618c0976b916925c973e759 100644
--- a/modules/genrams/common/inferred_async_fifo_dual_rst.vhd
+++ b/modules/genrams/common/inferred_async_fifo_dual_rst.vhd
@@ -77,21 +77,37 @@ entity inferred_async_fifo_dual_rst is
 end inferred_async_fifo_dual_rst;
 
 
-architecture syn of inferred_async_fifo_dual_rst is
+architecture arch of inferred_async_fifo_dual_rst is
 
+  -- We use one more bit to be able to differentiate between an empty FIFO
+  -- (where rcb = wcb) and a full FIFO (where rcb = wcb except from the most
+  -- significant extra bit).
+  -- This extra bit is not used of course for actual addressing of the memory.
   constant c_counter_bits : integer := f_log2_size(g_size) + 1;
   subtype t_counter is std_logic_vector(c_counter_bits-1 downto 0);
 
+  -- bin: binary counter
+  -- bin_next: bin + 1
+  -- bin_x: cross-clock domain version of bin
+  -- gray: gray code of bin
+  -- gray_next: gray code of bin_next
+  -- gray_x: gray code of bin_x
+  --
+  -- We use gray codes for safe cross-clock domain crossing of counters. Thus,
+  -- a binary counter is converted to gray before crossing, and then it is
+  -- converted back to binary after crossing.
   type t_counter_block is record
-    bin, bin_next, gray, gray_next : t_counter;
-    bin_x, gray_x, gray_xm         : t_counter;
+    bin, bin_next   : t_counter;
+    gray, gray_next : t_counter;
+    bin_x, gray_x   : t_counter;
   end record;
 
   type t_mem_type is array (0 to g_size-1) of std_logic_vector(g_data_width-1 downto 0);
-  signal mem : t_mem_type;
+  signal mem : t_mem_type := (others => (others => '0'));
 
   signal rcb, wcb : t_counter_block;
 
+  signal rd_ptr_muxed : t_counter;
 
   signal full_int, empty_int               : std_logic;
   signal almost_full_int, almost_empty_int : std_logic;
@@ -100,19 +116,28 @@ architecture syn of inferred_async_fifo_dual_rst is
   signal wr_count, rd_count : t_counter;
   signal rd_int, we_int     : std_logic;
 
-  signal wr_empty_xm, wr_empty_x : std_logic;
-  signal rd_full_xm, rd_full_x   : std_logic;
+  signal wr_empty_x : std_logic;
+  signal rd_full_x  : std_logic;
 
-  signal almost_full_x, almost_full_xm   : std_logic;
-  signal almost_empty_x, almost_empty_xm : std_logic;
+  signal almost_full_x  : std_logic;
+  signal almost_empty_x : std_logic;
 
   signal q_int : std_logic_vector(g_data_width-1 downto 0) := (others => '0');
 
-begin  -- syn
+begin  -- arch
 
   rd_int <= rd_i and not empty_int;
   we_int <= we_i and not full_int;
 
+  p_rd_ptr_mux : process(rcb, rd_int)
+  begin
+    if(rd_int = '1' and g_show_ahead) then
+      rd_ptr_muxed <= rcb.bin_next;
+    elsif((rd_int = '1' and not g_show_ahead) or (g_show_ahead)) then
+      rd_ptr_muxed <= rcb.bin;
+    end if;
+  end process p_rd_ptr_mux;
+
   p_mem_write : process(clk_wr_i)
   begin
     if rising_edge(clk_wr_i) then
@@ -125,8 +150,8 @@ begin  -- syn
   p_mem_read : process(clk_rd_i)
   begin
     if rising_edge(clk_rd_i) then
-      if rd_int = '1' then
-        q_int <= mem(to_integer(unsigned(rcb.bin(rcb.bin'LEFT-1 downto 0))));
+      if(rd_int = '1' or g_show_ahead) then
+        q_int <= mem(to_integer(unsigned(rd_ptr_muxed(rd_ptr_muxed'LEFT-1 downto 0))));
       end if;
     end if;
   end process p_mem_read;
@@ -307,4 +332,4 @@ begin  -- syn
   wr_count_o <= std_logic_vector(wr_count(f_log2_size(g_size)-1 downto 0));
   rd_count_o <= std_logic_vector(rd_count(f_log2_size(g_size)-1 downto 0));
 
-end syn;
+end arch;
diff --git a/modules/genrams/common/inferred_sync_fifo.vhd b/modules/genrams/common/inferred_sync_fifo.vhd
index ed7de11bbf0a6da78770e09f0468db3d62d808ce..45c59f704f2c68f09db9653c6d1cf26cb4d38443 100644
--- a/modules/genrams/common/inferred_sync_fifo.vhd
+++ b/modules/genrams/common/inferred_sync_fifo.vhd
@@ -81,12 +81,12 @@ architecture syn of inferred_sync_fifo is
   signal   guard_bit                               : std_logic;
 
   signal q_comb : std_logic_vector(g_data_width-1 downto 0);
-  
+
 begin  -- syn
 
   we_int <= we_i and not full;
   rd_int <= rd_i and not empty;
-  
+
   U_FIFO_Ram : generic_dpram
     generic map (
       g_data_width               => g_data_width,
@@ -104,7 +104,7 @@ begin  -- syn
       ab_i    => std_logic_vector(rd_ptr_muxed(c_pointer_width-1 downto 0)),
       qb_o    => q_comb);
 
-  process(rd_ptr, rd_i, rd_int)
+  p_rd_ptr_mux: process(rd_int, rd_ptr)
   begin
     if(rd_int = '1' and g_show_ahead) then
       rd_ptr_muxed <= rd_ptr + 1;
@@ -113,7 +113,7 @@ begin  -- syn
     else
       rd_ptr_muxed <= rd_ptr - 1;
     end if;
-  end process;
+  end process p_rd_ptr_mux;
 
   q_o <= q_comb;
 
@@ -173,7 +173,7 @@ begin  -- syn
     p_reg_flags : process(clk_i)
     begin
       if rising_edge(clk_i) then
-        
+
         if(rst_n_i = '0') then
           full  <= '0';
           empty <= '1';
@@ -190,7 +190,7 @@ begin  -- syn
             full <= '0';
           end if;
         end if;
-        
+
       end if;
     end process;
   end generate gen_registered_flags;
diff --git a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd
index 8ba53a2fdf4a859cb34161d9b55cc93376ee0ce8..cf77bb0a0846e1cbb1ec6c316b49b976719b7f97 100644
--- a/modules/wishbone/wb_crossbar/xwb_crossbar.vhd
+++ b/modules/wishbone/wb_crossbar/xwb_crossbar.vhd
@@ -55,7 +55,9 @@ entity xwb_crossbar is
     g_registered  : boolean := false;
     -- Address of the slaves connected
     g_address     : t_wishbone_address_array;
-    g_mask        : t_wishbone_address_array);
+    g_mask        : t_wishbone_address_array;
+   -- Set to false to skip "Mapping Slave" notes during simulation
+    g_verbose     : boolean := true);
   port(
     clk_sys_i     : in  std_logic;
     rst_n_i       : in  std_logic;
@@ -111,10 +113,12 @@ architecture rtl of xwb_crossbar is
       severity Failure;
       
       -- Working case
-      report "Mapping slave #" & 
-             Integer'image(i) & "[" & f_bits2string(c_address(i)) & "/" &
-                                      f_bits2string(c_mask(i)) & "]"
-      severity Note;
+      if g_verbose then
+        report "Mapping slave #" &
+          Integer'image(i) & "[" & f_bits2string(c_address(i)) & "/" &
+          f_bits2string(c_mask(i)) & "]"
+          severity Note;
+      end if;
     end loop;
     return true;
   end f_ranges_ok;
diff --git a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd
index 9c3b26bf4a04032e7bf22e1f153493abd5858ac8..3c5f8196e91b2c18a6d2a724dbb52be6adc85e58 100644
--- a/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd
+++ b/modules/wishbone/wb_crossbar/xwb_sdb_crossbar.vhd
@@ -31,6 +31,7 @@ use work.wishbone_pkg.all;
 
 entity xwb_sdb_crossbar is
   generic(
+    g_verbose     : boolean := true;
     g_num_masters : natural := 1;
     g_num_slaves  : natural := 1;
     g_registered  : boolean := false;
@@ -232,7 +233,8 @@ begin
       g_num_slaves  => g_num_slaves + 1,
       g_registered  => g_registered,
       g_address     => c_address,
-      g_mask        => c_mask)
+      g_mask        => c_mask,
+      g_verbose     => g_verbose)
     port map(
       clk_sys_i     => clk_sys_i,
       rst_n_i       => rst_n_i,
@@ -248,7 +250,8 @@ begin
       g_num_slaves  => g_num_masters,
       g_registered  => g_registered,
       g_address     => c_addresses.msi_address,
-      g_mask        => c_addresses.msi_mask)
+      g_mask        => c_addresses.msi_mask,
+      g_verbose     => g_verbose)
     port map(
       clk_sys_i     => clk_sys_i,
       rst_n_i       => rst_n_i,
diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd
index 573eceb12f2ccc3daa156964aedd84007e3de85f..f7a43281dc5196b87732e82982ae6a9891767582 100644
--- a/modules/wishbone/wishbone_pkg.vhd
+++ b/modules/wishbone/wishbone_pkg.vhd
@@ -390,7 +390,8 @@ package wishbone_pkg is
       g_num_slaves  : integer;
       g_registered  : boolean;
       g_address     : t_wishbone_address_array;
-      g_mask        : t_wishbone_address_array);
+      g_mask        : t_wishbone_address_array;
+      g_verbose     : boolean := true);
     port (
       clk_sys_i : in  std_logic;
       rst_n_i   : in  std_logic;
@@ -419,6 +420,7 @@ package wishbone_pkg is
 
   component xwb_sdb_crossbar
     generic (
+      g_verbose     : boolean := true;
       g_num_masters : integer;
       g_num_slaves  : integer;
       g_registered  : boolean := false;