diff --git a/Manifest.py b/Manifest.py
index 58df8902b20384964c895941f7ae3580fc47db57..03239d0ddb8fd05c40f53ee11217a0e977a87d37 100644
--- a/Manifest.py
+++ b/Manifest.py
@@ -2,6 +2,6 @@ modules = {
 	"local" : [
 								"modules/common",
 								"modules/genrams" 
-#								"modules/wishbone"
+								"modules/wishbone"
 						]
 					}
\ No newline at end of file
diff --git a/modules/wishbone/Manifest.py b/modules/wishbone/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..d2b7a2ab5fe01fe497fbcb1f709a7977bb1dbc87
--- /dev/null
+++ b/modules/wishbone/Manifest.py
@@ -0,0 +1,13 @@
+modules =  { "local" :
+	
+						[ "wb_async_bridge",
+						"wb_conmax",
+						"wb_gpio_port",
+						"wb_simple_timer",
+						"wb_uart",
+						"wb_vic",
+						"wb_virtual_uart",
+						"wbgen2",
+						 ]};
+
+files = ["wishbone_pkg.vhd"];
diff --git a/modules/wishbone/wb_async_bridge/manifest.py b/modules/wishbone/wb_async_bridge/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..da4fbcbdba01c4543c6301efe16a1c76d39da6a6
--- /dev/null
+++ b/modules/wishbone/wb_async_bridge/manifest.py
@@ -0,0 +1 @@
+files = ["wb_cpu_bridge.vhd"]
diff --git a/modules/wishbone/wb_async_bridge/wb_cpu_bridge.vhd b/modules/wishbone/wb_async_bridge/wb_cpu_bridge.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9062e13942a5d40a4a1f0dd007546e716498c654
--- /dev/null
+++ b/modules/wishbone/wb_async_bridge/wb_cpu_bridge.vhd
@@ -0,0 +1,286 @@
+------------------------------------------------------------------------------
+-- Title      : Atmel EBI asynchronous bus <-> Wishbone bridge
+-- Project    : White Rabbit Switch
+------------------------------------------------------------------------------
+-- Author     : Tomasz Wlostowski
+-- Company    : CERN BE-Co-HT
+-- Created    : 2010-05-18
+-- Last update: 2011-03-16
+-- Platform   : FPGA-generic
+-- Standard   : VHDL'87
+-------------------------------------------------------------------------------
+-- Description: An interface between AT91SAM9x-series ARM CPU External Bus Interface
+-- and FPGA-internal Wishbone bus:
+-- - does clock domain synchronisation
+-- - provides configurable number of independent WB master ports at fixed base addresses
+-- TODO:
+-- - implement write queueing and read prefetching (for speed improvement)
+-------------------------------------------------------------------------------
+-- Copyright (c) 2010 Tomasz Wlostowski
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2010-05-18  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.log2;
+use ieee.math_real.ceil;
+
+use work.wishbone_pkg.all;
+use work.common_components.all;
+
+entity wb_cpu_bridge is
+  generic (
+    g_simulation           : integer := 0;
+    g_wishbone_num_masters : integer);
+
+  port(
+    sys_rst_n_i : in std_logic;         -- global reset
+
+-------------------------------------------------------------------------------
+-- Atmel EBI bus
+-------------------------------------------------------------------------------
+
+    cpu_clk_i  : in std_logic;          -- clock (not used now)
+-- async chip select, active LOW
+    cpu_cs_n_i : in std_logic;
+-- async write, active LOW
+    cpu_wr_n_i : in std_logic;
+-- async read, active LOW
+    cpu_rd_n_i : in std_logic;
+-- byte select, active  LOW (not used due to weird CPU pin layout - NBS2 line is
+-- shared with 100 Mbps Ethernet PHY)
+    cpu_bs_n_i : in std_logic_vector(3 downto 0);
+
+-- address input
+    cpu_addr_i : in std_logic_vector(c_cpu_addr_width-1 downto 0);
+
+-- data bus (bidirectional)
+    cpu_data_b : inout std_logic_vector(31 downto 0);
+
+-- async wait, active LOW
+    cpu_nwait_o : out std_logic;
+
+-------------------------------------------------------------------------------
+-- Wishbone master I/F 
+-------------------------------------------------------------------------------
+
+-- wishbone clock input (refclk/2)
+    wb_clk_i  : in  std_logic;
+-- wishbone master address output (m->s, common for all slaves)
+    wb_addr_o : out std_logic_vector(c_wishbone_addr_width - 1 downto 0);
+-- wishbone master data output (m->s, common for all slaves)
+    wb_data_o : out std_logic_vector(31 downto 0);
+-- wishbone cycle strobe (m->s, common for all slaves)
+    wb_stb_o  : out std_logic;
+-- wishbone write enable (m->s, common for all slaves)
+    wb_we_o   : out std_logic;
+-- wishbone byte select output (m->s, common for all slaves)
+    wb_sel_o  : out std_logic_vector(3 downto 0);
+
+
+-- wishbone cycle select (m->s, individual)
+    wb_cyc_o  : out std_logic_vector (g_wishbone_num_masters - 1 downto 0);
+-- wishbone master data input (s->m, individual)
+    wb_data_i : in  std_logic_vector (32 * g_wishbone_num_masters-1 downto 0);
+-- wishbone ACK input (s->m, individual)
+    wb_ack_i  : in  std_logic_vector(g_wishbone_num_masters-1 downto 0)
+
+    );
+
+end wb_cpu_bridge;
+
+architecture behavioral of wb_cpu_bridge is
+
+  constant c_periph_addr_bits : integer := c_cpu_addr_width - c_wishbone_addr_width;
+
+  signal periph_addr     : std_logic_vector(c_periph_addr_bits - 1 downto 0);
+  signal periph_addr_reg : std_logic_vector(c_periph_addr_bits - 1 downto 0);
+
+  signal periph_sel     : std_logic_vector(g_wishbone_num_masters - 1 downto 0);
+  signal periph_sel_reg : std_logic_vector(g_wishbone_num_masters - 1 downto 0);
+
+
+  signal rw_sel, cycle_in_progress, cs_synced, rd_pulse, wr_pulse : std_logic;
+  signal cpu_data_reg                                             : std_logic_vector(31 downto 0);
+  signal ack_muxed                                                : std_logic;
+  signal data_in_muxed                                            : std_logic_vector(31 downto 0);
+  signal long_cycle                                               : std_logic;
+  signal wb_cyc_int                                               : std_logic;
+  
+begin
+
+  gen_sync_chains_nosim : if(g_simulation = 0) generate
+
+    sync_ffs_cs : sync_ffs
+      generic map (
+        g_sync_edge => "positive")
+      port map
+      (rst_n_i  => sys_rst_n_i,
+       clk_i    => wb_clk_i,
+       data_i   => cpu_cs_n_i,
+       synced_o => cs_synced,
+       npulse_o => open
+       );
+
+    sync_ffs_wr : sync_ffs
+      generic map (
+        g_sync_edge => "positive")
+      port map (
+        rst_n_i  => sys_rst_n_i,
+        clk_i    => wb_clk_i,
+        data_i   => cpu_wr_n_i,
+        synced_o => open,
+        npulse_o => wr_pulse
+        );
+
+    sync_ffs_rd : sync_ffs
+      generic map (
+        g_sync_edge => "positive")
+      port map (
+        rst_n_i  => sys_rst_n_i,
+        clk_i    => wb_clk_i,
+        data_i   => cpu_rd_n_i,
+        synced_o => open,
+        npulse_o => rd_pulse
+        );
+
+  end generate gen_sync_chains_nosim;
+
+  gen_sim : if(g_simulation = 1) generate
+    wr_pulse  <= not cpu_wr_n_i;
+    rd_pulse  <= not cpu_rd_n_i;
+    cs_synced <= cpu_cs_n_i;
+  end generate gen_sim;
+
+
+
+  periph_addr <= cpu_addr_i (c_cpu_addr_width - 1 downto c_wishbone_addr_width);
+
+  onehot_decode : process (periph_addr)  -- periph_sel <= onehot_decode(periph_addr)
+    variable temp1 : std_logic_vector (periph_sel'high downto 0);
+    variable temp2 : integer range 0 to periph_sel'high;
+  begin
+    temp1 := (others => '0');
+    temp2 := 0;
+    for i in periph_addr'range loop
+      if (periph_addr(i) = '1') then
+        temp2 := 2*temp2+1;
+      else
+        temp2 := 2*temp2;
+      end if;
+    end loop;
+    temp1(temp2) := '1';
+    periph_sel   <= temp1;
+  end process;
+
+
+  ACK_MUX : process (periph_addr_reg, wb_ack_i)
+  begin
+    if(to_integer(unsigned(periph_addr_reg)) < g_wishbone_num_masters) then
+      ack_muxed <= wb_ack_i(to_integer(unsigned(periph_addr_reg)));
+    else
+      ack_muxed <= '0';
+    end if;
+  end process;
+
+
+  DIN_MUX : process (periph_addr_reg, wb_data_i)
+  begin
+    if(to_integer(unsigned(periph_addr_reg)) < g_wishbone_num_masters) then
+      data_in_muxed <= wb_data_i(32*to_integer(unsigned(periph_addr_reg)) + 31 downto 32 * to_integer(unsigned(periph_addr_reg)));
+    else
+      data_in_muxed <= (others => 'X');
+    end if;
+  end process;
+
+  process(wb_clk_i)
+  begin
+    if(rising_edge(wb_clk_i)) then
+      if(sys_rst_n_i = '0') then
+        cpu_data_reg      <= (others => '0');
+        cycle_in_progress <= '0';
+        rw_sel            <= '0';
+        cpu_nwait_o       <= '1';
+        long_cycle        <= '0';
+
+        wb_addr_o  <= (others => '0');
+        wb_data_o  <= (others => '0');
+        wb_sel_o   <= (others => '1');
+        wb_stb_o   <= '0';
+        wb_we_o    <= '0';
+        wb_cyc_int <= '0';
+
+        periph_sel_reg  <= (others => '0');
+        periph_addr_reg <= (others => '0');
+      else
+        
+
+        if(cs_synced = '0') then
+
+          wb_addr_o <= cpu_addr_i(c_wishbone_addr_width-1 downto 0);
+
+          if(cycle_in_progress = '1') then
+            if(ack_muxed = '1') then
+
+              if(rw_sel = '0') then
+                cpu_data_reg <= data_in_muxed;
+              end if;
+
+              cycle_in_progress <= '0';
+              wb_cyc_int        <= '0';
+              wb_sel_o          <= (others => '1');
+              wb_stb_o          <= '0';
+              wb_we_o           <= '0';
+              cpu_nwait_o       <= '1';
+              long_cycle        <= '0';
+              
+            else
+              cpu_nwait_o <= not long_cycle;
+              long_cycle  <= '1';
+            end if;
+            
+          elsif(rd_pulse = '1' or wr_pulse = '1') then
+            wb_we_o <= wr_pulse;
+            rw_sel  <= wr_pulse;
+
+            wb_cyc_int <= '1';
+            wb_stb_o   <= '1';
+            wb_addr_o  <= cpu_addr_i(c_wishbone_addr_width-1 downto 0);
+            long_cycle <= '0';
+
+            periph_addr_reg <= cpu_addr_i (c_cpu_addr_width-1 downto c_wishbone_addr_width);
+            periph_sel_reg  <= periph_sel;
+
+            if(wr_pulse = '1') then
+              wb_data_o <= cpu_data_b;
+            end if;
+
+            cycle_in_progress <= '1';
+          end if;
+        end if;
+      end if;
+    end if;
+  end process;
+
+  process(cpu_cs_n_i, cpu_rd_n_i, cpu_data_reg)
+  begin
+    if(cpu_cs_n_i = '0' and cpu_rd_n_i = '0') then
+      cpu_data_b <= cpu_data_reg;
+    else
+      cpu_data_b <= (others => 'Z');
+    end if;
+  end process;
+
+  gen_cyc_outputs : for i in 0 to g_wishbone_num_masters-1 generate
+    wb_cyc_o(i) <= wb_cyc_int and periph_sel_reg(i);
+  end generate gen_cyc_outputs;
+  
+  
+
+end behavioral;
diff --git a/modules/wishbone/wb_conmax/Manifest.py b/modules/wishbone/wb_conmax/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4dc1c435ece1df8b3596c8bd9ba1b904b45bf5f
--- /dev/null
+++ b/modules/wishbone/wb_conmax/Manifest.py
@@ -0,0 +1,3 @@
+files = ["wb_conmax_pri_dec.vhd", "wb_conmax_pri_enc.vhd", "wb_conmax_arb.vhd", "wb_conmax_msel.vhd",
+					"wbconmax_pkg.vhd", "wb_conmax_slave_if.vhd", "wb_conmax_master_if.vhd", "wb_conmax_rf.vhd",
+					"wb_conmax_top.vhd" ];
diff --git a/modules/wishbone/wb_conmax/wb_conmax_arb.vhd b/modules/wishbone/wb_conmax/wb_conmax_arb.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..6ab431fbe4466448a5b37048ce28eb8bac1c4cb6
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_arb.vhd
@@ -0,0 +1,238 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_arb.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2011-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Simple arbiter with round robin. It does not use any prioritization for 
+-- WB Masters.
+-- 
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_conmax_arb is
+  port(
+    clk_i : in std_logic;
+    rst_i : in std_logic;
+
+    --req_i(n) <- wb_cyc from n-th Master
+    req_i : in std_logic_vector(7 downto 0);
+    next_i  : in std_logic;
+    --which master (0 to 7) is granted
+    gnt_o : out std_logic_vector(2 downto 0)
+  );
+end wb_conmax_arb;
+
+architecture behaviour of wb_conmax_arb is
+  type t_arb_states is (GRANT0, GRANT1, GRANT2, GRANT3, GRANT4, GRANT5, 
+                        GRANT6, GRANT7);
+  
+  signal s_state  : t_arb_states;
+begin
+
+  --state transitions
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      if(rst_i = '1') then
+        s_state <= GRANT0;
+      else
+
+        case s_state is
+          when GRANT0 =>
+            --if this req is dropped or next is asserted, check for other req's
+            if(req_i(0)='0' or next_i='1') then
+              if   ( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              end if;
+            end if;
+
+          when GRANT1 =>
+            if(req_i(1)='0' or next_i='1') then
+              if   ( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              end if;
+            end if;
+
+          when GRANT2 =>
+            if(req_i(2)='0' or next_i='1') then
+              if   ( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              end if;
+            end if;
+
+          when GRANT3 =>
+            if(req_i(3)='0' or next_i='1') then
+              if   ( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              end if;
+            end if;
+
+          when GRANT4 =>
+            if(req_i(4)='0' or next_i='1') then
+              if   ( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              end if;
+            end if;
+
+          when GRANT5 =>
+            if(req_i(5)='0' or next_i='1') then
+              if   ( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              elsif( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              end if;
+            end if;
+
+          when GRANT6 =>
+            if(req_i(6)='0' or next_i='1') then
+              if   ( req_i(7)='1' ) then
+                s_state <= GRANT7;
+              elsif( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              end if;
+            end if;
+
+          when GRANT7 =>
+            if(req_i(7)='0' or next_i='1') then
+              if   ( req_i(0)='1' ) then
+                s_state <= GRANT0;
+              elsif( req_i(1)='1' ) then
+                s_state <= GRANT1;
+              elsif( req_i(2)='1' ) then
+                s_state <= GRANT2;
+              elsif( req_i(3)='1' ) then
+                s_state <= GRANT3;
+              elsif( req_i(4)='1' ) then
+                s_state <= GRANT4;
+              elsif( req_i(5)='1' ) then
+                s_state <= GRANT5;
+              elsif( req_i(6)='1' ) then
+                s_state <= GRANT6;
+              end if;
+            end if;
+
+          when others =>
+            s_state <= GRANT0;
+        end case;
+
+      end if;
+    end if;
+  end process;
+
+  process(s_state)
+  begin
+    case(s_state) is
+      when GRANT0 =>  gnt_o <= "000";
+      when GRANT1 =>  gnt_o <= "001";
+      when GRANT2 =>  gnt_o <= "010";
+      when GRANT3 =>  gnt_o <= "011";
+      when GRANT4 =>  gnt_o <= "100";
+      when GRANT5 =>  gnt_o <= "101";
+      when GRANT6 =>  gnt_o <= "110";
+      when GRANT7 =>  gnt_o <= "111";
+      when others =>  gnt_o <= "000";
+    end case;
+  end process;
+
+end behaviour;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_master_if.vhd b/modules/wishbone/wb_conmax/wb_conmax_master_if.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..1862520f0b07fbb612c331b9c12c73f54aa187cc
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_master_if.vhd
@@ -0,0 +1,168 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_master_if.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Wishbone interface to connect WB master from outside. Decodes 4 most 
+-- significant bits of Address bus. Using the selection it multiplexes the 
+-- Master's WB interface to appropriate Slave interface.
+--
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-- 2011-02-16  1.1      greg.d          Using generates and types
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.wbconmax_pkg.all;
+
+entity wb_conmax_master_if is
+  port(
+    clk_i : in std_logic;
+    rst_i : in std_logic;
+
+    --Master interface
+    wb_master_i : in  t_wb_i;
+    wb_master_o : out t_wb_o;
+
+    --Slaves(0 to 15) interface
+    wb_slaves_i : in  t_conmax_slaves_i;
+    wb_slaves_o : out t_conmax_slaves_o
+  ); 
+end wb_conmax_master_if;
+
+architecture behaviour of wb_conmax_master_if is
+
+  signal s_slv_sel  : std_logic_vector(3 downto 0);
+  signal s_cyc_o_next : std_logic_vector(15 downto 0);
+  signal s_cyc_o  : std_logic_vector(15 downto 0);
+
+begin
+
+  --Select logic
+  s_slv_sel <= wb_master_i.addr(c_aw-1 downto c_aw-4);
+
+  --Address & Data Pass
+  GEN_OUTS: 
+    for I in 0 to 15 generate
+      wb_slaves_o(I).addr <= wb_master_i.addr;
+      wb_slaves_o(I).sel  <= wb_master_i.sel;
+      wb_slaves_o(I).data <= wb_master_i.data;
+      wb_slaves_o(I).we   <= wb_master_i.we;
+      wb_slaves_o(I).cyc  <= s_cyc_o(I);
+      wb_slaves_o(I).stb  <= wb_master_i.stb when(s_slv_sel=std_logic_vector(
+                             to_unsigned(I, 4)) ) else '0';
+    end generate;
+ 
+  wb_master_o.data <= wb_slaves_i( 0).data when(s_slv_sel="0000") else
+                      wb_slaves_i( 1).data when(s_slv_sel="0001") else
+                      wb_slaves_i( 2).data when(s_slv_sel="0010") else
+                      wb_slaves_i( 3).data when(s_slv_sel="0011") else
+                      wb_slaves_i( 4).data when(s_slv_sel="0100") else
+                      wb_slaves_i( 5).data when(s_slv_sel="0101") else
+                      wb_slaves_i( 6).data when(s_slv_sel="0110") else
+                      wb_slaves_i( 7).data when(s_slv_sel="0111") else
+                      wb_slaves_i( 8).data when(s_slv_sel="1000") else
+                      wb_slaves_i( 9).data when(s_slv_sel="1001") else
+                      wb_slaves_i(10).data when(s_slv_sel="1010") else
+                      wb_slaves_i(11).data when(s_slv_sel="1011") else
+                      wb_slaves_i(12).data when(s_slv_sel="1100") else
+                      wb_slaves_i(13).data when(s_slv_sel="1101") else
+                      wb_slaves_i(14).data when(s_slv_sel="1110") else
+                      wb_slaves_i(15).data when(s_slv_sel="1111") else
+                      (others=>'0');
+
+  --Control Signal Pass
+  G1: for I in 0 to 15 generate
+  s_cyc_o_next(I) <= s_cyc_o(I) when ( wb_master_i.cyc='1' and wb_master_i.stb='0') else
+                wb_master_i.cyc when ( s_slv_sel=std_logic_vector(to_unsigned(I, 4)) ) else
+                '0';
+  end generate;
+
+  process(clk_i)
+  begin
+    if( clk_i'event and clk_i='1') then
+      if(rst_i='1') then
+        s_cyc_o(15 downto 0) <= (others => '0');
+      else
+        s_cyc_o(15 downto 0) <= s_cyc_o_next(15 downto 0);
+      end if;
+    end if;
+  end process;
+
+  wb_master_o.ack <= wb_slaves_i( 0).ack when(s_slv_sel="0000") else
+                     wb_slaves_i( 1).ack when(s_slv_sel="0001") else
+                     wb_slaves_i( 2).ack when(s_slv_sel="0010") else
+                     wb_slaves_i( 3).ack when(s_slv_sel="0011") else
+                     wb_slaves_i( 4).ack when(s_slv_sel="0100") else
+                     wb_slaves_i( 5).ack when(s_slv_sel="0101") else
+                     wb_slaves_i( 6).ack when(s_slv_sel="0110") else
+                     wb_slaves_i( 7).ack when(s_slv_sel="0111") else
+                     wb_slaves_i( 8).ack when(s_slv_sel="1000") else
+                     wb_slaves_i( 9).ack when(s_slv_sel="1001") else
+                     wb_slaves_i(10).ack when(s_slv_sel="1010") else
+                     wb_slaves_i(11).ack when(s_slv_sel="1011") else
+                     wb_slaves_i(12).ack when(s_slv_sel="1100") else
+                     wb_slaves_i(13).ack when(s_slv_sel="1101") else
+                     wb_slaves_i(14).ack when(s_slv_sel="1110") else
+                     wb_slaves_i(15).ack when(s_slv_sel="1111") else
+                     '0';
+
+  wb_master_o.err <= wb_slaves_i( 0).err when(s_slv_sel="0000") else
+                     wb_slaves_i( 1).err when(s_slv_sel="0001") else
+                     wb_slaves_i( 2).err when(s_slv_sel="0010") else
+                     wb_slaves_i( 3).err when(s_slv_sel="0011") else
+                     wb_slaves_i( 4).err when(s_slv_sel="0100") else
+                     wb_slaves_i( 5).err when(s_slv_sel="0101") else
+                     wb_slaves_i( 6).err when(s_slv_sel="0110") else
+                     wb_slaves_i( 7).err when(s_slv_sel="0111") else
+                     wb_slaves_i( 8).err when(s_slv_sel="1000") else
+                     wb_slaves_i( 9).err when(s_slv_sel="1001") else
+                     wb_slaves_i(10).err when(s_slv_sel="1010") else
+                     wb_slaves_i(11).err when(s_slv_sel="1011") else
+                     wb_slaves_i(12).err when(s_slv_sel="1100") else
+                     wb_slaves_i(13).err when(s_slv_sel="1101") else
+                     wb_slaves_i(14).err when(s_slv_sel="1110") else
+                     wb_slaves_i(15).err when(s_slv_sel="1111") else
+                     '0';
+
+  wb_master_o.rty <= wb_slaves_i( 0).rty when(s_slv_sel="0000") else
+                     wb_slaves_i( 1).rty when(s_slv_sel="0001") else
+                     wb_slaves_i( 2).rty when(s_slv_sel="0010") else
+                     wb_slaves_i( 3).rty when(s_slv_sel="0011") else
+                     wb_slaves_i( 4).rty when(s_slv_sel="0100") else
+                     wb_slaves_i( 5).rty when(s_slv_sel="0101") else
+                     wb_slaves_i( 6).rty when(s_slv_sel="0110") else
+                     wb_slaves_i( 7).rty when(s_slv_sel="0111") else
+                     wb_slaves_i( 8).rty when(s_slv_sel="1000") else
+                     wb_slaves_i( 9).rty when(s_slv_sel="1001") else
+                     wb_slaves_i(10).rty when(s_slv_sel="1010") else
+                     wb_slaves_i(11).rty when(s_slv_sel="1011") else
+                     wb_slaves_i(12).rty when(s_slv_sel="1100") else
+                     wb_slaves_i(13).rty when(s_slv_sel="1101") else
+                     wb_slaves_i(14).rty when(s_slv_sel="1110") else
+                     wb_slaves_i(15).rty when(s_slv_sel="1111") else
+                     '0';
+
+end behaviour;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_msel.vhd b/modules/wishbone/wb_conmax/wb_conmax_msel.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..3631498b5b15c6ddd4bdc47984d7a9686e6702c0
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_msel.vhd
@@ -0,0 +1,267 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_msel.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-12
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Prioritizing arbiter for Slave interface. Uses simple arbitrer 
+-- (wb_conmax_arb) and takes Master's priorities into account.
+-- 
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_conmax_msel is
+  generic(
+    g_pri_sel : integer := 0
+  );
+  port(
+    clk_i : in std_logic;
+    rst_i : in std_logic;
+    
+    conf_i  : in std_logic_vector(15 downto 0);
+    req_i   : in std_logic_vector(7 downto 0);
+    next_i  : in std_logic;
+    
+    sel     : out std_logic_vector(2 downto 0)
+  );
+end wb_conmax_msel;
+
+architecture behavioral of wb_conmax_msel is
+
+  component wb_conmax_pri_enc is
+  generic(
+    -- :=1 means 2 priority levels, :=2 means 4 priority levels
+    g_pri_sel : integer := 0
+  );
+  port(
+    valid_i : in std_logic_vector(7 downto 0);
+
+    pri0_i  : in std_logic_vector(1 downto 0);
+    pri1_i  : in std_logic_vector(1 downto 0);
+    pri2_i  : in std_logic_vector(1 downto 0);
+    pri3_i  : in std_logic_vector(1 downto 0);
+    pri4_i  : in std_logic_vector(1 downto 0);
+    pri5_i  : in std_logic_vector(1 downto 0);
+    pri6_i  : in std_logic_vector(1 downto 0);
+    pri7_i  : in std_logic_vector(1 downto 0);
+
+    pri_o   : out std_logic_vector(1 downto 0)
+  );
+  end component;
+
+  component wb_conmax_arb is
+    port(
+      clk_i : in std_logic;
+      rst_i : in std_logic;
+  
+      req_i : in std_logic_vector(7 downto 0);
+      gnt_o : out std_logic_vector(2 downto 0);
+  
+      next_i  : in std_logic
+    );
+  end component;
+
+
+  signal s_pri0, s_pri1, s_pri2, s_pri3, s_pri4,
+         s_pri5, s_pri6, s_pri7 : std_logic_vector(1 downto 0);
+ 
+  signal s_pri_out_d, s_pri_out : std_logic_vector(1 downto 0);
+  signal s_req_p0, s_req_p1, s_req_p2, s_req_p3 : std_logic_vector(7 downto 0);
+  signal s_gnt_p0, s_gnt_p1, s_gnt_p2, s_gnt_p3 : std_logic_vector(2 downto 0);
+  signal s_sel1, s_sel2 : std_logic_vector(2 downto 0);
+  
+begin
+
+  --------------------------------------
+  --Priority Select logic
+  G1: if(g_pri_sel=0) generate
+    s_pri0 <= "00";
+    s_pri1 <= "00";
+    s_pri2 <= "00";
+    s_pri3 <= "00";
+    s_pri4 <= "00";
+    s_pri5 <= "00";
+    s_pri6 <= "00";
+    s_pri7 <= "00";
+  end generate;
+
+  G2: if(g_pri_sel=2) generate
+    s_pri0 <= conf_i(1 downto 0);
+    s_pri1 <= conf_i(3 downto 2);
+    s_pri2 <= conf_i(5 downto 4);
+    s_pri3 <= conf_i(7 downto 6);
+    s_pri4 <= conf_i(9 downto 8);
+    s_pri5 <= conf_i(11 downto 10);
+    s_pri6 <= conf_i(13 downto 12);
+    s_pri7 <= conf_i(15 downto 14);
+  end generate;
+
+  G3: if(g_pri_sel/=0 and g_pri_sel/=2) generate
+    s_pri0 <= '0' & conf_i(0);
+    s_pri1 <= '0' & conf_i(2); 
+    s_pri2 <= '0' & conf_i(4); 
+    s_pri3 <= '0' & conf_i(6); 
+    s_pri4 <= '0' & conf_i(8); 
+    s_pri5 <= '0' & conf_i(10); 
+    s_pri6 <= '0' & conf_i(12); 
+    s_pri7 <= '0' & conf_i(14); 
+  end generate;
+  
+  PRI_ENC: wb_conmax_pri_enc
+    generic map(
+      -- :=1 means 2 priority levels, :=2 means 4 priority levels
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => req_i,
+  
+      pri0_i  => s_pri0, 
+      pri1_i  => s_pri1, 
+      pri2_i  => s_pri2, 
+      pri3_i  => s_pri3, 
+      pri4_i  => s_pri4, 
+      pri5_i  => s_pri5, 
+      pri6_i  => s_pri6, 
+      pri7_i  => s_pri7, 
+  
+      pri_o   => s_pri_out_d
+    );
+
+  
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      if(rst_i = '1') then
+        s_pri_out <= "00";
+      elsif(next_i = '1') then
+        s_pri_out <= s_pri_out_d;
+      end if;
+    end if;
+  end process;
+
+
+  -----------------------------------------------
+  --Arbiters
+  s_req_p0(0) <= req_i(0) when(s_pri0 = "00") else '0';
+  s_req_p0(1) <= req_i(1) when(s_pri1 = "00") else '0';
+  s_req_p0(2) <= req_i(2) when(s_pri2 = "00") else '0';
+  s_req_p0(3) <= req_i(3) when(s_pri3 = "00") else '0';
+  s_req_p0(4) <= req_i(4) when(s_pri4 = "00") else '0';
+  s_req_p0(5) <= req_i(5) when(s_pri5 = "00") else '0';
+  s_req_p0(6) <= req_i(6) when(s_pri6 = "00") else '0';
+  s_req_p0(7) <= req_i(7) when(s_pri7 = "00") else '0';
+  
+  s_req_p1(0) <= req_i(0) when(s_pri0 = "01") else '0';
+  s_req_p1(1) <= req_i(1) when(s_pri1 = "01") else '0';
+  s_req_p1(2) <= req_i(2) when(s_pri2 = "01") else '0';
+  s_req_p1(3) <= req_i(3) when(s_pri3 = "01") else '0';
+  s_req_p1(4) <= req_i(4) when(s_pri4 = "01") else '0';
+  s_req_p1(5) <= req_i(5) when(s_pri5 = "01") else '0';
+  s_req_p1(6) <= req_i(6) when(s_pri6 = "01") else '0';
+  s_req_p1(7) <= req_i(7) when(s_pri7 = "01") else '0';
+  
+  s_req_p2(0) <= req_i(0) when(s_pri0 = "10") else '0';
+  s_req_p2(1) <= req_i(1) when(s_pri1 = "10") else '0';
+  s_req_p2(2) <= req_i(2) when(s_pri2 = "10") else '0';
+  s_req_p2(3) <= req_i(3) when(s_pri3 = "10") else '0';
+  s_req_p2(4) <= req_i(4) when(s_pri4 = "10") else '0';
+  s_req_p2(5) <= req_i(5) when(s_pri5 = "10") else '0';
+  s_req_p2(6) <= req_i(6) when(s_pri6 = "10") else '0';
+  s_req_p2(7) <= req_i(7) when(s_pri7 = "10") else '0';
+  
+  s_req_p3(0) <= req_i(0) when(s_pri0 = "11") else '0';
+  s_req_p3(1) <= req_i(1) when(s_pri1 = "11") else '0';
+  s_req_p3(2) <= req_i(2) when(s_pri2 = "11") else '0';
+  s_req_p3(3) <= req_i(3) when(s_pri3 = "11") else '0';
+  s_req_p3(4) <= req_i(4) when(s_pri4 = "11") else '0';
+  s_req_p3(5) <= req_i(5) when(s_pri5 = "11") else '0';
+  s_req_p3(6) <= req_i(6) when(s_pri6 = "11") else '0';
+  s_req_p3(7) <= req_i(7) when(s_pri7 = "11") else '0';
+
+  ARB0: wb_conmax_arb 
+    port map(
+      clk_i  => clk_i,
+      rst_i  => rst_i,
+  
+      req_i  => s_req_p0,
+      gnt_o  => s_gnt_p0,
+  
+      next_i => '0'
+    );
+
+  ARB1: wb_conmax_arb 
+    port map(
+      clk_i  => clk_i,
+      rst_i  => rst_i,
+  
+      req_i  => s_req_p1,
+      gnt_o  => s_gnt_p1,
+  
+      next_i => '0'
+    );
+
+  ARB2: wb_conmax_arb 
+    port map(
+      clk_i  => clk_i,
+      rst_i  => rst_i,
+  
+      req_i  => s_req_p2,
+      gnt_o  => s_gnt_p2,
+  
+      next_i => '0'
+    );
+
+  ARB3: wb_conmax_arb 
+    port map(
+      clk_i  => clk_i,
+      rst_i  => rst_i,
+  
+      req_i  => s_req_p3,
+      gnt_o  => s_gnt_p3,
+  
+      next_i => '0'
+    );
+
+  -----------------------------------------------
+  --Final Master Select
+  s_sel1 <= s_gnt_p1 when( s_pri_out(0)='1' ) else
+            s_gnt_p0;
+
+  s_sel2 <= s_gnt_p0 when( s_pri_out="00" ) else
+            s_gnt_p1 when( s_pri_out="01" ) else
+            s_gnt_p2 when( s_pri_out="10" ) else
+            s_gnt_p3;
+
+  G4: if(g_pri_sel=0) generate
+    sel <= s_gnt_p0;
+  end generate;
+  
+  G5: if(g_pri_sel=1) generate
+    sel <= s_sel1;
+  end generate;
+
+  G6: if(g_pri_sel/=0 and g_pri_sel/=1) generate
+    sel <= s_sel2;
+  end generate;
+
+end behavioral;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_pri_dec.vhd b/modules/wishbone/wb_conmax/wb_conmax_pri_dec.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..c16c9be10555b608eb9459c59288cdca6d56a6e0
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_pri_dec.vhd
@@ -0,0 +1,91 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_pri_dec.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-12
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Simple Master's priority encoder
+--
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+-- (eg. <if..generate> instead of pri_out_d0 and pri_out_d1)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_conmax_pri_dec is
+  generic(
+    -- :=1 means 2 priority levels, :=2 means 4 priority levels
+    g_pri_sel : integer := 0
+  );
+  port(
+    valid_i : in std_logic;
+    pri_i   : in std_logic_vector(1 downto 0);
+    pri_o   : out std_logic_vector(3 downto 0)
+  );
+end wb_conmax_pri_dec;
+
+architecture behaviour of wb_conmax_pri_dec is
+
+  signal pri_out_d0 : std_logic_vector(3 downto 0);
+  signal pri_out_d1 : std_logic_vector(3 downto 0);
+
+begin
+
+  --4 priority levels
+  process(valid_i,pri_i)
+  begin
+    if( valid_i='0' ) then
+      pri_out_d1 <= "0001";
+    elsif( pri_i="00" ) then
+      pri_out_d1 <= "0001";
+    elsif( pri_i="01" ) then
+      pri_out_d1 <= "0010";
+    elsif( pri_i="10" ) then
+      pri_out_d1 <= "0100";
+    else
+      pri_out_d1 <= "1000";
+    end if;
+  end process;
+
+  --2 priority levels
+  process(valid_i, pri_i)
+  begin
+    if( valid_i='0' ) then
+      pri_out_d0 <= "0001";
+    elsif( pri_i="00" ) then
+      pri_out_d0 <= "0001";
+    else
+      pri_out_d0 <= "0010";
+    end if;
+  end process;
+
+  --select how many pririty levels
+  G1: if(g_pri_sel=0) generate
+    pri_o <= "0000";
+  end generate;
+  G2: if(g_pri_sel=1) generate
+    pri_o <= pri_out_d0;
+  end generate;
+  G3: if(g_pri_sel/=0 and g_pri_sel/=1) generate
+    pri_o <= pri_out_d1;
+  end generate;
+
+end behaviour;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_pri_enc.vhd b/modules/wishbone/wb_conmax/wb_conmax_pri_enc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..193c6b579668fdb39a669519b0f67e50ea0713d6
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_pri_enc.vhd
@@ -0,0 +1,193 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_pri_enc.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-12
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- The set of priority encoders for all Master interfaces.
+-- 
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_conmax_pri_enc is
+  generic(
+    -- :=1 means 2 priority levels, :=2 means 4 priority levels
+    g_pri_sel : integer := 0
+  );
+  port(
+    valid_i : in std_logic_vector(7 downto 0);
+
+    pri0_i  : in std_logic_vector(1 downto 0);
+    pri1_i  : in std_logic_vector(1 downto 0);
+    pri2_i  : in std_logic_vector(1 downto 0);
+    pri3_i  : in std_logic_vector(1 downto 0);
+    pri4_i  : in std_logic_vector(1 downto 0);
+    pri5_i  : in std_logic_vector(1 downto 0);
+    pri6_i  : in std_logic_vector(1 downto 0);
+    pri7_i  : in std_logic_vector(1 downto 0);
+
+    pri_o   : out std_logic_vector(1 downto 0)
+  );
+end wb_conmax_pri_enc;
+
+architecture behaviour of wb_conmax_pri_enc is
+
+  component wb_conmax_pri_dec is
+    generic(
+      -- :=1 means 2 priority levels, :=2 means 4 priority levels
+      g_pri_sel : integer := 0
+    );
+    port(
+      valid_i : in std_logic;
+      pri_i   : in std_logic_vector(1 downto 0);
+      pri_o   : out std_logic_vector(3 downto 0)
+    );
+  end component;
+
+  signal s_pri0_o : std_logic_vector(3 downto 0);
+  signal s_pri1_o : std_logic_vector(3 downto 0);
+  signal s_pri2_o : std_logic_vector(3 downto 0);
+  signal s_pri3_o : std_logic_vector(3 downto 0);
+  signal s_pri4_o : std_logic_vector(3 downto 0);
+  signal s_pri5_o : std_logic_vector(3 downto 0);
+  signal s_pri6_o : std_logic_vector(3 downto 0);
+  signal s_pri7_o : std_logic_vector(3 downto 0);
+
+  signal s_pritmp_o : std_logic_vector(3 downto 0);
+
+  signal s_pri_out0 : std_logic_vector(1 downto 0);
+  signal s_pri_out1 : std_logic_vector(1 downto 0);
+
+
+begin
+
+  PD0: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(0),
+      pri_i   => pri0_i,
+      pri_o   => s_pri0_o
+    );
+ 
+  PD1: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(1),
+      pri_i   => pri1_i,
+      pri_o   => s_pri1_o
+    );
+
+  PD2: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(2),
+      pri_i   => pri2_i,
+      pri_o   => s_pri2_o
+    );
+
+  PD3: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(3),
+      pri_i   => pri3_i,
+      pri_o   => s_pri3_o
+    );
+
+  PD4: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(4),
+      pri_i   => pri4_i,
+      pri_o   => s_pri4_o
+    );
+ 
+  PD5: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(5),
+      pri_i   => pri5_i,
+      pri_o   => s_pri5_o
+    );
+
+  PD6: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(6),
+      pri_i   => pri6_i,
+      pri_o   => s_pri6_o
+    );
+
+  PD7: wb_conmax_pri_dec
+    generic map( 
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      valid_i => valid_i(7),
+      pri_i   => pri7_i,
+      pri_o   => s_pri7_o
+    );
+
+
+  s_pritmp_o <= s_pri0_o or s_pri1_o or s_pri2_o or s_pri3_o or s_pri4_o or
+                s_pri5_o or s_pri6_o or s_pri7_o;
+
+  --4 priority levels
+  s_pri_out1 <= "11" when ( s_pritmp_o(3)='1' ) else
+                "10" when ( s_pritmp_o(2)='1' ) else
+                "01" when ( s_pritmp_o(1)='1' ) else
+                "00";
+
+  --2 priority levels
+  s_pri_out0 <= "01" when ( s_pritmp_o(1)='1' ) else
+                "00";
+
+
+
+  G1: if (g_pri_sel=0) generate
+    pri_o <= "00";
+  end generate;
+  G2: if (g_pri_sel=1) generate
+    pri_o <= s_pri_out0;
+  end generate;
+  G3: if (g_pri_sel/=0 and g_pri_sel/=1) generate 
+    pri_o <= s_pri_out1;
+  end generate;
+
+
+end behaviour;
+
+
diff --git a/modules/wishbone/wb_conmax/wb_conmax_rf.vhd b/modules/wishbone/wb_conmax/wb_conmax_rf.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..430b17e0b1fe8ea92740910aef28957efeb133b7
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_rf.vhd
@@ -0,0 +1,167 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_rf.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Register File - consists of 16 registers. Each stores configuration for 
+-- different Slave. 
+-- Each of those 16 registers is the Slave's personal priority register, 
+-- where the priorities for each Master are stored. The Register File is 
+-- accessible from Master through Slave 15th interface.
+-- 
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-- 2011-02-16  1.1      greg.d          Using generates and types
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.wbconmax_pkg.all;
+
+entity wb_conmax_rf is
+  generic(
+    g_rf_addr : integer range 0 to 15 := 15  --0xF
+  );
+  port(
+    clk_i : in std_logic;
+    rst_i : in std_logic;
+    
+    --Internal WB interface
+    int_wb_i  : in  t_wb_i;
+    int_wb_o  : out t_wb_o;
+    --External WB interface
+    ext_wb_i  : in  t_wb_o;
+    ext_wb_o  : out t_wb_i;
+
+    --Configuration regs
+    conf_o    : out t_rf_conf
+  );
+end wb_conmax_rf;
+
+architecture behaviour of wb_conmax_rf is
+
+  signal s_rf_sel  : std_logic;
+  signal s_rf_dout : std_logic_vector(15 downto 0);
+  signal s_rf_ack  : std_logic;
+  signal s_rf_we   : std_logic;
+
+  signal s_conf    : t_rf_conf;
+
+  signal s_rf_addr  : std_logic_vector(3 downto 0);
+begin
+
+  --Register File select logic
+  s_rf_addr <= std_logic_vector(to_unsigned(g_rf_addr, 4));
+  s_rf_sel <= int_wb_i.cyc and int_wb_i.stb when(int_wb_i.addr(c_aw-5 downto c_aw-8) = s_rf_addr )
+              else '0';
+
+
+  --Register File logic
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      s_rf_we <= s_rf_sel and int_wb_i.we and not(s_rf_we);
+      s_rf_ack <= s_rf_sel and not(s_rf_ack);
+    end if;
+  end process;
+
+
+  --Write logic
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      if(rst_i = '1') then
+        s_conf <= (others=> (others=>'0'));
+      elsif(s_rf_we='1') then
+
+        if   (int_wb_i.addr(5 downto 2)=x"0") then s_conf(0)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"1") then s_conf(1)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"2") then s_conf(2)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"3") then s_conf(3)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"4") then s_conf(4)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"5") then s_conf(5)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"6") then s_conf(6)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"7") then s_conf(7)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"8") then s_conf(8)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"9") then s_conf(9)  <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"a") then s_conf(10) <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"b") then s_conf(11) <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"c") then s_conf(12) <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"d") then s_conf(13) <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"e") then s_conf(14) <= int_wb_i.data(15 downto 0);
+        elsif(int_wb_i.addr(5 downto 2)=x"f") then s_conf(15) <= int_wb_i.data(15 downto 0);
+        end if;
+
+      end if;
+    end if;
+  end process;
+
+
+  --Read logic
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      if(s_rf_sel='0') then
+        s_rf_dout <= x"0000";
+      else
+      
+        if   ( int_wb_i.addr(5 downto 2)=x"0" ) then s_rf_dout <= s_conf(0);
+        elsif( int_wb_i.addr(5 downto 2)=x"1" ) then s_rf_dout <= s_conf(1);
+        elsif( int_wb_i.addr(5 downto 2)=x"2" ) then s_rf_dout <= s_conf(2);
+        elsif( int_wb_i.addr(5 downto 2)=x"3" ) then s_rf_dout <= s_conf(3);
+        elsif( int_wb_i.addr(5 downto 2)=x"4" ) then s_rf_dout <= s_conf(4);
+        elsif( int_wb_i.addr(5 downto 2)=x"5" ) then s_rf_dout <= s_conf(5);
+        elsif( int_wb_i.addr(5 downto 2)=x"6" ) then s_rf_dout <= s_conf(6);
+        elsif( int_wb_i.addr(5 downto 2)=x"7" ) then s_rf_dout <= s_conf(7);
+        elsif( int_wb_i.addr(5 downto 2)=x"8" ) then s_rf_dout <= s_conf(8);
+        elsif( int_wb_i.addr(5 downto 2)=x"9" ) then s_rf_dout <= s_conf(9);
+        elsif( int_wb_i.addr(5 downto 2)=x"A" ) then s_rf_dout <= s_conf(10);
+        elsif( int_wb_i.addr(5 downto 2)=x"B" ) then s_rf_dout <= s_conf(11);
+        elsif( int_wb_i.addr(5 downto 2)=x"C" ) then s_rf_dout <= s_conf(12);
+        elsif( int_wb_i.addr(5 downto 2)=x"D" ) then s_rf_dout <= s_conf(13);
+        elsif( int_wb_i.addr(5 downto 2)=x"E" ) then s_rf_dout <= s_conf(14);
+        elsif( int_wb_i.addr(5 downto 2)=x"F" ) then s_rf_dout <= s_conf(15);
+        end if;
+      
+      end if;
+    end if;
+  end process;
+
+
+  --Register File bypass logic
+  ext_wb_o.addr <= int_wb_i.addr;
+  ext_wb_o.sel  <= int_wb_i.sel;
+  ext_wb_o.data <= int_wb_i.data;
+  ext_wb_o.cyc  <= int_wb_i.cyc when(s_rf_sel='0') else '0';
+  ext_wb_o.stb  <= int_wb_i.stb;
+  ext_wb_o.we   <= int_wb_i.we;
+
+  int_wb_o.data <= ( (c_dw-1 downto 16 => '0') & s_rf_dout ) when(s_rf_sel='1')
+                   else ext_wb_i.data;
+  int_wb_o.ack  <= s_rf_ack when(s_rf_sel='1') else ext_wb_i.ack;
+  int_wb_o.err  <= '0'      when(s_rf_sel='1') else ext_wb_i.err;
+  int_wb_o.rty  <= '0'      when(s_rf_sel='1') else ext_wb_i.rty;
+
+  conf_o  <= s_conf;
+
+end behaviour;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_slave_if.vhd b/modules/wishbone/wb_conmax/wb_conmax_slave_if.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..945f85aefde0759b01d41a1a3bfbcb46e6e3a79e
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_slave_if.vhd
@@ -0,0 +1,226 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_slave_if.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Full interface for a single Wishbone Slave. Consists of WB Master interface,
+-- Prioritizing Arbiter and multiplexer for selecting appropriate Master.
+-- 
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-- 2011-02-16  1.1      greg.d          Using generates and types
+-------------------------------------------------------------------------------
+-- TODO:
+-- Code optimization. (now it is more like dummy translation from Verilog)
+--
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.wbconmax_pkg.all;
+
+entity wb_conmax_slave_if is
+  generic(
+    g_pri_sel : integer := 2
+  );
+  port(
+    clk_i        : in std_logic;
+    rst_i        : in std_logic;
+    conf_i       : in std_logic_vector(15 downto 0);
+
+    --Slave interface
+    wb_slave_i   : in  t_wb_o;
+    wb_slave_o   : out t_wb_i;
+
+    --Master (0 to 7) interfaces
+    wb_masters_i : in  t_conmax_masters_i;
+    wb_masters_o : out t_conmax_masters_o
+  );
+end wb_conmax_slave_if;
+
+architecture bahaviour of wb_conmax_slave_if is
+
+  component wb_conmax_arb is
+    port(
+      clk_i : in std_logic;
+      rst_i : in std_logic;
+  
+      req_i : in std_logic_vector(7 downto 0);
+      gnt_o : out std_logic_vector(2 downto 0);
+  
+      next_i  : in std_logic
+    );
+  end component;
+
+  component wb_conmax_msel is
+    generic(
+      g_pri_sel : integer := 0
+    );
+    port(
+      clk_i : in std_logic;
+      rst_i : in std_logic;
+      
+      conf_i  : in std_logic_vector(15 downto 0);
+      req_i   : in std_logic_vector(7 downto 0);
+      next_i  : in std_logic;
+      
+      sel     : out std_logic_vector(2 downto 0)
+    );
+  end component;
+
+
+
+  signal s_wb_cyc_o : std_logic;
+  signal s_msel_simple, s_msel_pe, s_msel : std_logic_vector(2 downto 0);
+  signal s_next : std_logic;
+  signal s_mcyc : std_logic_vector(7 downto 0);
+  signal s_arb_req_i  : std_logic_vector(7 downto 0);
+
+begin
+
+  wb_slave_o.cyc  <= s_wb_cyc_o;
+
+  process(clk_i)
+  begin
+    if(clk_i'event and clk_i='1') then
+      s_next <= not(s_wb_cyc_o);
+    end if;
+  end process;
+
+  s_arb_req_i <= wb_masters_i(7).cyc & wb_masters_i(6).cyc & wb_masters_i(5).cyc &
+                 wb_masters_i(4).cyc & wb_masters_i(3).cyc & wb_masters_i(2).cyc &
+                 wb_masters_i(1).cyc & wb_masters_i(0).cyc;
+  --Prioritizing Arbiter
+  ARB: wb_conmax_arb
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      req_i => s_arb_req_i,
+      gnt_o => s_msel_simple,
+      next_i=> '0'  --no round robin
+    );
+ 
+  MSEL: wb_conmax_msel
+    generic map(
+      g_pri_sel => g_pri_sel
+    )
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+      
+      conf_i => conf_i,
+      req_i  => s_arb_req_i,
+      next_i => s_next,
+      sel    => s_msel_pe
+    );
+
+    G1: if(g_pri_sel=0) generate
+      s_msel <= s_msel_simple;
+    end generate;
+    G2: if(g_pri_sel/=0) generate
+      s_msel <= s_msel_pe;
+    end generate;
+
+
+    -------------------------------------
+    --Address & Data Pass
+    wb_slave_o.addr <= wb_masters_i(0).addr when(s_msel="000") else
+                       wb_masters_i(1).addr when(s_msel="001") else
+                       wb_masters_i(2).addr when(s_msel="010") else
+                       wb_masters_i(3).addr when(s_msel="011") else
+                       wb_masters_i(4).addr when(s_msel="100") else
+                       wb_masters_i(5).addr when(s_msel="101") else
+                       wb_masters_i(6).addr when(s_msel="110") else
+                       wb_masters_i(7).addr when(s_msel="111") else
+                       (others=>'0');
+
+    wb_slave_o.sel <=  wb_masters_i(0).sel when(s_msel="000") else
+                       wb_masters_i(1).sel when(s_msel="001") else
+                       wb_masters_i(2).sel when(s_msel="010") else
+                       wb_masters_i(3).sel when(s_msel="011") else
+                       wb_masters_i(4).sel when(s_msel="100") else
+                       wb_masters_i(5).sel when(s_msel="101") else
+                       wb_masters_i(6).sel when(s_msel="110") else
+                       wb_masters_i(7).sel when(s_msel="111") else
+                       (others=>'0');
+
+    wb_slave_o.data <= wb_masters_i(0).data when(s_msel="000") else
+                       wb_masters_i(1).data when(s_msel="001") else
+                       wb_masters_i(2).data when(s_msel="010") else
+                       wb_masters_i(3).data when(s_msel="011") else
+                       wb_masters_i(4).data when(s_msel="100") else
+                       wb_masters_i(5).data when(s_msel="101") else
+                       wb_masters_i(6).data when(s_msel="110") else
+                       wb_masters_i(7).data when(s_msel="111") else
+                       (others=>'0');
+  
+    G_OUT: for I in 0 to 7 generate
+      wb_masters_o(I).data <= wb_slave_i.data;
+      wb_masters_o(I).ack  <= wb_slave_i.ack when(s_msel= std_logic_vector(
+                              to_unsigned(I, 3)) ) else '0';
+      wb_masters_o(I).err  <= wb_slave_i.err when(s_msel= std_logic_vector(
+                              to_unsigned(I, 3)) ) else '0';
+      wb_masters_o(I).rty  <= wb_slave_i.rty when(s_msel= std_logic_vector(
+                              to_unsigned(I, 3)) ) else '0';
+    end generate;
+
+    ------------------------------------
+    --Control Signal Pass
+    wb_slave_o.we <= wb_masters_i(0).we when(s_msel="000") else
+                     wb_masters_i(1).we when(s_msel="001") else
+                     wb_masters_i(2).we when(s_msel="010") else
+                     wb_masters_i(3).we when(s_msel="011") else
+                     wb_masters_i(4).we when(s_msel="100") else
+                     wb_masters_i(5).we when(s_msel="101") else
+                     wb_masters_i(6).we when(s_msel="110") else
+                     wb_masters_i(7).we when(s_msel="111") else
+                     '0';
+
+    process(clk_i)
+    begin
+      if(clk_i'event and clk_i='1') then
+        s_mcyc(7 downto 0)  <=     wb_masters_i(7).cyc & wb_masters_i(6).cyc & 
+             wb_masters_i(5).cyc & wb_masters_i(4).cyc & wb_masters_i(3).cyc &
+             wb_masters_i(2).cyc & wb_masters_i(1).cyc & wb_masters_i(0).cyc;
+                             
+      end if;
+    end process;
+
+    s_wb_cyc_o <= wb_masters_i(0).cyc and s_mcyc(0)  when(s_msel="000") else
+                  wb_masters_i(1).cyc and s_mcyc(1)  when(s_msel="001") else
+                  wb_masters_i(2).cyc and s_mcyc(2)  when(s_msel="010") else
+                  wb_masters_i(3).cyc and s_mcyc(3)  when(s_msel="011") else
+                  wb_masters_i(4).cyc and s_mcyc(4)  when(s_msel="100") else
+                  wb_masters_i(5).cyc and s_mcyc(5)  when(s_msel="101") else
+                  wb_masters_i(6).cyc and s_mcyc(6)  when(s_msel="110") else
+                  wb_masters_i(7).cyc and s_mcyc(7)  when(s_msel="111") else
+                  '0';
+
+    wb_slave_o.stb <= wb_masters_i(0).stb when(s_msel="000") else
+                      wb_masters_i(1).stb when(s_msel="001") else
+                      wb_masters_i(2).stb when(s_msel="010") else
+                      wb_masters_i(3).stb when(s_msel="011") else
+                      wb_masters_i(4).stb when(s_msel="100") else
+                      wb_masters_i(5).stb when(s_msel="101") else
+                      wb_masters_i(6).stb when(s_msel="110") else
+                      wb_masters_i(7).stb when(s_msel="111") else
+                      '0';
+
+end bahaviour;
diff --git a/modules/wishbone/wb_conmax/wb_conmax_top.vhd b/modules/wishbone/wb_conmax/wb_conmax_top.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..377485eb8f71e61afdb550748e09e0e698330af2
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wb_conmax_top.vhd
@@ -0,0 +1,323 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_top.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-12
+-- Last update: 2010-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Wishbone Interconnect Matrix, up to 8 Masters and 16 Slaves. Features 
+-- prioritized arbiter inside each Slave Interface (1, 2 of 4 priority levels).
+-- Allows the parallel communication between masters and slaves on 
+-- different interfaces.
+-- It is the WISHBONE Conmax IP Core from opencores.org rewritten in VHDL (from
+-- Verilog) with some code optimalization.
+--
+-------------------------------------------------------------------------------
+-- Copyright (C) 2000-2002 Rudolf Usselmann
+-- Copyright (c) 2011 Grzegorz Daniluk (VHDL port)
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-12  1.0      greg.d          Created
+-- 2011-02-16  1.1      greg.d          Using generates and types
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+use work.wbconmax_pkg.all;
+
+entity wb_conmax_top is
+  generic(
+    g_rf_addr     : integer range 0 to 15 := 15   --0xf
+  );
+  port(
+    clk_i : std_logic;
+    rst_i : std_logic;
+
+    wb_masters_i : in  t_conmax_masters_i;
+    wb_masters_o : out t_conmax_masters_o;
+    wb_slaves_i  : in  t_conmax_slaves_i;
+    wb_slaves_o  : out t_conmax_slaves_o
+  );
+end wb_conmax_top;
+
+architecture struct of wb_conmax_top is
+  
+  component wb_conmax_master_if is
+    port(
+      clk_i : in std_logic;
+      rst_i : in std_logic;
+
+      --Master interface
+      wb_master_i : in  t_wb_i;
+      wb_master_o : out t_wb_o;
+
+      --Slaves(0 to 15) interface
+      wb_slaves_i : in  t_conmax_slaves_i;
+      wb_slaves_o : out t_conmax_slaves_o
+    ); 
+  end component;
+
+  component wb_conmax_slave_if is
+    generic(
+      g_pri_sel : integer := 2
+    );
+    port(
+      clk_i        : in std_logic;
+      rst_i        : in std_logic;
+      conf_i       : in std_logic_vector(15 downto 0);
+  
+      --Slave interface
+      wb_slave_i   : in  t_wb_o;
+      wb_slave_o   : out t_wb_i;
+
+      --Master (0 to 7) interfaces
+      wb_masters_i : in  t_conmax_masters_i;
+      wb_masters_o : out t_conmax_masters_o
+    );
+  end component;
+
+  component wb_conmax_rf is
+    generic(
+      g_rf_addr : integer range 0 to 15 := 15  --0xF
+    );
+    port(
+      clk_i : in std_logic;
+      rst_i : in std_logic;
+      
+      --Internal WB interface
+      int_wb_i  : in  t_wb_i;
+      int_wb_o  : out t_wb_o;
+      --External WB interface
+      ext_wb_i  : in  t_wb_o;
+      ext_wb_o  : out t_wb_i;
+
+      --Configuration regs
+      conf_o    : out t_rf_conf
+    );
+  end component;
+
+
+  signal intwb_s15_i  : t_wb_o;
+  signal intwb_s15_o  : t_wb_i;
+
+  --M0Sx
+  signal m0_slaves_i : t_conmax_slaves_i;
+  signal m0_slaves_o : t_conmax_slaves_o;
+  signal m1_slaves_i : t_conmax_slaves_i;
+  signal m1_slaves_o : t_conmax_slaves_o;
+  signal m2_slaves_i : t_conmax_slaves_i;
+  signal m2_slaves_o : t_conmax_slaves_o;
+  signal m3_slaves_i : t_conmax_slaves_i;
+  signal m3_slaves_o : t_conmax_slaves_o;
+  signal m4_slaves_i : t_conmax_slaves_i;
+  signal m4_slaves_o : t_conmax_slaves_o;
+  signal m5_slaves_i : t_conmax_slaves_i;
+  signal m5_slaves_o : t_conmax_slaves_o;
+  signal m6_slaves_i : t_conmax_slaves_i;
+  signal m6_slaves_o : t_conmax_slaves_o;
+  signal m7_slaves_i : t_conmax_slaves_i;
+  signal m7_slaves_o : t_conmax_slaves_o;
+
+
+  signal s_conf   : t_rf_conf;
+  
+  signal s15_wb_masters_i : t_conmax_masters_i;
+  signal s15_wb_masters_o : t_conmax_masters_o;
+
+begin
+
+  --Master interfaces
+  M0: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      --Master interface
+      wb_master_i => wb_masters_i(0),
+      wb_master_o => wb_masters_o(0),
+      --Slaves(0 to 15) interface
+      wb_slaves_i => m0_slaves_i,
+      wb_slaves_o => m0_slaves_o
+    );
+
+  M1: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+
+      wb_master_i => wb_masters_i(1),
+      wb_master_o => wb_masters_o(1),
+      wb_slaves_i => m1_slaves_i,
+      wb_slaves_o => m1_slaves_o
+    );
+
+  M2: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(2),
+      wb_master_o => wb_masters_o(2),
+      wb_slaves_i => m2_slaves_i,
+      wb_slaves_o => m2_slaves_o
+    );
+     
+  M3: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(3),
+      wb_master_o => wb_masters_o(3),
+      wb_slaves_i => m3_slaves_i,
+      wb_slaves_o => m3_slaves_o
+    );
+
+  M4: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(4),
+      wb_master_o => wb_masters_o(4),
+      wb_slaves_i => m4_slaves_i,
+      wb_slaves_o => m4_slaves_o
+    );
+
+  M5: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(5),
+      wb_master_o => wb_masters_o(5),
+      wb_slaves_i => m5_slaves_i,
+      wb_slaves_o => m5_slaves_o
+    );
+
+  M6: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(6),
+      wb_master_o => wb_masters_o(6),
+      wb_slaves_i => m6_slaves_i,
+      wb_slaves_o => m6_slaves_o
+    );
+
+  M7: wb_conmax_master_if
+    port map(
+      clk_i => clk_i,
+      rst_i => rst_i,
+  
+      wb_master_i => wb_masters_i(7),
+      wb_master_o => wb_masters_o(7),
+      wb_slaves_i => m7_slaves_i,
+      wb_slaves_o => m7_slaves_o
+    );
+
+  --------------------------------------------------
+  --Slave interfaces
+  S_GEN: for I in 0 to 14 generate
+    SLV: wb_conmax_slave_if
+      generic map(
+        g_pri_sel => g_pri_sel(I)
+      )
+      port map(
+        clk_i  => clk_i, 
+        rst_i  => rst_i,
+        conf_i => s_conf(I),
+    
+        --Slave interface
+        wb_slave_i => wb_slaves_i(I),
+        wb_slave_o => wb_slaves_o(I),
+
+        --Interfaces to masters
+        wb_masters_i(0) => m0_slaves_o(I),
+        wb_masters_i(1) => m1_slaves_o(I),
+        wb_masters_i(2) => m2_slaves_o(I),
+        wb_masters_i(3) => m3_slaves_o(I),
+        wb_masters_i(4) => m4_slaves_o(I),
+        wb_masters_i(5) => m5_slaves_o(I),
+        wb_masters_i(6) => m6_slaves_o(I),
+        wb_masters_i(7) => m7_slaves_o(I),
+        
+        wb_masters_o(0) => m0_slaves_i(I),
+        wb_masters_o(1) => m1_slaves_i(I),
+        wb_masters_o(2) => m2_slaves_i(I),
+        wb_masters_o(3) => m3_slaves_i(I),
+        wb_masters_o(4) => m4_slaves_i(I),
+        wb_masters_o(5) => m5_slaves_i(I),
+        wb_masters_o(6) => m6_slaves_i(I),
+        wb_masters_o(7) => m7_slaves_i(I)
+      );
+  end generate;
+
+
+  s15_wb_masters_i(0) <= m0_slaves_o(15);
+  s15_wb_masters_i(1) <= m1_slaves_o(15);
+  s15_wb_masters_i(2) <= m2_slaves_o(15);
+  s15_wb_masters_i(3) <= m3_slaves_o(15);
+  s15_wb_masters_i(4) <= m4_slaves_o(15);
+  s15_wb_masters_i(5) <= m5_slaves_o(15);
+  s15_wb_masters_i(6) <= m6_slaves_o(15);
+  s15_wb_masters_i(7) <= m7_slaves_o(15);
+  
+  m0_slaves_i(15) <= s15_wb_masters_o(0);
+  m1_slaves_i(15) <= s15_wb_masters_o(1);
+  m2_slaves_i(15) <= s15_wb_masters_o(2);
+  m3_slaves_i(15) <= s15_wb_masters_o(3);
+  m4_slaves_i(15) <= s15_wb_masters_o(4);
+  m5_slaves_i(15) <= s15_wb_masters_o(5);
+  m6_slaves_i(15) <= s15_wb_masters_o(6);
+  m7_slaves_i(15) <= s15_wb_masters_o(7);
+
+
+  SLV15: wb_conmax_slave_if
+    generic map(
+      g_pri_sel => g_pri_sel(15)
+    )
+    port map(
+      clk_i  => clk_i, 
+      rst_i  => rst_i,
+      conf_i => s_conf(15),
+
+      --Slave interface
+      wb_slave_i => intwb_s15_i,
+      wb_slave_o => intwb_s15_o,
+
+      --Interfaces to masters
+      wb_masters_i => s15_wb_masters_i,
+      wb_masters_o => s15_wb_masters_o
+    );
+   
+  ---------------------------------------
+  --Register File
+
+  RF: wb_conmax_rf
+    generic map(
+      g_rf_addr => g_rf_addr
+    )
+    port map(
+      clk_i   => clk_i,
+      rst_i   => rst_i,
+      
+      int_wb_i  => intwb_s15_o,
+      int_wb_o  => intwb_s15_i,
+      ext_wb_i  => wb_slaves_i(15),
+      ext_wb_o  => wb_slaves_o(15),
+      
+      conf_o    => s_conf
+    );
+
+end struct;
diff --git a/modules/wishbone/wb_conmax/wbconmax_pkg.vhd b/modules/wishbone/wb_conmax/wbconmax_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..a3497ce2759299a12ab82d5163b4834df1c7d689
--- /dev/null
+++ b/modules/wishbone/wb_conmax/wbconmax_pkg.vhd
@@ -0,0 +1,63 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone interconnect matrix for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wbconmax_pkg.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-02-16
+-- Last update: 2010-02-16
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Package for WB interconnect matrix. Defines basic constants and types used
+-- to simplify WB interface connections.
+-------------------------------------------------------------------------------
+-- Copyright (c) 2011 Grzegorz Daniluk
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-16  1.1      greg.d          Using generates and types
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+package wbconmax_pkg is
+
+  type t_rf_conf  is array(0 to 15) of std_logic_vector(15 downto 0);
+
+  constant c_dw : integer := 32;  --data width
+  constant c_aw : integer := 18;  --address width = max 14b (for dpram) + 4b 
+                                  --for wb_intercom (Mst selects Slave)
+  constant c_sw : integer := 4;   -- c_dw/8
+
+  --g_pri_selx := 0 (1 priority level), 1 (2 pri levels) or 2 (4 pri levels).
+  type t_pri_sels is array(0 to 15) of integer range 0 to 3;  
+  constant g_pri_sel : t_pri_sels := (2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2);  
+
+  --as in original WB conmax spec and implementation, those are
+  --inputs fed by WB Master from outside 
+  type t_wb_i is record
+    data  : std_logic_vector(c_dw-1 downto 0);
+    addr  : std_logic_vector(c_aw-1 downto 0);
+    sel   : std_logic_vector(c_sw-1 downto 0);
+    we    : std_logic;
+    cyc   : std_logic;
+    stb   : std_logic;
+  end record;
+
+  type t_wb_o is record
+    data  : std_logic_vector(c_dw-1 downto 0);
+    ack   : std_logic;
+    err   : std_logic;
+    rty   : std_logic;
+  end record;
+
+  type t_conmax_masters_i is array(0 to 7) of t_wb_i;
+  type t_conmax_masters_o is array(0 to 7) of t_wb_o;
+  type t_conmax_slaves_i  is array(0 to 15) of t_wb_o;
+  type t_conmax_slaves_o  is array(0 to 15) of t_wb_i;
+
+end wbconmax_pkg;
diff --git a/modules/wishbone/wb_gpio_port/manifest.py b/modules/wishbone/wb_gpio_port/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd4aae4f47d29d26476e0b1ebf6f0a232f28ade5
--- /dev/null
+++ b/modules/wishbone/wb_gpio_port/manifest.py
@@ -0,0 +1 @@
+files = ["wb_gpio_port.vhd"];
\ No newline at end of file
diff --git a/modules/wishbone/wb_gpio_port/wb_gpio_port.vhd b/modules/wishbone/wb_gpio_port/wb_gpio_port.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..5f5ddbb490e0394ad8056f55cf92df25b34ac00a
--- /dev/null
+++ b/modules/wishbone/wb_gpio_port/wb_gpio_port.vhd
@@ -0,0 +1,147 @@
+------------------------------------------------------------------------------
+-- Title      : Wishbone GPIO port
+-- Project    : White Rabbit Switch
+------------------------------------------------------------------------------
+-- Author     : Tomasz Wlostowski
+-- Company    : CERN BE-Co-HT
+-- Created    : 2010-05-18
+-- Last update: 2011-04-06
+-- Platform   : FPGA-generic
+-- Standard   : VHDL'87
+-------------------------------------------------------------------------------
+-- Description: Bidirectional GPIO port of configurable width (1 to 32 bits).
+-------------------------------------------------------------------------------
+-- Copyright (c) 2010 Tomasz Wlostowski
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2010-05-18  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+library work;
+
+use work.wishbone_pkg.all;
+use work.common_components.all;
+
+entity wb_gpio_port is
+  generic(g_num_pins : natural := 8     -- number of GPIO pins
+          );
+  port(
+-- System reset, active low
+    sys_rst_n_i : in std_logic;
+
+-------------------------------------------------------------------------------
+-- Wishbone bus
+-------------------------------------------------------------------------------
+
+    wb_clk_i  : in  std_logic;
+    wb_sel_i  : in  std_logic;
+    wb_cyc_i  : in  std_logic;
+    wb_stb_i  : in  std_logic;
+    wb_we_i   : in  std_logic;
+    wb_addr_i : in  std_logic_vector(2 downto 0);
+    wb_data_i : in  std_logic_vector(31 downto 0);
+    wb_data_o : out std_logic_vector(31 downto 0);
+    wb_ack_o  : out std_logic;
+
+-- GPIO pin vector
+    gpio_b : inout std_logic_vector(g_num_pins-1 downto 0)
+    );
+end wb_gpio_port;
+
+
+architecture behavioral of wb_gpio_port is
+
+  constant c_GPIO_REG_CODR : std_logic_vector(2 downto 0) := "000";  -- *reg* clear output register
+  constant c_GPIO_REG_SODR : std_logic_vector(2 downto 0) := "001";  -- *reg* set output register
+  constant c_GPIO_REG_DDR  : std_logic_vector(2 downto 0) := "010";  -- *reg* data direction register
+  constant c_GPIO_REG_PSR  : std_logic_vector(2 downto 0) := "011";  -- *reg* pin state register
+
+
+  signal out_reg, in_reg, dir_reg : std_logic_vector(g_num_pins-1 downto 0);
+  signal gpio_in_synced           : std_logic_vector(g_num_pins-1 downto 0);
+  signal ack_int                  : std_logic;
+
+begin
+
+
+  GEN_SYNC_FFS : for i in 0 to g_num_pins-1 generate
+    INPUT_SYNC : sync_ffs
+      generic map (
+        g_sync_edge => "positive")
+      port map (
+        rst_n_i  => sys_rst_n_i,
+        clk_i    => wb_clk_i,
+        data_i   => gpio_b(i),
+        synced_o => gpio_in_synced(i),
+        npulse_o => open
+        );
+
+  end generate GEN_SYNC_FFS;
+
+
+  process (wb_clk_i, sys_rst_n_i)
+  begin
+    if sys_rst_n_i = '0' then
+      dir_reg                          <= (others => '0');
+      out_reg                          <= (others => '0');
+      ack_int                          <= '0';
+      wb_data_o(g_num_pins-1 downto 0) <= (others => '0');
+    elsif rising_edge(wb_clk_i) then
+      if(ack_int = '1') then
+        ack_int <= '0';
+      elsif(wb_cyc_i = '1') and (wb_sel_i = '1') and (wb_stb_i = '1') then
+        if(wb_we_i = '1') then
+          case wb_addr_i(2 downto 0) is
+            when c_GPIO_REG_SODR =>
+              out_reg <= out_reg or wb_data_i(g_num_pins-1 downto 0);
+              ack_int <= '1';
+            when c_GPIO_REG_CODR =>
+              out_reg <= out_reg and (not wb_data_i(g_num_pins-1 downto 0));
+              ack_int <= '1';
+            when c_GPIO_REG_DDR =>
+              dir_reg <= wb_data_i(g_num_pins-1 downto 0);
+              ack_int <= '1';
+            when others =>
+              ack_int <= '1';
+          end case;
+        else
+          case wb_addr_i(2 downto 0) is
+            when c_GPIO_REG_DDR =>
+              wb_data_o(g_num_pins-1 downto 0) <= dir_reg;
+              ack_int                          <= '1';
+              
+            when c_GPIO_REG_PSR =>
+              wb_data_o(g_num_pins-1 downto 0) <= gpio_in_synced;
+              ack_int                          <= '1';
+            when others =>
+              ack_int <= '1';
+          end case;
+        end if;
+      else
+        ack_int <= '0';
+      end if;
+    end if;
+  end process;
+
+  gpio_out_tristate : process (out_reg, dir_reg)
+  begin
+    for i in 0 to g_num_pins-1 loop
+      if(dir_reg(i) = '1') then
+        gpio_b(i) <= out_reg(i);
+      else
+        gpio_b(i) <= 'Z';
+      end if;
+      
+    end loop;
+  end process gpio_out_tristate;
+
+  wb_ack_o <= ack_int;
+end behavioral;
+
+
diff --git a/modules/wishbone/wb_i2c_master/i2c_master_bit_ctrl.vhd b/modules/wishbone/wb_i2c_master/i2c_master_bit_ctrl.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..a095fde0e882d3b0d6322145e9396759b223b9c2
--- /dev/null
+++ b/modules/wishbone/wb_i2c_master/i2c_master_bit_ctrl.vhd
@@ -0,0 +1,576 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 I2C Master Core; bit-controller             ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_bit_ctrl.vhd,v 1.17 2009-02-04 20:17:34 rherveille Exp $
+--
+--  $Date: 2009-02-04 20:17:34 $
+--  $Revision: 1.17 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               $Log: not supported by cvs2svn $
+--               Revision 1.16  2009/01/20 20:40:36  rherveille
+--               Fixed type iscl_oen instead of scl_oen
+--
+--               Revision 1.15  2009/01/20 10:34:51  rherveille
+--               Added SCL clock synchronization logic
+--               Fixed slave_wait signal generation
+--
+--               Revision 1.14  2006/10/11 12:10:13  rherveille
+--               Added missing semicolons ';' on endif
+--
+--               Revision 1.13  2006/10/06 10:48:24  rherveille
+--               fixed short scl high pulse after clock stretch
+--
+--               Revision 1.12  2004/05/07 11:53:31  rherveille
+--               Fixed previous fix :) Made a variable vs signal mistake.
+--
+--               Revision 1.11  2004/05/07 11:04:00  rherveille
+--               Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
+--
+--               Revision 1.10  2004/02/27 07:49:43  rherveille
+--               Fixed a bug in the arbitration-lost signal generation. VHDL version only.
+--
+--               Revision 1.9  2003/08/12 14:48:37  rherveille
+--               Forgot an 'end if' :-/
+--
+--               Revision 1.8  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.7  2003/02/05 00:06:02  rherveille
+--               Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
+--
+--               Revision 1.6  2003/02/01 02:03:06  rherveille
+--               Fixed a few 'arbitration lost' bugs. VHDL version only.
+--
+--               Revision 1.5  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.4  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.3  2002/10/30 18:09:53  rherveille
+--               Fixed some reported minor start/stop generation timing issuess.
+--
+--               Revision 1.2  2002/06/15 07:37:04  rherveille
+--               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
+--
+--               Revision 1.1  2001/11/05 12:02:33  rherveille
+--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
+--               Code updated, is now up-to-date to doc. rev.0.4.
+--               Added headers.
+--
+
+
+--
+-------------------------------------
+-- Bit controller section
+------------------------------------
+--
+-- Translate simple commands into SCL/SDA transitions
+-- Each command has 5 states, A/B/C/D/idle
+--
+-- start:    SCL  ~~~~~~~~~~~~~~\____
+--           SDA  XX/~~~~~~~\______
+--                x | A | B | C | D | i
+--
+-- repstart  SCL  ______/~~~~~~~\___
+--           SDA  __/~~~~~~~\______
+--                x | A | B | C | D | i
+--
+-- stop      SCL  _______/~~~~~~~~~~~
+--           SDA  ==\___________/~~~~~
+--                x | A | B | C | D | i
+--
+--- write    SCL  ______/~~~~~~~\____
+--           SDA  XXX===============XX
+--                x | A | B | C | D | i
+--
+--- read     SCL  ______/~~~~~~~\____
+--           SDA  XXXXXXX=XXXXXXXXXXX
+--                x | A | B | C | D | i
+--
+
+-- Timing:      Normal mode     Fast mode
+-----------------------------------------------------------------
+-- Fscl         100KHz          400KHz
+-- Th_scl       4.0us           0.6us   High period of SCL
+-- Tl_scl       4.7us           1.3us   Low period of SCL
+-- Tsu:sta      4.7us           0.6us   setup time for a repeated start condition
+-- Tsu:sto      4.0us           0.6us   setup time for a stop conditon
+-- Tbuf         4.7us           1.3us   Bus free time between a stop and start condition
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity i2c_master_bit_ctrl is
+    port (
+          clk    : in std_logic;
+          rst    : in std_logic;
+          nReset : in std_logic;
+          ena    : in std_logic;                     -- core enable signal
+
+          clk_cnt : in unsigned(15 downto 0);        -- clock prescale value
+
+          cmd     : in std_logic_vector(3 downto 0);
+          cmd_ack : out std_logic;                   -- command completed
+          busy    : out std_logic;                   -- i2c bus busy
+          al      : out std_logic;                   -- arbitration lost
+
+          din  : in std_logic;
+          dout : out std_logic;
+
+          -- i2c lines
+          scl_i   : in std_logic;                    -- i2c clock line input
+          scl_o   : out std_logic;                   -- i2c clock line output
+          scl_oen : out std_logic;                   -- i2c clock line output enable, active low
+          sda_i   : in std_logic;                    -- i2c data line input
+          sda_o   : out std_logic;                   -- i2c data line output
+          sda_oen : out std_logic                    -- i2c data line output enable, active low
+    );
+end entity i2c_master_bit_ctrl;
+
+architecture structural of i2c_master_bit_ctrl is
+    constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
+    constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
+    constant I2C_CMD_STOP   : std_logic_vector(3 downto 0) := "0010";
+    constant I2C_CMD_READ   : std_logic_vector(3 downto 0) := "0100";
+    constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
+
+    type states is (idle, start_a, start_b, start_c, start_d, start_e,
+                    stop_a, stop_b, stop_c, stop_d, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);
+    signal c_state : states;
+
+    signal iscl_oen, isda_oen   : std_logic;             -- internal I2C lines
+    signal sda_chk              : std_logic;             -- check SDA status (multi-master arbitration)
+    signal dscl_oen             : std_logic;             -- delayed scl_oen signals
+    signal sSCL, sSDA           : std_logic;             -- synchronized SCL and SDA inputs
+    signal dSCL, dSDA           : std_logic;             -- delayed versions ofsSCL and sSDA
+    signal clk_en               : std_logic;             -- statemachine clock enable
+    signal scl_sync, slave_wait : std_logic;             -- clock generation signals
+    signal ial                  : std_logic;             -- internal arbitration lost signal
+    signal cnt                  : unsigned(15 downto 0); -- clock divider counter (synthesis)
+
+begin
+    -- whenever the slave is not ready it can delay the cycle by pulling SCL low
+    -- delay scl_oen
+    process (clk, nReset)
+    begin
+        if (nReset = '0') then
+            dscl_oen <= '0';
+        elsif (clk'event and clk = '1') then
+            dscl_oen <= iscl_oen;
+        end if;
+    end process;
+
+    -- slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
+    -- slave_wait remains asserted until the slave releases SCL
+    process (clk, nReset)
+    begin
+        if (nReset = '0') then
+            slave_wait <= '0';
+        elsif (clk'event and clk = '1') then
+               slave_wait <= (iscl_oen and not dscl_oen and not sSCL) or (slave_wait and not sSCL);
+        end if;
+    end process;
+
+    -- master drives SCL high, but another master pulls it low
+    -- master start counting down its low cycle now (clock synchronization)
+    scl_sync <= dSCL and not sSCL and iscl_oen;
+
+    -- generate clk enable signal
+    gen_clken: process(clk, nReset)
+    begin
+        if (nReset = '0') then
+            cnt    <= (others => '0');
+            clk_en <= '1';
+        elsif (clk'event and clk = '1') then
+               if ((rst = '1') or (cnt = 0) or (ena = '0') or (scl_sync = '1')) then
+                   cnt    <= clk_cnt;
+                   clk_en <= '1';
+               elsif (slave_wait = '1') then
+                   cnt    <= cnt;
+                   clk_en <= '0';
+               else
+                   cnt    <= cnt -1;
+                   clk_en <= '0';
+               end if;
+        end if;
+    end process gen_clken;
+
+
+    -- generate bus status controller
+    bus_status_ctrl: block
+      signal cSCL, cSDA    : std_logic_vector( 1 downto 0); -- capture SDA and SCL
+      signal fSCL, fSDA    : std_logic_vector( 2 downto 0); -- filter inputs for SCL and SDA
+      signal filter_cnt    : unsigned(13 downto 0);         -- clock divider for filter
+      signal sta_condition : std_logic;                     -- start detected
+      signal sto_condition : std_logic;                     -- stop detected
+      signal cmd_stop      : std_logic;                     -- STOP command
+      signal ibusy         : std_logic;                     -- internal busy signal
+    begin
+        -- capture SCL and SDA
+        capture_scl_sda: process(clk, nReset)
+        begin
+            if (nReset = '0') then
+                cSCL <= "00";
+                cSDA <= "00";
+            elsif (clk'event and clk = '1') then
+                if (rst = '1') then
+                    cSCL <= "00";
+                    cSDA <= "00";
+                else
+                    cSCL <= (cSCL(0) & scl_i);
+                    cSDA <= (cSDA(0) & sda_i);
+                end if;
+            end if;
+        end process capture_scl_sda;
+
+        -- filter SCL and SDA; (attempt to) remove glitches
+        filter_divider: process(clk, nReset)
+        begin
+            if (nReset = '0') then
+                filter_cnt <= (others => '0');
+            elsif (clk'event and clk = '1') then
+                if ( (rst = '1') or (ena = '0') ) then
+                    filter_cnt <= (others => '0');
+                elsif (filter_cnt = 0) then
+                    filter_cnt <= clk_cnt(15 downto 2);
+                else
+                    filter_cnt <= filter_cnt -1;
+                end if;
+            end if;
+        end process filter_divider;
+
+        filter_scl_sda: process(clk, nReset)
+        begin
+            if (nReset = '0') then
+                fSCL <= (others => '1');
+                fSDA <= (others => '1');
+            elsif (clk'event and clk = '1') then
+                if (rst = '1') then
+                    fSCL <= (others => '1');
+                    fSDA <= (others => '1');
+                elsif (filter_cnt = 0) then
+                    fSCL <= (fSCL(1 downto 0) & cSCL(1));
+                    fSDA <= (fSDA(1 downto 0) & cSDA(1));
+                end if;
+            end if;
+        end process filter_scl_sda;
+
+       -- generate filtered SCL and SDA signals
+       scl_sda: process(clk, nReset)
+       begin
+           if (nReset = '0') then
+               sSCL <= '1';
+               sSDA <= '1';
+
+               dSCL <= '1';
+               dSDA <= '1';
+           elsif (clk'event and clk = '1') then
+               if (rst = '1') then
+                   sSCL <= '1';
+                   sSDA <= '1';
+
+                   dSCL <= '1';
+                   dSDA <= '1';
+               else
+                  sSCL <= (fSCL(2) and fSCL(1)) or
+                          (fSCL(2) and fSCL(0)) or
+                          (fSCL(1) and fSCL(0));
+                  sSDA <= (fSDA(2) and fSDA(1)) or
+                          (fSDA(2) and fSDA(0)) or
+                          (fSDA(1) and fSDA(0));
+
+                  dSCL <= sSCL;
+                  dSDA <= sSDA;
+               end if;
+           end if;
+       end process scl_sda;
+
+
+       -- detect start condition => detect falling edge on SDA while SCL is high
+       -- detect stop condition  => detect rising edge on SDA while SCL is high
+       detect_sta_sto: process(clk, nReset)
+       begin
+           if (nReset = '0') then
+               sta_condition <= '0';
+               sto_condition <= '0';
+           elsif (clk'event and clk = '1') then
+               if (rst = '1') then
+                   sta_condition <= '0';
+                   sto_condition <= '0';
+               else
+                   sta_condition <= (not sSDA and dSDA) and sSCL;
+                   sto_condition <= (sSDA and not dSDA) and sSCL;
+               end if;
+           end if;
+       end process detect_sta_sto;
+
+
+       -- generate i2c-bus busy signal
+       gen_busy: process(clk, nReset)
+       begin
+           if (nReset = '0') then
+               ibusy <= '0';
+           elsif (clk'event and clk = '1') then
+               if (rst = '1') then
+                   ibusy <= '0';
+               else
+                   ibusy <= (sta_condition or ibusy) and not sto_condition;
+               end if;
+           end if;
+       end process gen_busy;
+       busy <= ibusy;
+
+
+       -- generate arbitration lost signal
+       -- aribitration lost when:
+       -- 1) master drives SDA high, but the i2c bus is low
+       -- 2) stop detected while not requested (detect during 'idle' state)
+       gen_al: process(clk, nReset)
+       begin
+           if (nReset = '0') then
+               cmd_stop  <= '0';
+               ial       <= '0';
+           elsif (clk'event and clk = '1') then
+               if (rst = '1') then
+                   cmd_stop  <= '0';
+                   ial       <= '0';
+               else
+                   if (clk_en = '1') then
+                       if (cmd = I2C_CMD_STOP) then
+                           cmd_stop <= '1';
+                       else
+                           cmd_stop <= '0';
+                       end if;
+                   end if;
+
+                   if (c_state = idle) then
+                       ial <= (sda_chk and not sSDA and isda_oen) or (sto_condition and not cmd_stop);
+                   else
+                       ial <= (sda_chk and not sSDA and isda_oen);
+                   end if;
+               end if;
+          end if;
+       end process gen_al;
+       al <= ial;
+
+
+       -- generate dout signal, store dout on rising edge of SCL
+       gen_dout: process(clk, nReset)
+       begin
+           if (nReset = '0') then
+               dout <= '0';
+           elsif (clk'event and clk = '1') then
+               if (sSCL = '1' and dSCL = '0') then
+                   dout <= sSDA;
+               end if;
+           end if;
+       end process gen_dout;
+    end block bus_status_ctrl;
+
+
+    -- generate statemachine
+    nxt_state_decoder : process (clk, nReset)
+    begin
+        if (nReset = '0') then
+            c_state  <= idle;
+            cmd_ack  <= '0';
+            iscl_oen <= '1';
+            isda_oen <= '1';
+            sda_chk  <= '0';
+        elsif (clk'event and clk = '1') then
+               if (rst = '1' or ial = '1') then
+                   c_state  <= idle;
+                   cmd_ack  <= '0';
+                   iscl_oen <= '1';
+                   isda_oen <= '1';
+                   sda_chk  <= '0';
+               else
+                   cmd_ack <= '0'; -- default no acknowledge
+
+                   if (clk_en = '1') then
+                       case (c_state) is
+                             -- idle
+                             when idle =>
+                                 case cmd is
+                                     when I2C_CMD_START => c_state <= start_a;
+                                     when I2C_CMD_STOP  => c_state <= stop_a;
+                                     when I2C_CMD_WRITE => c_state <= wr_a;
+                                     when I2C_CMD_READ  => c_state <= rd_a;
+                                     when others        => c_state <= idle; -- NOP command
+                                 end case;
+
+                                 iscl_oen <= iscl_oen; -- keep SCL in same state
+                                 isda_oen <= isda_oen; -- keep SDA in same state
+                                 sda_chk  <= '0';      -- don't check SDA
+
+                             -- start
+                             when start_a =>
+                                 c_state  <= start_b;
+                                 iscl_oen <= iscl_oen; -- keep SCL in same state (for repeated start)
+                                 isda_oen <= '1';      -- set SDA high
+                                 sda_chk  <= '0';      -- don't check SDA
+
+                             when start_b =>
+                                 c_state  <= start_c;
+                                 iscl_oen <= '1'; -- set SCL high
+                                 isda_oen <= '1'; -- keep SDA high
+                                 sda_chk  <= '0'; -- don't check SDA
+
+                             when start_c =>
+                                 c_state  <= start_d;
+                                 iscl_oen <= '1'; -- keep SCL high
+                                 isda_oen <= '0'; -- set SDA low
+                                 sda_chk  <= '0'; -- don't check SDA
+
+                             when start_d =>
+                                 c_state  <= start_e;
+                                 iscl_oen <= '1'; -- keep SCL high
+                                 isda_oen <= '0'; -- keep SDA low
+                                 sda_chk  <= '0'; -- don't check SDA
+
+                             when start_e =>
+                                 c_state  <= idle;
+                                 cmd_ack  <= '1'; -- command completed
+                                 iscl_oen <= '0'; -- set SCL low
+                                 isda_oen <= '0'; -- keep SDA low
+                                 sda_chk  <= '0'; -- don't check SDA
+
+                             -- stop
+                            when stop_a =>
+                                c_state  <= stop_b;
+                                iscl_oen <= '0'; -- keep SCL low
+                                isda_oen <= '0'; -- set SDA low
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when stop_b =>
+                                c_state  <= stop_c;
+                                iscl_oen <= '1'; -- set SCL high
+                                isda_oen <= '0'; -- keep SDA low
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when stop_c =>
+                                c_state  <= stop_d;
+                                iscl_oen <= '1'; -- keep SCL high
+                                isda_oen <= '0'; -- keep SDA low
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when stop_d =>
+                                c_state  <= idle;
+                                cmd_ack  <= '1'; -- command completed
+                                iscl_oen <= '1'; -- keep SCL high
+                                isda_oen <= '1'; -- set SDA high
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            -- read
+                            when rd_a =>
+                                c_state  <= rd_b;
+                                iscl_oen <= '0'; -- keep SCL low
+                                isda_oen <= '1'; -- tri-state SDA
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when rd_b =>
+                                c_state  <= rd_c;
+                                iscl_oen <= '1'; -- set SCL high
+                                isda_oen <= '1'; -- tri-state SDA
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when rd_c =>
+                                c_state  <= rd_d;
+                                iscl_oen <= '1'; -- keep SCL high
+                                isda_oen <= '1'; -- tri-state SDA
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            when rd_d =>
+                                c_state  <= idle;
+                                cmd_ack  <= '1'; -- command completed
+                                iscl_oen <= '0'; -- set SCL low
+                                isda_oen <= '1'; -- tri-state SDA
+                                sda_chk  <= '0'; -- don't check SDA
+
+                            -- write
+                            when wr_a =>
+                                c_state  <= wr_b;
+                                iscl_oen <= '0'; -- keep SCL low
+                                isda_oen <= din; -- set SDA
+                                sda_chk  <= '0'; -- don't check SDA (SCL low)
+
+                            when wr_b =>
+                                c_state  <= wr_c;
+                                iscl_oen <= '1'; -- set SCL high
+                                isda_oen <= din; -- keep SDA
+                                sda_chk  <= '0'; -- don't check SDA yet
+                                                 -- Allow some more time for SDA and SCL to settle
+
+                            when wr_c =>
+                                c_state  <= wr_d;
+                                iscl_oen <= '1'; -- keep SCL high
+                                isda_oen <= din; -- keep SDA
+                                sda_chk  <= '1'; -- check SDA
+
+                            when wr_d =>
+                                c_state  <= idle;
+                                cmd_ack  <= '1'; -- command completed
+                                iscl_oen <= '0'; -- set SCL low
+                                isda_oen <= din; -- keep SDA
+                                sda_chk  <= '0'; -- don't check SDA (SCL low)
+
+                            when others =>
+
+                       end case;
+                   end if;
+               end if;
+        end if;
+    end process nxt_state_decoder;
+
+
+    -- assign outputs
+    scl_o   <= '0';
+    scl_oen <= iscl_oen;
+    sda_o   <= '0';
+    sda_oen <= isda_oen;
+end architecture structural;
+
diff --git a/modules/wishbone/wb_i2c_master/i2c_master_byte_ctrl.vhd b/modules/wishbone/wb_i2c_master/i2c_master_byte_ctrl.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..8e4d02a5bba06586c75d1c68066d7a4258876463
--- /dev/null
+++ b/modules/wishbone/wb_i2c_master/i2c_master_byte_ctrl.vhd
@@ -0,0 +1,368 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 compl. I2C Master Core; byte-controller     ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004-02-18 11:41:48 rherveille Exp $
+--
+--  $Date: 2004-02-18 11:41:48 $
+--  $Revision: 1.5 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               $Log: not supported by cvs2svn $
+--               Revision 1.4  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.3  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.2  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.1  2001/11/05 12:02:33  rherveille
+--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
+--               Code updated, is now up-to-date to doc. rev.0.4.
+--               Added headers.
+--
+
+
+
+
+--
+------------------------------------------
+-- Byte controller section
+------------------------------------------
+--
+library ieee;
+use ieee.std_logic_1164.all;
+--use ieee.std_logic_arith.all;
+use ieee.numeric_std.all;
+
+entity i2c_master_byte_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
+		nReset : in std_logic;	-- asynchornous active low reset (FPGA compatible)
+		ena    : in std_logic; -- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);	-- 4x SCL
+
+		-- input signals
+		start,
+		stop,
+		read,
+		write,
+		ack_in : std_logic;
+		din    : in std_logic_vector(7 downto 0);
+
+		-- output signals
+		cmd_ack  : out std_logic; -- command done
+		ack_out  : out std_logic;
+		i2c_busy : out std_logic; -- arbitration lost
+		i2c_al   : out std_logic; -- i2c bus busy
+		dout     : out std_logic_vector(7 downto 0);
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+end entity i2c_master_byte_ctrl;
+
+architecture structural of i2c_master_byte_ctrl is
+	component i2c_master_bit_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic;
+		nReset : in std_logic;
+		ena    : in std_logic;				-- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);		-- clock prescale value
+
+		cmd     : in std_logic_vector(3 downto 0);
+		cmd_ack : out std_logic; -- command done
+		busy    : out std_logic; -- i2c bus busy
+		al      : out std_logic; -- arbitration lost
+
+		din  : in std_logic;
+		dout : out std_logic;
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+	end component i2c_master_bit_ctrl;
+
+	-- commands for bit_controller block
+	constant I2C_CMD_NOP  	: std_logic_vector(3 downto 0) := "0000";
+	constant I2C_CMD_START	: std_logic_vector(3 downto 0) := "0001";
+	constant I2C_CMD_STOP	 : std_logic_vector(3 downto 0) := "0010";
+	constant I2C_CMD_READ	 : std_logic_vector(3 downto 0) := "0100";
+	constant I2C_CMD_WRITE	: std_logic_vector(3 downto 0) := "1000";
+
+	-- signals for bit_controller
+	signal core_cmd : std_logic_vector(3 downto 0);
+	signal core_ack, core_txd, core_rxd : std_logic;
+	signal al : std_logic;
+
+	-- signals for shift register
+	signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
+	signal shift, ld : std_logic;
+
+	-- signals for state machine
+	signal go, host_ack : std_logic;
+	signal dcnt : unsigned(2 downto 0); -- data counter
+	signal cnt_done : std_logic;
+
+begin
+	-- hookup bit_controller
+	bit_ctrl: i2c_master_bit_ctrl port map(
+		clk     => clk,
+		rst     => rst,
+		nReset  => nReset,
+		ena     => ena,
+		clk_cnt => clk_cnt,
+		cmd     => core_cmd,
+		cmd_ack => core_ack,
+		busy    => i2c_busy,
+		al      => al,
+		din     => core_txd,
+		dout    => core_rxd,
+		scl_i   => scl_i,
+		scl_o   => scl_o,
+		scl_oen => scl_oen,
+		sda_i   => sda_i,
+		sda_o   => sda_o,
+		sda_oen => sda_oen
+	);
+	i2c_al <= al;
+
+	-- generate host-command-acknowledge
+	cmd_ack <= host_ack;
+
+	-- generate go-signal
+	go <= (read or write or stop) and not host_ack;
+
+	-- assign Dout output to shift-register
+	dout <= sr;
+
+	-- generate shift register
+	shift_register: process(clk, nReset)
+	begin
+	    if (nReset = '0') then
+	      sr <= (others => '0');
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1') then
+	        sr <= (others => '0');
+	      elsif (ld = '1') then
+	        sr <= din;
+	      elsif (shift = '1') then
+	        sr <= (sr(6 downto 0) & core_rxd);
+	      end if;
+	    end if;
+	end process shift_register;
+
+	-- generate data-counter
+	data_cnt: process(clk, nReset)
+	begin
+	    if (nReset = '0') then
+	      dcnt <= (others => '0');
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1') then
+	        dcnt <= (others => '0');
+	      elsif (ld = '1') then
+	        dcnt <= (others => '1');  -- load counter with 7
+	      elsif (shift = '1') then
+	        dcnt <= dcnt -1;
+	      end if;
+	    end if;
+	end process data_cnt;
+
+	cnt_done <= '1' when (dcnt = 0) else '0';
+
+	--
+	-- state machine
+	--
+	statemachine : block
+	    type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
+	    signal c_state : states;
+	begin
+	    --
+	    -- command interpreter, translate complex commands into simpler I2C commands
+	    --
+	    nxt_state_decoder: process(clk, nReset)
+	    begin
+	        if (nReset = '0') then
+	          core_cmd <= I2C_CMD_NOP;
+	          core_txd <= '0';
+	          shift    <= '0';
+	          ld       <= '0';
+	          host_ack <= '0';
+	          c_state  <= st_idle;
+	          ack_out  <= '0';
+	        elsif (clk'event and clk = '1') then
+	          if (rst = '1' or al = '1') then
+	            core_cmd <= I2C_CMD_NOP;
+	            core_txd <= '0';
+	            shift    <= '0';
+	            ld       <= '0';
+	            host_ack <= '0';
+	            c_state  <= st_idle;
+	            ack_out  <= '0';
+	          else
+	            -- initialy reset all signal
+	            core_txd <= sr(7);
+	            shift    <= '0';
+	            ld       <= '0';
+	            host_ack <= '0';
+
+	            case c_state is
+	              when st_idle =>
+	                 if (go = '1') then
+	                   if (start = '1') then
+	                     c_state  <= st_start;
+	                     core_cmd <= I2C_CMD_START;
+	                   elsif (read = '1') then
+	                     c_state  <= st_read;
+	                     core_cmd <= I2C_CMD_READ;
+	                   elsif (write = '1') then
+	                     c_state  <= st_write;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   else -- stop
+	                     c_state  <= st_stop;
+	                     core_cmd <= I2C_CMD_STOP;
+	                   end if;
+
+	                   ld <= '1';
+	                 end if;
+
+	              when st_start =>
+	                 if (core_ack = '1') then
+	                   if (read = '1') then
+	                     c_state  <= st_read;
+	                     core_cmd <= I2C_CMD_READ;
+	                   else
+	                     c_state  <= st_write;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   end if;
+
+	                   ld <= '1';
+	                 end if;
+
+	              when st_write =>
+	                 if (core_ack = '1') then
+	                   if (cnt_done = '1') then
+	                     c_state  <= st_ack;
+	                     core_cmd <= I2C_CMD_READ;
+	                   else
+	                     c_state  <= st_write;       -- stay in same state
+	                     core_cmd <= I2C_CMD_WRITE;  -- write next bit
+	                     shift    <= '1';
+	                   end if;
+	                 end if;
+
+	              when st_read =>
+	                 if (core_ack = '1') then
+	                   if (cnt_done = '1') then
+	                     c_state  <= st_ack;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   else
+	                     c_state  <= st_read;      -- stay in same state
+	                     core_cmd <= I2C_CMD_READ; -- read next bit
+	                   end if;
+
+	                   shift    <= '1';
+	                   core_txd <= ack_in;
+	                 end if;
+
+	              when st_ack =>
+	                 if (core_ack = '1') then
+	                   -- check for stop; Should a STOP command be generated ?
+	                   if (stop = '1') then
+	                     c_state  <= st_stop;
+	                     core_cmd <= I2C_CMD_STOP;
+	                   else
+	                     c_state  <= st_idle;
+	                     core_cmd <= I2C_CMD_NOP;
+
+	                     -- generate command acknowledge signal
+	                     host_ack <= '1';
+	                   end if;
+
+	                   -- assign ack_out output to core_rxd (contains last received bit)
+	                   ack_out  <= core_rxd;
+
+	                   core_txd <= '1';
+	                 else
+	                   core_txd <= ack_in;
+	                 end if;
+
+	              when st_stop =>
+	                 if (core_ack = '1') then
+	                   c_state  <= st_idle;
+	                   core_cmd <= I2C_CMD_NOP;
+
+	                   -- generate command acknowledge signal
+	                   host_ack <= '1';
+	                 end if;
+
+	              when others => -- illegal states
+	                 c_state  <= st_idle;
+	                 core_cmd <= I2C_CMD_NOP;
+	                 report ("Byte controller entered illegal state.");
+
+	            end case;
+
+	          end if;
+	        end if;
+	    end process nxt_state_decoder;
+
+	end block statemachine;
+
+end architecture structural;
+
diff --git a/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd b/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f1a63eddbd6b81521f614cdd7ba773c2db51d255
--- /dev/null
+++ b/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd
@@ -0,0 +1,359 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 compl. I2C Master Core; top level           ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_top.vhd,v 1.8 2009-01-20 10:38:45 rherveille Exp $
+--
+--  $Date: 2009-01-20 10:38:45 $
+--  $Revision: 1.8 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               Revision 1.7  2004/03/14 10:17:03  rherveille
+--               Fixed simulation issue when writing to CR register
+--
+--               Revision 1.6  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.5  2003/02/01 02:03:06  rherveille
+--               Fixed a few 'arbitration lost' bugs. VHDL version only.
+--
+--               Revision 1.4  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.3  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.2  2001/11/10 10:52:44  rherveille
+--               Changed PRER reset value from 0x0000 to 0xffff, conform specs.
+--
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+--use ieee.std_logic_arith.all;
+use ieee.numeric_std.all;
+
+entity i2c_master_top is
+    generic(
+            ARST_LVL : std_logic := '0'                   -- asynchronous reset level
+    );
+    port   (
+            -- wishbone signals
+            wb_clk_i      : in  std_logic;                    -- master clock input
+            wb_rst_i      : in  std_logic := '0';             -- synchronous active high reset
+            arst_i        : in  std_logic := not ARST_LVL;    -- asynchronous reset
+            wb_adr_i      : in  std_logic_vector(2 downto 0); -- lower address bits
+            wb_dat_i      : in  std_logic_vector(7 downto 0); -- Databus input
+            wb_dat_o      : out std_logic_vector(7 downto 0); -- Databus output
+            wb_we_i       : in  std_logic;                    -- Write enable input
+            wb_stb_i      : in  std_logic;                    -- Strobe signals / core select signal
+            wb_cyc_i      : in  std_logic;                    -- Valid bus cycle input
+            wb_ack_o      : out std_logic;                    -- Bus cycle acknowledge output
+            wb_inta_o     : out std_logic;                    -- interrupt request output signal
+
+            -- i2c lines
+            scl_pad_i     : in  std_logic;                    -- i2c clock line input
+            scl_pad_o     : out std_logic;                    -- i2c clock line output
+            scl_padoen_o  : out std_logic;                    -- i2c clock line output enable, active low
+            sda_pad_i     : in  std_logic;                    -- i2c data line input
+            sda_pad_o     : out std_logic;                    -- i2c data line output
+            sda_padoen_o  : out std_logic                     -- i2c data line output enable, active low
+    );
+end entity i2c_master_top;
+
+architecture structural of i2c_master_top is
+    component i2c_master_byte_ctrl is
+    port (
+          clk    : in std_logic;
+          rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
+          nReset : in std_logic; -- asynchornous active low reset (FPGA compatible)
+          ena    : in std_logic; -- core enable signal
+
+          clk_cnt : in unsigned(15 downto 0); -- 4x SCL
+
+          -- input signals
+          start,
+          stop,
+          read,
+          write,
+          ack_in : std_logic;
+          din    : in std_logic_vector(7 downto 0);
+
+          -- output signals
+          cmd_ack  : out std_logic;
+          ack_out  : out std_logic;
+          i2c_busy : out std_logic;
+          i2c_al   : out std_logic;
+          dout     : out std_logic_vector(7 downto 0);
+
+          -- i2c lines
+          scl_i   : in std_logic;  -- i2c clock line input
+          scl_o   : out std_logic; -- i2c clock line output
+          scl_oen : out std_logic; -- i2c clock line output enable, active low
+          sda_i   : in std_logic;  -- i2c data line input
+          sda_o   : out std_logic; -- i2c data line output
+          sda_oen : out std_logic  -- i2c data line output enable, active low
+    );
+    end component i2c_master_byte_ctrl;
+
+    -- registers
+    signal prer : unsigned(15 downto 0);             -- clock prescale register
+    signal ctr  : std_logic_vector(7 downto 0);      -- control register
+    signal txr  : std_logic_vector(7 downto 0);      -- transmit register
+    signal rxr  : std_logic_vector(7 downto 0);      -- receive register
+    signal cr   : std_logic_vector(7 downto 0);      -- command register
+    signal sr   : std_logic_vector(7 downto 0);      -- status register
+
+    -- internal reset signal
+    signal rst_i : std_logic;
+
+    -- wishbone write access
+    signal wb_wacc : std_logic;
+
+    -- internal acknowledge signal
+    signal iack_o : std_logic;
+
+    -- done signal: command completed, clear command register
+    signal done : std_logic;
+
+    -- command register signals
+    signal sta, sto, rd, wr, ack, iack : std_logic;
+
+    signal core_en : std_logic;                      -- core enable signal
+    signal ien     : std_logic;                      -- interrupt enable signal
+
+    -- status register signals
+    signal irxack, rxack : std_logic;                -- received aknowledge from slave
+    signal tip           : std_logic;                -- transfer in progress
+    signal irq_flag      : std_logic;                -- interrupt pending flag
+    signal i2c_busy      : std_logic;                -- i2c bus busy (start signal detected)
+    signal i2c_al, al    : std_logic;                -- arbitration lost
+
+begin
+    -- generate internal reset signal
+    rst_i <= arst_i xor ARST_LVL;
+
+    -- generate acknowledge output signal
+    gen_ack_o : process(wb_clk_i)
+    begin
+        if (wb_clk_i'event and wb_clk_i = '1') then
+            iack_o <= wb_cyc_i and wb_stb_i and not iack_o;         -- because timing is always honored
+        end if;
+    end process gen_ack_o;
+    wb_ack_o <= iack_o;
+
+    -- generate wishbone write access signal
+    wb_wacc <= wb_we_i and iack_o;
+
+    -- assign wb_dat_o
+    assign_dato : process(wb_clk_i)
+    begin
+        if (wb_clk_i'event and wb_clk_i = '1') then
+            case wb_adr_i is
+                when "000"  => wb_dat_o <= std_logic_vector(prer( 7 downto 0));
+                when "001"  => wb_dat_o <= std_logic_vector(prer(15 downto 8));
+                when "010"  => wb_dat_o <= ctr;
+                when "011"  => wb_dat_o <= rxr; -- write is transmit register TxR
+                when "100"  => wb_dat_o <= sr;  -- write is command register CR
+
+                -- Debugging registers:
+                -- These registers are not documented.
+                -- Functionality could change in future releases
+                when "101"  => wb_dat_o <= txr;
+                when "110"  => wb_dat_o <= cr;
+                when "111"  => wb_dat_o <= (others => '0');
+                when others => wb_dat_o <= (others => 'X'); -- for simulation only
+            end case;
+        end if;
+    end process assign_dato;
+
+
+    -- generate registers (CR, SR see below)
+    gen_regs: process(rst_i, wb_clk_i)
+    begin
+        if (rst_i = '0') then
+            prer <= (others => '1');
+            ctr  <= (others => '0');
+            txr  <= (others => '0');
+        elsif (wb_clk_i'event and wb_clk_i = '1') then
+               if (wb_rst_i = '1') then
+                   prer <= (others => '1');
+                   ctr  <= (others => '0');
+                   txr  <= (others => '0');
+               elsif (wb_wacc = '1') then
+                   case wb_adr_i is
+                       when "000" => prer( 7 downto 0) <= unsigned(wb_dat_i);
+                       when "001" => prer(15 downto 8) <= unsigned(wb_dat_i);
+                       when "010" => ctr               <= wb_dat_i;
+                       when "011" => txr               <= wb_dat_i;
+                       when "100" => null; --write to CR, avoid executing the others clause
+
+                      -- illegal cases, for simulation only
+                      when others =>
+                          report ("Illegal write address, setting all registers to unknown.");
+                          prer <= (others => 'X');
+                          ctr  <= (others => 'X');
+                          txr  <= (others => 'X');
+                   end case;
+               end if;
+        end if;
+    end process gen_regs;
+
+
+    -- generate command register
+    gen_cr: process(rst_i, wb_clk_i)
+    begin
+        if (rst_i = '0') then
+            cr <= (others => '0');
+        elsif (wb_clk_i'event and wb_clk_i = '1') then
+            if (wb_rst_i = '1') then
+                cr <= (others => '0');
+            elsif (wb_wacc = '1') then
+                if ( (core_en = '1') and (wb_adr_i = "100") ) then
+                    -- only take new commands when i2c core enabled
+                    -- pending commands are finished
+                    cr <= wb_dat_i;
+                end if;
+            else
+                if (done = '1' or i2c_al = '1') then
+                    cr(7 downto 4) <= (others => '0'); -- clear command bits when command done or arbitration lost
+                end if;
+
+                cr(2 downto 1) <= (others => '0');   -- reserved bits, always '0'
+                cr(0) <= '0';                        -- clear IRQ_ACK bit
+            end if;
+        end if;
+    end process gen_cr;
+
+    -- decode command register
+    sta  <= cr(7);
+    sto  <= cr(6);
+    rd   <= cr(5);
+    wr   <= cr(4);
+    ack  <= cr(3);
+    iack <= cr(0);
+
+    -- decode control register
+    core_en <= ctr(7);
+    ien     <= ctr(6);
+
+    -- hookup byte controller block
+    byte_ctrl: i2c_master_byte_ctrl
+    port map (
+              clk      => wb_clk_i,
+              rst      => wb_rst_i,
+              nReset   => rst_i,
+              ena      => core_en,
+              clk_cnt  => prer,
+              start    => sta,
+              stop     => sto,
+              read     => rd,
+              write    => wr,
+              ack_in   => ack,
+              i2c_busy => i2c_busy,
+              i2c_al   => i2c_al,
+              din      => txr,
+              cmd_ack  => done,
+              ack_out  => irxack,
+              dout     => rxr,
+              scl_i    => scl_pad_i,
+              scl_o    => scl_pad_o,
+              scl_oen  => scl_padoen_o,
+              sda_i    => sda_pad_i,
+              sda_o    => sda_pad_o,
+              sda_oen  => sda_padoen_o
+    );
+
+
+    -- status register block + interrupt request signal
+    st_irq_block : block
+    begin
+        -- generate status register bits
+        gen_sr_bits: process (wb_clk_i, rst_i)
+        begin
+            if (rst_i = '0') then
+                al       <= '0';
+                rxack    <= '0';
+                tip      <= '0';
+                irq_flag <= '0';
+            elsif (wb_clk_i'event and wb_clk_i = '1') then
+                   if (wb_rst_i = '1') then
+                       al       <= '0';
+                       rxack    <= '0';
+                       tip      <= '0';
+                       irq_flag <= '0';
+                   else
+                       al       <= i2c_al or (al and not sta);
+                       rxack    <= irxack;
+                       tip      <= (rd or wr);
+
+                       -- interrupt request flag is always generated
+                       irq_flag <= (done or i2c_al or irq_flag) and not iack;
+                   end if;
+            end if;
+        end process gen_sr_bits;
+
+        -- generate interrupt request signals
+        gen_irq: process (wb_clk_i, rst_i)
+        begin
+            if (rst_i = '0') then
+                wb_inta_o <= '0';
+            elsif (wb_clk_i'event and wb_clk_i = '1') then
+                   if (wb_rst_i = '1') then
+                       wb_inta_o <= '0';
+                   else
+                       -- interrupt signal is only generated when IEN (interrupt enable bit) is set
+                       wb_inta_o <= irq_flag and ien;
+                   end if;
+            end if;
+        end process gen_irq;
+
+        -- assign status register bits
+        sr(7)          <= rxack;
+        sr(6)          <= i2c_busy;
+        sr(5)          <= al;
+        sr(4 downto 2) <= (others => '0'); -- reserved
+        sr(1)          <= tip;
+        sr(0)          <= irq_flag;
+    end block;
+
+end architecture structural;
diff --git a/modules/wishbone/wb_simple_timer/manifest.py b/modules/wishbone/wb_simple_timer/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bd835b91162e5733a2b04ada27947cd36b8d727
--- /dev/null
+++ b/modules/wishbone/wb_simple_timer/manifest.py
@@ -0,0 +1 @@
+files = ["wb_tics.vhd"];
\ No newline at end of file
diff --git a/modules/wishbone/wb_simple_timer/wb_tics.vhd b/modules/wishbone/wb_simple_timer/wb_tics.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..d7acc1388bf909332507783fb592066676f51731
--- /dev/null
+++ b/modules/wishbone/wb_simple_timer/wb_tics.vhd
@@ -0,0 +1,116 @@
+-------------------------------------------------------------------------------
+-- Title      : WhiteRabbit PTP Core tics
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_tics.vhd
+-- Author     : Grzegorz Daniluk
+-- Company    : Elproma
+-- Created    : 2011-04-03
+-- Last update: 2011-04-07
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- WB_TICS is a simple counter with wishbone interface. Each step of a counter
+-- takes 1 usec. It is used by ptp-noposix as a replace of gettimeofday()
+-- function.
+-------------------------------------------------------------------------------
+-- Copyright (c) 2011 Grzegorz Daniluk
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-04-03  1.0      greg.d          Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.common_components.all;
+
+entity wb_tics is
+
+  generic (
+    g_period : integer);
+  port(
+    rst_n_i : in std_logic;
+
+    clk_sys_i : in std_logic;
+
+    wb_addr_i : in  std_logic_vector(1 downto 0);
+    wb_data_i : in  std_logic_vector(31 downto 0);
+    wb_data_o : out std_logic_vector(31 downto 0);
+    wb_cyc_i  : in  std_logic;
+    wb_sel_i  : in  std_logic_vector(3 downto 0);
+    wb_stb_i  : in  std_logic;
+    wb_we_i   : in  std_logic;
+    wb_ack_o  : out std_logic
+    );
+end wb_tics;
+
+architecture behaviour of wb_tics is
+
+  constant c_TICS_REG : std_logic_vector(1 downto 0) := "00";
+
+  signal cntr_div      : unsigned(23 downto 0);
+  signal cntr_tics     : unsigned(31 downto 0);
+  signal cntr_overflow : std_logic;
+
+begin
+
+  process(clk_sys_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if(rst_n_i = '0') then
+        cntr_div      <= (others => '0');
+        cntr_overflow <= '0';
+      else
+        if(cntr_div = g_period-1) then
+          cntr_div      <= (others => '0');
+          cntr_overflow <= '1';
+        else
+          cntr_div      <= cntr_div + 1;
+          cntr_overflow <= '0';
+        end if;
+      end if;
+    end if;
+  end process;
+
+  --usec counter
+  process(clk_sys_i)
+  begin
+    if(rising_edge(clk_sys_i)) then
+      if(rst_n_i = '0') then
+        cntr_tics <= (others => '0');
+      elsif(cntr_overflow = '1') then
+        cntr_tics <= cntr_tics + 1;
+      end if;
+    end if;
+  end process;
+
+  --Wishbone interface
+  process(clk_sys_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if(rst_n_i = '0') then
+        wb_ack_o  <= '0';
+        wb_data_o <= (others => '0');
+      else
+        if(wb_stb_i = '1' and wb_cyc_i = '1' and wb_we_i = '0') then
+          case wb_addr_i is
+            when c_TICS_REG =>
+              wb_data_o <= std_logic_vector(cntr_tics);
+            when others =>
+              wb_data_o <= (others => '0');
+          end case;
+          wb_ack_o <= '1';
+        else
+          wb_data_o <= (others => '0');
+          wb_ack_o  <= '0';
+        end if;
+      end if;
+    end if;
+  end process;
+
+end behaviour;
diff --git a/modules/wishbone/wb_uart/build_wb.sh b/modules/wishbone/wb_uart/build_wb.sh
new file mode 100755
index 0000000000000000000000000000000000000000..63156eace9bcbee8995dd5f9a6c2420b991593e4
--- /dev/null
+++ b/modules/wishbone/wb_uart/build_wb.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+mkdir -p doc
+wbgen2 -D ./doc/wb_uart.html -V uart_wb_slave.vhd -C ../../../../software/include/hw/wb_uart.h --cstyle defines --lang vhdl -K ../../../sim/wb_uart_defs.v uart.wb 
diff --git a/modules/wishbone/wb_uart/manifest.py b/modules/wishbone/wb_uart/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..5568ec6ab597882a08d8cb4ee403dab120ad6206
--- /dev/null
+++ b/modules/wishbone/wb_uart/manifest.py
@@ -0,0 +1,5 @@
+files = [	"uart_async_rx.vhd",
+					"uart_async_tx.vhd",
+					"uart_baud_gen.vhd",
+					"uart_wb_slave.vhd",
+					"wb_simple_uart.vhd"];
diff --git a/modules/wishbone/wb_uart/uart.wb b/modules/wishbone/wb_uart/uart.wb
new file mode 100644
index 0000000000000000000000000000000000000000..d211b76af199541744ed3374e25eb0922b71d23d
--- /dev/null
+++ b/modules/wishbone/wb_uart/uart.wb
@@ -0,0 +1,80 @@
+-- -*- Mode: LUA; tab-width: 2 -*-
+
+peripheral {
+	 name = "Simple Wishbone UART";
+	 description = "A simple Wishbone UART (8N1 mode) with programmable baud rate. ";
+	 prefix = "UART";
+	 hdl_entity = "uart_wb_slave";
+
+	 reg {
+			name = "Status Register";
+			prefix = "SR";
+			
+			field {
+				 name = "TX busy";
+				 description = "1: UART is busy transmitting a byte\n0: UART is idle and ready to transmit next byte";
+				 prefix = "TX_BUSY";
+				 type = BIT;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+
+			field {
+				 name = "RX ready";
+				 description = "1: UART received a byte and its in RXD register\n0: no data in RXD register";
+
+				 prefix = "RX_RDY";
+				 type = BIT;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+			
+	 };
+
+	 reg {
+			name = "Baudrate control register";
+			description = "Register controlling the UART baudrate";
+			prefix = "BCR";
+
+			field {
+				 name = "Baudrate divider setting";
+				 description = "Baudrate setting. The value can be calculated using the following equation:\
+				 BRATE = ((Baudrate * 8) << 9 + (ClockFreq >> 8)) / (ClockFreq >> 7)";
+				 size = 32;
+				 type = SLV;
+				 access_bus = READ_WRITE;
+				 access_dev = READ_ONLY;
+			};
+	 };
+
+	 reg {
+			name = "Transmit data regsiter";
+			prefix = "TDR";
+			
+			field {
+				 name = "Transmit data";
+				 prefix = "TX_DATA";
+				 size = 8;
+				 type = SLV;
+				 access_bus = READ_WRITE;
+				 access_dev = READ_WRITE;
+				 load = LOAD_EXT;
+			};
+	 };
+	 
+	 reg {
+			name = "Receive data regsiter";
+			prefix = "RDR";
+			
+
+			field {
+				 ack_read = "rdr_rack_o";
+				 name = "Received data";
+				 prefix = "RX_DATA";
+				 size = 8;
+				 type = SLV;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+	 };
+};
\ No newline at end of file
diff --git a/modules/wishbone/wb_uart/uart_async_rx.vhd b/modules/wishbone/wb_uart/uart_async_rx.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..34857ad6591508afe8bd5cabd4c66cdfdf4c8398
--- /dev/null
+++ b/modules/wishbone/wb_uart/uart_async_rx.vhd
@@ -0,0 +1,200 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity uart_async_rx is
+
+
+  port (
+    clk_sys_i : in std_logic;
+    rst_n_i   : in std_logic;
+
+    baud8_tick_i: in std_logic;
+
+    rxd_i      : in  std_logic;
+    rx_ready_o : out std_logic;
+    rx_error_o : out std_logic;
+    rx_data_o  : out std_logic_vector(7 downto 0)
+
+    );
+
+end uart_async_rx;
+
+
+architecture behavioral of uart_async_rx is
+
+  signal Baud8Tick : std_logic;
+  
+  signal RxD_sync_inv      : std_logic_vector(1 downto 0);
+  signal RxD_cnt_inv       : unsigned(1 downto 0);
+  signal RxD_bit_inv       : std_logic;
+
+  signal state       : std_logic_vector(3 downto 0);
+  signal bit_spacing : std_logic_vector(3 downto 0);
+  signal next_bit    : std_logic;
+
+  signal RxD_data       : std_logic_vector(7 downto 0);
+  signal RxD_data_ready : std_logic;
+  signal RxD_data_error : std_logic;
+
+  
+
+begin  -- behavioral
+
+  Baud8Tick <= baud8_tick_i;
+               
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        RxD_sync_inv <= (others => '0');
+      else
+        if(Baud8Tick = '1') then
+          RxD_sync_inv <= RxD_sync_inv(0) & (not rxd_i);
+        end if;
+      end if;
+    end if;
+  end process;
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        RxD_bit_inv <= '0';
+        RxD_cnt_inv <= (others => '0');
+      else
+        if(Baud8Tick = '1') then
+          if(RxD_sync_inv(1) = '1' and RxD_cnt_inv /= "11") then
+            RxD_cnt_inv <= RxD_cnt_inv + 1;
+          elsif (RxD_sync_inv(1) = '0' and RxD_cnt_inv /= "00") then
+            RxD_cnt_inv <= RxD_cnt_inv - 1;
+          end if;
+
+          if(RxD_cnt_inv = "00") then
+            RxD_bit_inv <= '0';
+          elsif(RxD_cnt_inv = "11") then
+            RxD_bit_inv <= '1';
+          end if;
+        end if;
+      end if;
+    end if;
+  end process;
+
+
+  next_bit <= '1' when (bit_spacing = x"a") else '0';
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        bit_spacing <= (others => '0');
+      else
+        if(state = x"0") then
+          bit_spacing <= "0000";
+        elsif(Baud8Tick = '1') then
+--          bit_spacing <= std_logic_vector(resize((unsigned(bit_spacing(2 downto 0)) + 1), 4))
+          bit_spacing <= std_logic_vector(unsigned('0' & bit_spacing(2 downto 0)) + 1)
+                         or (bit_spacing(3) & "000");
+        end if;
+      end if;
+    end if;
+  end process;
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        state <= (others => '0');
+      else
+        if(Baud8Tick = '1') then
+          case state is
+            when "0000" =>
+              if(RxD_bit_inv = '1') then  -- start bit
+                state <= "1000";
+              end if;
+            when "1000" =>
+              if(next_bit = '1') then
+                state <= "1001";          -- bit 0
+              end if;
+            when "1001" =>
+              if(next_bit = '1') then
+                state <= "1010";          -- bit 1
+              end if;
+            when "1010" =>
+              if(next_bit = '1') then
+                state <= "1011";          -- bit 2
+              end if;
+            when "1011" =>
+              if(next_bit = '1') then
+                state <= "1100";          -- bit 3
+              end if;
+            when "1100" =>
+              if(next_bit = '1') then
+                state <= "1101";          -- bit 4
+              end if;
+            when "1101" =>
+              if(next_bit = '1') then
+                state <= "1110";          -- bit 5
+              end if;
+            when "1110" =>
+              if(next_bit = '1') then
+                state <= "1111";          -- bit 6
+              end if;
+            when "1111" =>
+              if(next_bit = '1') then
+                state <= "0001";          -- bit 7
+              end if;
+            when "0001" =>
+              if(next_bit = '1') then
+                state <= "0000";          -- bit stop
+              end if;
+            when others => state <= "0000";
+          end case;
+        end if;
+      end if;
+    end if;
+  end process;
+
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        RxD_data <= (others => '0');
+      else
+        if(Baud8Tick = '1' and next_bit = '1' and state(3) = '1') then
+          RxD_data <= (not RxD_bit_inv) & RxD_data(7 downto 1);
+        end if;
+      end if;
+    end if;
+  end process;
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        RxD_data_error <= '0';
+        RxD_data_ready <= '0';
+      else
+        if(Baud8Tick = '1' and next_bit = '1' and state = "0001" and RxD_bit_inv = '0') then
+          RxD_data_ready <= '1';
+        else
+          RxD_data_ready <= '0';
+        end if;
+
+        if(Baud8Tick = '1' and next_bit = '1' and state = "0001" and RxD_bit_inv = '1') then
+          RxD_data_error <= '1';
+        else
+          RxD_data_error <= '0';
+        end if;
+      end if;
+    end if;
+  end process;
+
+  rx_data_o <= RxD_data;
+  rx_ready_o  <= RxD_data_ready;
+  rx_error_o <= RxD_data_error;
+  
+
+end behavioral;
diff --git a/modules/wishbone/wb_uart/uart_async_tx.vhd b/modules/wishbone/wb_uart/uart_async_tx.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..993fb8573c36adc49b2eaad3f5e079b9d1303de2
--- /dev/null
+++ b/modules/wishbone/wb_uart/uart_async_tx.vhd
@@ -0,0 +1,161 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity uart_async_tx is
+  
+  port (
+    clk_sys_i : in std_logic;
+    rst_n_i   : in std_logic;
+
+    baud_tick_i: in std_logic;
+    
+    txd_o        : out std_logic;
+    tx_start_p_i : in  std_logic;
+    tx_data_i    : in  std_logic_vector(7 downto 0);
+    tx_busy_o    : out std_logic
+
+    );
+
+end uart_async_tx;
+
+architecture behavioral of uart_async_tx is
+
+signal BaudTick : std_logic;
+  signal TxD_busy         : std_logic;
+  signal TxD_ready        : std_logic;
+  signal state            : std_logic_vector(3 downto 0);
+
+  signal TxD_dataReg : std_logic_vector(7 downto 0);
+  signal TxD_dataD   : std_logic_vector(7 downto 0);
+  signal muxbit      : std_logic;
+  signal TxD         : std_logic;
+
+begin  -- behavioral
+
+
+
+
+  TxD_ready <= '1' when state = "0000" else '0';
+  TxD_busy  <= not TxD_ready;
+  BaudTick  <= baud_tick_i;
+  
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        TxD_dataReg <= (others => '0');
+      elsif TxD_ready = '1' and tx_start_p_i = '1' then
+        TxD_dataReg <= tx_data_i;
+      end if;
+    end if;
+  end process;
+
+  TxD_dataD <= TxD_dataReg;
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        state <= "0000";
+      else
+        case state is
+          when "0000" =>
+            if (tx_start_p_i = '1') then
+              state <= "0001";
+            end if;
+
+          when "0001" =>
+            if (BaudTick = '1') then
+              state <= "0100";
+            end if;
+          when "0100" =>
+            if (BaudTick = '1') then
+              state <= "1000";
+            end if;
+          when "1000" =>
+            if (BaudTick = '1') then
+              state <= "1001";
+            end if;
+          when "1001" =>
+            if (BaudTick = '1') then
+              state <= "1010";
+            end if;
+
+          when "1010" =>
+            if (BaudTick = '1') then
+              state <= "1011";
+            end if;
+          when "1011" =>
+            if (BaudTick = '1') then
+              state <= "1100";
+            end if;
+          when "1100" =>
+            if (BaudTick = '1') then
+              state <= "1101";
+            end if;
+          when "1101" =>
+            if (BaudTick = '1') then
+              state <= "1110";
+            end if;
+          when "1110" =>
+            if (BaudTick = '1') then
+              state <= "1111";
+            end if;
+
+          when "1111" =>
+            if (BaudTick = '1') then
+              state <= "0010";
+            end if;
+          when "0010" =>
+            if (BaudTick = '1') then
+              state <= "0011";
+            end if;
+
+          when "0011" =>
+            if (BaudTick = '1') then
+              state <= "0000";
+            end if;
+          when others =>
+            state <= "0000";
+        end case;
+      end if;
+    end if;
+  end process;
+
+
+  process(TxD_dataD, state)
+  begin
+    case state(2 downto 0) is
+      when "000"      => muxbit <= TxD_dataD(0);
+      when "001"      => muxbit <= TxD_dataD(1);
+      when "010"      => muxbit <= TxD_dataD(2);
+      when "011"      => muxbit <= TxD_dataD(3);
+      when "100"      => muxbit <= TxD_dataD(4);
+      when "101"      => muxbit <= TxD_dataD(5);
+      when "110"      => muxbit <= TxD_dataD(6);
+      when "111"      => muxbit <= TxD_dataD(7);
+      when others => null;
+    end case;
+  end process;
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        TxD <= '0';
+      else
+        if(unsigned(state) < to_unsigned(4, state'length) or (state(3) = '1' and muxbit = '1')) then
+          TxD <= '1';
+        else
+          TxD <= '0';
+        end if;
+      end if;
+    end if;
+  end process;
+
+  txd_o      <= TxD;
+  tx_busy_o <= TxD_busy;
+
+end behavioral;
diff --git a/modules/wishbone/wb_uart/uart_baud_gen.vhd b/modules/wishbone/wb_uart/uart_baud_gen.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9bc849724b2a508256a709eddd8150f6aaad572a
--- /dev/null
+++ b/modules/wishbone/wb_uart/uart_baud_gen.vhd
@@ -0,0 +1,60 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity uart_baud_gen is
+  
+  generic (
+    g_baud_acc_width : integer := 16);
+
+  port (
+    clk_sys_i : in std_logic;
+    rst_n_i   : in std_logic;
+
+    baudrate_i : in std_logic_vector(g_baud_acc_width  downto 0);
+
+    baud_tick_o  : out std_logic;
+    baud8_tick_o : out std_logic);
+
+end uart_baud_gen;
+
+architecture behavioral of uart_baud_gen is
+
+  signal Baud8GeneratorInc : unsigned(g_baud_acc_width downto 0);
+  signal Baud8GeneratorAcc : unsigned(g_baud_acc_width downto 0);
+  signal Baud8Tick         : std_logic;
+  signal Baud_sreg         : std_logic_vector(7 downto 0);
+  
+  
+begin  -- behavioral
+
+  Baud8GeneratorInc <= unsigned(baudrate_i);
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        Baud8GeneratorAcc <= (others => '0');
+      else
+        Baud8GeneratorAcc <= ('0' & Baud8GeneratorAcc(Baud8GeneratorAcc'high-1 downto 0)) + Baud8GeneratorInc;
+      end if;
+    end if;
+  end process;
+
+  Baud8Tick <= std_logic(Baud8GeneratorAcc(g_baud_acc_width));
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        Baud_sreg <= "10000000";
+      elsif Baud8Tick = '1' then
+        Baud_sreg <= Baud_sreg(0) & Baud_sreg(7 downto 1);
+      end if;
+    end if;
+  end process;
+
+  baud_tick_o  <= Baud_sreg(0) and Baud8Tick;
+  baud8_tick_o <= Baud8Tick;
+
+end behavioral;
diff --git a/modules/wishbone/wb_uart/uart_wb_slave.vhd b/modules/wishbone/wb_uart/uart_wb_slave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..fb2d0e87fa8a5c66b783fc0fc32cf9d1493ba5c8
--- /dev/null
+++ b/modules/wishbone/wb_uart/uart_wb_slave.vhd
@@ -0,0 +1,228 @@
+---------------------------------------------------------------------------------------
+-- Title          : Wishbone slave core for Simple Wishbone UART
+---------------------------------------------------------------------------------------
+-- File           : uart_wb_slave.vhd
+-- Author         : auto-generated by wbgen2 from uart.wb
+-- Created        : Mon Feb 21 10:04:29 2011
+-- Standard       : VHDL'87
+---------------------------------------------------------------------------------------
+-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE uart.wb
+-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
+---------------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+entity uart_wb_slave is
+  port (
+    rst_n_i                                  : in     std_logic;
+    wb_clk_i                                 : in     std_logic;
+    wb_addr_i                                : in     std_logic_vector(1 downto 0);
+    wb_data_i                                : in     std_logic_vector(31 downto 0);
+    wb_data_o                                : out    std_logic_vector(31 downto 0);
+    wb_cyc_i                                 : in     std_logic;
+    wb_sel_i                                 : in     std_logic_vector(3 downto 0);
+    wb_stb_i                                 : in     std_logic;
+    wb_we_i                                  : in     std_logic;
+    wb_ack_o                                 : out    std_logic;
+-- Port for BIT field: 'TX busy' in reg: 'Status Register'
+    uart_sr_tx_busy_i                        : in     std_logic;
+-- Port for BIT field: 'RX ready' in reg: 'Status Register'
+    uart_sr_rx_rdy_i                         : in     std_logic;
+-- Port for std_logic_vector field: 'Baudrate divider setting' in reg: 'Baudrate control register'
+    uart_bcr_o                               : out    std_logic_vector(31 downto 0);
+-- Port for std_logic_vector field: 'Transmit data' in reg: 'Transmit data regsiter'
+    uart_tdr_tx_data_o                       : out    std_logic_vector(7 downto 0);
+    uart_tdr_tx_data_i                       : in     std_logic_vector(7 downto 0);
+    uart_tdr_tx_data_load_o                  : out    std_logic;
+-- Port for std_logic_vector field: 'Received data' in reg: 'Receive data regsiter'
+    uart_rdr_rx_data_i                       : in     std_logic_vector(7 downto 0);
+    rdr_rack_o                               : out    std_logic
+  );
+end uart_wb_slave;
+
+architecture syn of uart_wb_slave is
+
+signal uart_bcr_int                             : std_logic_vector(31 downto 0);
+signal ack_sreg                                 : std_logic_vector(9 downto 0);
+signal rddata_reg                               : std_logic_vector(31 downto 0);
+signal wrdata_reg                               : std_logic_vector(31 downto 0);
+signal bwsel_reg                                : std_logic_vector(3 downto 0);
+signal rwaddr_reg                               : std_logic_vector(1 downto 0);
+signal ack_in_progress                          : std_logic      ;
+signal wr_int                                   : std_logic      ;
+signal rd_int                                   : std_logic      ;
+signal bus_clock_int                            : std_logic      ;
+signal allones                                  : std_logic_vector(31 downto 0);
+signal allzeros                                 : std_logic_vector(31 downto 0);
+
+begin
+-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
+  wrdata_reg <= wb_data_i;
+  bwsel_reg <= wb_sel_i;
+  bus_clock_int <= wb_clk_i;
+  rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
+  wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
+  allones <= (others => '1');
+  allzeros <= (others => '0');
+-- 
+-- Main register bank access process.
+  process (bus_clock_int, rst_n_i)
+  begin
+    if (rst_n_i = '0') then 
+      ack_sreg <= "0000000000";
+      ack_in_progress <= '0';
+      rddata_reg <= "00000000000000000000000000000000";
+      uart_bcr_int <= "00000000000000000000000000000000";
+      uart_tdr_tx_data_load_o <= '0';
+      rdr_rack_o <= '0';
+    elsif rising_edge(bus_clock_int) then
+-- advance the ACK generator shift register
+      ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
+      ack_sreg(9) <= '0';
+      if (ack_in_progress = '1') then
+        if (ack_sreg(0) = '1') then
+          uart_tdr_tx_data_load_o <= '0';
+          rdr_rack_o <= '0';
+          ack_in_progress <= '0';
+        else
+          uart_tdr_tx_data_load_o <= '0';
+        end if;
+      else
+        if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
+          case rwaddr_reg(1 downto 0) is
+          when "00" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(0) <= uart_sr_tx_busy_i;
+              rddata_reg(1) <= uart_sr_rx_rdy_i;
+              rddata_reg(2) <= 'X';
+              rddata_reg(3) <= 'X';
+              rddata_reg(4) <= 'X';
+              rddata_reg(5) <= 'X';
+              rddata_reg(6) <= 'X';
+              rddata_reg(7) <= 'X';
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "01" => 
+            if (wb_we_i = '1') then
+              uart_bcr_int <= wrdata_reg(31 downto 0);
+            else
+              rddata_reg(31 downto 0) <= uart_bcr_int;
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "10" => 
+            if (wb_we_i = '1') then
+              uart_tdr_tx_data_load_o <= '1';
+            else
+              rddata_reg(7 downto 0) <= uart_tdr_tx_data_i;
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "11" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(7 downto 0) <= uart_rdr_rx_data_i;
+              rdr_rack_o <= '1';
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when others =>
+-- prevent the slave from hanging the bus on invalid address
+            ack_in_progress <= '1';
+            ack_sreg(0) <= '1';
+          end case;
+        end if;
+      end if;
+    end if;
+  end process;
+  
+  
+-- Drive the data output bus
+  wb_data_o <= rddata_reg;
+-- TX busy
+-- RX ready
+-- Baudrate divider setting
+  uart_bcr_o <= uart_bcr_int;
+-- Transmit data
+  uart_tdr_tx_data_o <= wrdata_reg(7 downto 0);
+-- Received data
+  rwaddr_reg <= wb_addr_i;
+-- ACK signal generation. Just pass the LSB of ACK counter.
+  wb_ack_o <= ack_sreg(0);
+end syn;
diff --git a/modules/wishbone/wb_uart/wb_simple_uart.vhd b/modules/wishbone/wb_uart/wb_simple_uart.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..437a4f15e2ade0133f54954d0db9763271beab02
--- /dev/null
+++ b/modules/wishbone/wb_uart/wb_simple_uart.vhd
@@ -0,0 +1,192 @@
+-------------------------------------------------------------------------------
+-- Title      : Wishbone UART for WR Core
+-- Project    : WhiteRabbit
+-------------------------------------------------------------------------------
+-- File       : wb_conmax_top.vhd
+-- Author     : Tomasz Wlostowski
+-- Company    : CERN BE-Co-HT
+-- Created    : 2011-02-21
+-- Last update: 2011-02-21
+-- Platform   : FPGA-generics
+-- Standard   : VHDL
+-------------------------------------------------------------------------------
+-- Description:
+-- Simple UART port with Wishbone interface
+--
+-------------------------------------------------------------------------------
+-- Copyright (c) 2011 Tomasz Wlostowski
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2011-02-21  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_simple_uart is
+  port (
+
+    clk_sys_i : in std_logic;
+    rst_n_i   : in std_logic;
+
+    wb_addr_i : in  std_logic_vector(1 downto 0);
+    wb_data_i : in  std_logic_vector(31 downto 0);
+    wb_data_o : out std_logic_vector(31 downto 0);
+    wb_cyc_i  : in  std_logic;
+    wb_sel_i  : in  std_logic_vector(3 downto 0);
+    wb_stb_i  : in  std_logic;
+    wb_we_i   : in  std_logic;
+    wb_ack_o  : out std_logic;
+
+    uart_rxd_i : in  std_logic;
+    uart_txd_o : out std_logic
+    );
+end wb_simple_uart;
+
+architecture syn of wb_simple_uart is
+
+  constant c_baud_acc_width : integer := 16;
+
+  component uart_wb_slave
+    port (
+      rst_n_i                 : in  std_logic;
+      wb_clk_i                : in  std_logic;
+      wb_addr_i               : in  std_logic_vector(1 downto 0);
+      wb_data_i               : in  std_logic_vector(31 downto 0);
+      wb_data_o               : out std_logic_vector(31 downto 0);
+      wb_cyc_i                : in  std_logic;
+      wb_sel_i                : in  std_logic_vector(3 downto 0);
+      wb_stb_i                : in  std_logic;
+      wb_we_i                 : in  std_logic;
+      wb_ack_o                : out std_logic;
+      uart_sr_tx_busy_i       : in  std_logic;
+      uart_sr_rx_rdy_i        : in  std_logic;
+      uart_bcr_o              : out std_logic_vector(31 downto 0);
+      uart_tdr_tx_data_o      : out std_logic_vector(7 downto 0);
+      uart_tdr_tx_data_i      : in  std_logic_vector(7 downto 0);
+      uart_tdr_tx_data_load_o : out std_logic;
+
+      uart_rdr_rx_data_i : in  std_logic_vector(7 downto 0);
+      rdr_rack_o         : out std_logic);
+  end component;
+
+  component uart_baud_gen
+    generic (
+      g_baud_acc_width : integer);
+    port (
+      clk_sys_i    : in  std_logic;
+      rst_n_i      : in  std_logic;
+      baudrate_i   : in  std_logic_vector(g_baud_acc_width  downto 0);
+      baud_tick_o  : out std_logic;
+      baud8_tick_o : out std_logic);
+  end component;
+
+
+  component uart_async_rx
+    port (
+      clk_sys_i    : in  std_logic;
+      rst_n_i      : in  std_logic;
+      baud8_tick_i : in  std_logic;
+      rxd_i        : in  std_logic;
+      rx_ready_o   : out  std_logic;
+      rx_error_o   : out std_logic;
+      rx_data_o    : out std_logic_vector(7 downto 0));
+  end component;
+
+  component uart_async_tx
+    port (
+      clk_sys_i    : in  std_logic;
+      rst_n_i      : in  std_logic;
+      baud_tick_i  : in  std_logic;
+      txd_o        : out std_logic;
+      tx_start_p_i : in  std_logic;
+      tx_data_i    : in  std_logic_vector(7 downto 0);
+      tx_busy_o    : out std_logic);
+  end component;
+
+  signal rx_ready_reg    : std_logic;
+  signal rx_ready        : std_logic;
+  signal uart_sr_tx_busy : std_logic;
+  signal uart_sr_rx_rdy  : std_logic;
+  signal uart_bcr        : std_logic_vector(31 downto 0);
+
+  signal uart_tdr_tx_data      : std_logic_vector(7 downto 0);
+  signal uart_tdr_tx_data_load : std_logic;
+
+  signal uart_rdr_rx_data : std_logic_vector(7 downto 0);
+  signal rdr_rack         : std_logic;
+
+  signal baud_tick  : std_logic;
+  signal baud_tick8 : std_logic;
+  
+begin  -- syn
+
+  BAUD_GEN : uart_baud_gen
+    generic map (
+      g_baud_acc_width => c_baud_acc_width)
+    port map (
+      clk_sys_i    => clk_sys_i,
+      rst_n_i      => rst_n_i,
+      baudrate_i   => uart_bcr(c_baud_acc_width downto 0),
+      baud_tick_o  => baud_tick,
+      baud8_tick_o => baud_tick8);
+
+  TX : uart_async_tx
+    port map (
+      clk_sys_i    => clk_sys_i,
+      rst_n_i      => rst_n_i,
+      baud_tick_i  => baud_tick,
+      txd_o        => uart_txd_o,
+      tx_start_p_i => uart_tdr_tx_data_load,
+      tx_data_i    => uart_tdr_tx_data,
+      tx_busy_o    => uart_sr_tx_busy);
+
+  RX : uart_async_rx
+    port map (
+      clk_sys_i    => clk_sys_i,
+      rst_n_i      => rst_n_i,
+      baud8_tick_i => baud_tick8,
+      rxd_i        => uart_rxd_i,
+      rx_ready_o   => rx_ready,
+      rx_error_o   => open,
+      rx_data_o    => uart_rdr_rx_data);
+
+  WB_SLAVE : uart_wb_slave
+    port map (
+      rst_n_i   => rst_n_i,
+      wb_clk_i  => clk_sys_i,
+      wb_addr_i => wb_addr_i,
+      wb_data_i => wb_data_i,
+      wb_data_o => wb_data_o,
+      wb_cyc_i  => wb_cyc_i,
+      wb_sel_i  => wb_sel_i,
+      wb_stb_i  => wb_stb_i,
+      wb_we_i   => wb_we_i,
+      wb_ack_o  => wb_ack_o,
+
+      uart_sr_tx_busy_i       => uart_sr_tx_busy,
+      uart_sr_rx_rdy_i        => uart_sr_rx_rdy,
+      uart_bcr_o              => uart_bcr,
+      uart_tdr_tx_data_o      => uart_tdr_tx_data,
+      uart_tdr_tx_data_i      => uart_tdr_tx_data,
+      uart_tdr_tx_data_load_o => uart_tdr_tx_data_load,
+      uart_rdr_rx_data_i      => uart_rdr_rx_data,
+      rdr_rack_o              => rdr_rack);
+
+  process(clk_sys_i, rst_n_i)
+  begin
+    if rising_edge(clk_sys_i) then
+      if rst_n_i = '0' then
+        uart_sr_rx_rdy <= '0';
+      else
+        if(rx_ready = '1') then
+          uart_sr_rx_rdy <= '1';
+        elsif(rdr_rack = '1') then
+          uart_sr_rx_rdy <= '0';
+        end if;
+      end if;
+    end if;
+  end process;
+  
+end syn;
diff --git a/modules/wishbone/wb_vic/Manifest.py b/modules/wishbone/wb_vic/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..bc01174c21a939baf6f73301cde152b01c37e158
--- /dev/null
+++ b/modules/wishbone/wb_vic/Manifest.py
@@ -0,0 +1,3 @@
+files = ["vic_prio_enc.vhd",
+				"wb_slave_vic.wb",
+				"wb_vic.vhd"]
\ No newline at end of file
diff --git a/modules/wishbone/wb_vic/vic_prio_enc.vhd b/modules/wishbone/wb_vic/vic_prio_enc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..4e2c1328edb2367ae77b7edccb2b98f2accf7451
--- /dev/null
+++ b/modules/wishbone/wb_vic/vic_prio_enc.vhd
@@ -0,0 +1,88 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity vic_prio_enc is
+
+  port (
+    in_i  : in  std_logic_vector(31 downto 0);
+    out_o : out std_logic_vector(4 downto 0)
+    );
+
+end vic_prio_enc;
+
+architecture syn of vic_prio_enc is
+
+begin  -- syn
+
+  prencode : process (in_i)
+  begin  -- process prencode
+    if in_i(0) = '1' then
+      out_o <= "00000";
+    elsif in_i(1) = '1' then
+      out_o <= "00001";
+    elsif in_i(2) = '1' then
+      out_o <= "00010";
+    elsif in_i(3) = '1' then
+      out_o <= "00011";
+    elsif in_i(4) = '1' then
+      out_o <= "00100";
+    elsif in_i(5) = '1' then
+      out_o <= "00101";
+    elsif in_i(6) = '1' then
+      out_o <= "00110";
+    elsif in_i(7) = '1' then
+      out_o <= "00111";
+    elsif in_i(8+0) = '1' then
+      out_o <= "01000";
+    elsif in_i(8+1) = '1' then
+      out_o <= "01001";
+    elsif in_i(8+2) = '1' then
+      out_o <= "01010";
+    elsif in_i(8+3) = '1' then
+      out_o <= "01011";
+    elsif in_i(8+4) = '1' then
+      out_o <= "01100";
+    elsif in_i(8+5) = '1' then
+      out_o <= "01101";
+    elsif in_i(8+6) = '1' then
+      out_o <= "01110";
+    elsif in_i(8+7) = '1' then
+      out_o <= "01111";
+    elsif in_i(16+0) = '1' then
+      out_o <= "10000";
+    elsif in_i(16+1) = '1' then
+      out_o <= "10001";
+    elsif in_i(16+2) = '1' then
+      out_o <= "10010";
+    elsif in_i(16+3) = '1' then
+      out_o <= "10011";
+    elsif in_i(16+4) = '1' then
+      out_o <= "10100";
+    elsif in_i(16+5) = '1' then
+      out_o <= "10101";
+    elsif in_i(16+6) = '1' then
+      out_o <= "10110";
+    elsif in_i(16+7) = '1' then
+      out_o <= "10111";
+    elsif in_i(24+0) = '1' then
+      out_o <= "11000";
+    elsif in_i(24+1) = '1' then
+      out_o <= "11001";
+    elsif in_i(24+2) = '1' then
+      out_o <= "11010";
+    elsif in_i(24+3) = '1' then
+      out_o <= "11011";
+    elsif in_i(24+4) = '1' then
+      out_o <= "11100";
+    elsif in_i(24+5) = '1' then
+      out_o <= "11101";
+    elsif in_i(24+6) = '1' then
+      out_o <= "11110";
+    elsif in_i(24+7) = '1' then
+      out_o <= "11111";
+    else
+      out_o <= "XXXXX";
+    end if;
+  end process prencode;
+
+end syn;
diff --git a/modules/wishbone/wb_vic/wb_slave_vic.wb b/modules/wishbone/wb_vic/wb_slave_vic.wb
new file mode 100644
index 0000000000000000000000000000000000000000..06499dba79e20d0ea889c176c25a43e9cfd9ca86
--- /dev/null
+++ b/modules/wishbone/wb_vic/wb_slave_vic.wb
@@ -0,0 +1,132 @@
+-- -*- Mode: LUA; tab-width: 2 -*-
+
+peripheral {
+	 name = "Vectored Interrupt Controller (VIC)";
+	 description = "Module implementing a 2 to 32-input prioritized interrupt controller with internal interrupt vector storage support.";
+	 prefix = "VIC";
+	 hdl_entity = "wb_slave_vic";
+
+	 reg {
+			name = "VIC Control Register";
+			prefix = "CTL";
+
+			field {
+				 name = "VIC Enable";
+				 description = "1: enables VIC operation\n0: disables VIC operation";
+				 prefix = "ENABLE";
+				 type = BIT;
+				 access_dev = READ_ONLY;
+				 access_bus = READ_WRITE;
+			};
+
+			field {
+				 name = "VIC output polarity";
+				 description = "1: IRQ output is active high\n0: IRQ output is active low";
+				 prefix = "POL";
+				 type = BIT;
+				 access_dev = READ_ONLY;
+				 access_bus = READ_WRITE;
+			};
+	 };
+
+	 reg {
+			name = "Raw Interrupt Status Register";
+			prefix = "RISR";
+			
+			field {
+				 name = "Raw interrupt status";
+				 description = "Each bit reflects the current state of corresponding IRQ input line.\nread 1: interrupt line is currently active\nread 0: interrupt line is inactive";
+				 type = SLV;
+				 size = 32;
+				 access_dev = WRITE_ONLY;
+				 access_bus = READ_ONLY;
+			};
+	 };
+
+	 reg {
+			name = "Interrupt Enable Register";
+			prefix = "IER";
+			
+			field {
+				 name = "Enable IRQ";
+				 description = "Write 1: enables interrupt associated with written bit\nWrite 0: no effect";
+				 type = PASS_THROUGH;
+				 size = 32;
+			};
+	 };
+
+	 reg {
+			name = "Interrupt Disable Register";
+			prefix = "IDR";
+			
+			field {
+				 name = "Disable IRQ";
+				 description = "Write 1: enables interrupt associated with written bit\nWrite 0: no effect";
+				 type = PASS_THROUGH;
+				 size = 32;
+			};
+	 };
+
+	 reg {
+			name = "Interrupt Mask Register";
+			prefix = "IMR";
+			
+			field {
+				 name = "IRQ disabled/enabled";
+				 description = "Read 1: interrupt associated with bitfield is enabled\nRead 0: interrupt is disabled";
+				 type = SLV;
+				 size = 32;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+	 };
+
+	 reg {
+			name = "Vector Address Register";
+			prefix = "VAR";
+			
+			field {
+				 name = "Vector Address";
+				 description = "Address of pending interrupt vector, read from Interrupt Vector Table";
+				 type = SLV;
+				 size = 32;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+	 };
+
+	 reg {
+			name = "Software Interrupt Register";
+			description = "Writing 1 to one of bits of this register causes a software emulation of the respective interrupt.";
+			prefix = "SWIR";
+			field {
+				 name = "SWI interrupt mask";
+				 type = PASS_THROUGH;
+				 size = 32;
+			};
+	 };
+
+	 reg {
+			name = "End Of Interrupt Acknowledge Register";
+			prefix = "EOIR";
+			
+			field {
+				 name = "End of Interrupt";
+				 description = "Any write operation acknowledges the pending interrupt. Then, VIC advances to another pending interrupt(s).";
+				 type = PASS_THROUGH;
+				 size = 32;
+			};
+	 };
+
+	 ram {
+			name = "Interrupt Vector Table";
+			description = "Vector Address Table. Word at offset N stores the vector address of IRQ N. When interrupt is requested, VIC reads it's vector address from this memory and stores it in VAR register.";
+			prefix = "IVT_RAM";
+			
+			size = 32;
+			width = 32;
+			
+			access_bus = READ_WRITE;
+			access_dev = READ_ONLY;
+	 };
+};
\ No newline at end of file
diff --git a/modules/wishbone/wb_vic/wb_vic.vhd b/modules/wishbone/wb_vic/wb_vic.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..8cd519631f05ca6dd0a4dc52116733ce3d47b895
--- /dev/null
+++ b/modules/wishbone/wb_vic/wb_vic.vhd
@@ -0,0 +1,289 @@
+------------------------------------------------------------------------------
+-- Title      : Wishbone Vectored Interrupt Controller
+-- Project    : White Rabbit Switch
+------------------------------------------------------------------------------
+-- Author     : Tomasz Wlostowski
+-- Company    : CERN BE-Co-HT
+-- Created    : 2010-05-18
+-- Last update: 2010-07-29
+-- Platform   : FPGA-generic
+-- Standard   : VHDL'87
+-------------------------------------------------------------------------------
+-- Description: Simple interrupt controller/multiplexer:
+-- - designed to cooperate with wbgen2 peripherals Embedded Interrupt
+--   Controllers (EICs)
+-- - accepts 2 to 32 inputs (configurable using g_num_interrupts)
+-- - inputs are high-level sensitive
+-- - inputs have fixed priorities. Input 0 has the highest priority, Input
+--   g_num_interrupts-1 has the lowest priority.
+-- - output interrupt line (to the CPU) is active low or high depending on
+--   a configuration bit.
+-- - interrupt is acknowledged by writing to EIC_EOIR register.
+-- - register layout: see wb_vic.wb for details.
+-------------------------------------------------------------------------------
+-- Copyright (c) 2010 Tomasz Wlostowski
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2010-05-18  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.wishbone_pkg.all;
+
+entity wb_vic is
+  
+  generic (
+    g_num_interrupts : natural := 32    -- number of IRQ inputs.
+    );
+
+  port (
+    rst_n_i  : in std_logic;            -- reset
+    wb_clk_i : in std_logic;            -- wishbone clock
+
+    wb_addr_i : in  std_logic_vector(5 downto 0);
+    wb_data_i : in  std_logic_vector(31 downto 0);
+    wb_data_o : out std_logic_vector(31 downto 0);
+    wb_cyc_i  : in  std_logic;
+    wb_sel_i  : in  std_logic_vector(3 downto 0);
+    wb_stb_i  : in  std_logic;
+    wb_we_i   : in  std_logic;
+    wb_ack_o  : out std_logic;
+
+    irqs_i       : in  std_logic_vector(g_num_interrupts-1 downto 0);  -- IRQ inputs
+    irq_master_o : out std_logic        -- master IRQ output (multiplexed line,
+                                        -- to the CPU)
+    );
+
+end wb_vic;
+
+
+architecture syn of wb_vic is
+
+  component vic_prio_enc
+    port (
+      in_i  : in  std_logic_vector(31 downto 0);
+      out_o : out std_logic_vector(4 downto 0));
+  end component;
+
+  component wb_slave_vic
+    port (
+      rst_n_i            : in  std_logic;
+      wb_clk_i           : in  std_logic;
+      wb_addr_i          : in  std_logic_vector(5 downto 0);
+      wb_data_i          : in  std_logic_vector(31 downto 0);
+      wb_data_o          : out std_logic_vector(31 downto 0);
+      wb_cyc_i           : in  std_logic;
+      wb_sel_i           : in  std_logic_vector(3 downto 0);
+      wb_stb_i           : in  std_logic;
+      wb_we_i            : in  std_logic;
+      wb_ack_o           : out std_logic;
+      vic_ctl_enable_o   : out std_logic;
+      vic_ctl_pol_o      : out std_logic;
+      vic_risr_i         : in  std_logic_vector(31 downto 0);
+      vic_ier_o          : out std_logic_vector(31 downto 0);
+      vic_ier_wr_o       : out std_logic;
+      vic_idr_o          : out std_logic_vector(31 downto 0);
+      vic_idr_wr_o       : out std_logic;
+      vic_imr_i          : in  std_logic_vector(31 downto 0);
+      vic_var_i          : in  std_logic_vector(31 downto 0);
+      vic_swir_o         : out std_logic_vector(31 downto 0);
+      vic_swir_wr_o      : out std_logic;
+      vic_eoir_o         : out std_logic_vector(31 downto 0);
+      vic_eoir_wr_o      : out std_logic;
+      vic_ivt_ram_addr_i : in  std_logic_vector(4 downto 0);
+      vic_ivt_ram_data_o : out std_logic_vector(31 downto 0);
+      vic_ivt_ram_rd_i   : in  std_logic);
+  end component;
+
+  type t_state is (WAIT_IRQ, PROCESS_IRQ, WAIT_ACK, WAIT_MEM, WAIT_IDLE);
+
+  signal irqs_i_reg : std_logic_vector(32 downto 0);
+
+  signal vic_ctl_enable   : std_logic;
+  signal vic_ctl_pol      : std_logic;
+  signal vic_risr         : std_logic_vector(31 downto 0);
+  signal vic_ier          : std_logic_vector(31 downto 0);
+  signal vic_ier_wr       : std_logic;
+  signal vic_idr          : std_logic_vector(31 downto 0);
+  signal vic_idr_wr       : std_logic;
+  signal vic_imr          : std_logic_vector(31 downto 0);
+  signal vic_var          : std_logic_vector(31 downto 0);
+  signal vic_eoir         : std_logic_vector(31 downto 0);
+  signal vic_eoir_wr      : std_logic;
+  signal vic_ivt_ram_addr : std_logic_vector(4 downto 0);
+  signal vic_ivt_ram_data : std_logic_vector(31 downto 0);
+  signal vic_ivt_ram_rd   : std_logic;
+
+  signal vic_swir    : std_logic_vector(31 downto 0);
+  signal vic_swir_wr : std_logic;
+
+  signal got_irq  : std_logic;
+  signal swi_mask : std_logic_vector(31 downto 0);
+
+  signal current_irq    : std_logic_vector(4 downto 0);
+  signal irq_id_encoded : std_logic_vector(4 downto 0);
+  signal state          : t_state;
+  
+begin  -- syn
+
+  check1 : if (g_num_interrupts < 2 or g_num_interrupts > 32) generate
+    assert true report "invalid number of interrupts" severity failure;
+  end generate check1;
+
+
+  register_irq_lines : process(wb_clk_i, rst_n_i)
+  begin
+    if rising_edge(wb_clk_i) then
+      if rst_n_i = '0' then
+        irqs_i_reg <= (others => '0');
+      else
+        
+        irqs_i_reg(g_num_interrupts-1 downto 0) <= (irqs_i or swi_mask(g_num_interrupts-1 downto 0)) and vic_imr(g_num_interrupts-1 downto 0);
+
+        irqs_i_reg(32 downto g_num_interrupts) <= (others => '0');
+      end if;
+    end if;
+  end process;
+
+
+  vic_risr <= irqs_i_reg(31 downto 0);
+
+  priority_encoder : vic_prio_enc
+    port map (
+      in_i  => irqs_i_reg(31 downto 0),
+      out_o => irq_id_encoded);
+
+  vic_ivt_ram_addr <= current_irq;
+
+  wb_controller : wb_slave_vic
+    port map (
+      rst_n_i   => rst_n_i,
+      wb_clk_i  => wb_clk_i,
+      wb_addr_i => wb_addr_i,
+      wb_data_i => wb_data_i,
+      wb_data_o => wb_data_o,
+      wb_cyc_i  => wb_cyc_i,
+      wb_sel_i  => wb_sel_i,
+      wb_stb_i  => wb_stb_i,
+      wb_we_i   => wb_we_i,
+      wb_ack_o  => wb_ack_o,
+
+      vic_ctl_enable_o   => vic_ctl_enable,
+      vic_ctl_pol_o      => vic_ctl_pol,
+      vic_risr_i         => vic_risr,
+      vic_ier_o          => vic_ier,
+      vic_ier_wr_o       => vic_ier_wr,
+      vic_idr_o          => vic_idr,
+      vic_idr_wr_o       => vic_idr_wr,
+      vic_imr_i          => vic_imr,
+      vic_var_i          => vic_var,
+      vic_eoir_o         => vic_eoir,
+      vic_eoir_wr_o      => vic_eoir_wr,
+      vic_swir_o         => vic_swir,
+      vic_swir_wr_o      => vic_swir_wr,
+      vic_ivt_ram_addr_i => vic_ivt_ram_addr,
+      vic_ivt_ram_data_o => vic_ivt_ram_data,
+      vic_ivt_ram_rd_i   => vic_ivt_ram_rd);
+
+  process (wb_clk_i, rst_n_i)
+  begin  -- process enable_disable_irqs
+    if rising_edge(wb_clk_i) then
+      
+      if rst_n_i = '0' then             -- asynchronous reset (active low)
+        vic_imr <= (others => '0');
+      else
+        
+        if(vic_ier_wr = '1') then
+          for i in 0 to g_num_interrupts-1 loop
+            if(vic_ier(i) = '1') then
+              vic_imr(i) <= '1';
+            end if;
+          end loop;  -- i
+        end if;
+
+        if(vic_idr_wr = '1') then
+          for i in 0 to g_num_interrupts-1 loop
+            if(vic_idr(i) = '1') then
+              vic_imr(i) <= '0';
+            end if;
+          end loop;  -- i
+        end if;
+        
+      end if;
+    end if;
+  end process;
+
+  vic_fsm : process (wb_clk_i, rst_n_i)
+  begin  -- process vic_fsm
+    if rising_edge(wb_clk_i) then
+      
+      if rst_n_i = '0' then             -- asynchronous reset (active low)
+        state          <= WAIT_IRQ;
+        vic_ivt_ram_rd <= '0';
+        current_irq    <= (others => '0');
+        irq_master_o   <= '0';
+        vic_var        <= x"12345678";
+        swi_mask       <= (others => '0');
+        
+      else
+        if(vic_ctl_enable = '0') then
+          irq_master_o   <= not vic_ctl_pol;
+          vic_ivt_ram_rd <= '0';
+          current_irq    <= (others => '0');
+          state          <= WAIT_IRQ;
+          vic_var        <= x"12345678";
+          swi_mask       <= (others => '0');
+        else
+
+          if(vic_swir_wr = '1') then    -- handle the software IRQs
+            swi_mask <= vic_swir;
+          end if;
+
+          case state is
+            when WAIT_IRQ =>
+              if(irqs_i_reg /= std_logic_vector(to_unsigned(0, irqs_i_reg'length))) then
+                current_irq    <= irq_id_encoded;
+                state          <= WAIT_MEM;
+                vic_ivt_ram_rd <= '1';
+
+-- assert the master IRQ line
+              else
+-- no interrupts? de-assert the IRQ line 
+                irq_master_o <= not vic_ctl_pol;
+                vic_var      <= (others => '0');
+              end if;
+
+            when WAIT_MEM =>
+              state <= PROCESS_IRQ;
+              
+            when PROCESS_IRQ =>
+-- fetch the vector address from vector table and load it into VIC_VAR register
+              vic_var        <= vic_ivt_ram_data;
+              vic_ivt_ram_rd <= '0';
+              state          <= WAIT_ACK;
+              irq_master_o   <= vic_ctl_pol;
+
+            when WAIT_ACK =>
+-- got write operation to VIC_EOIR register? if yes, advance to next interrupt.
+
+              if(vic_eoir_wr = '1') then
+                state    <= WAIT_IDLE;
+                swi_mask <= (others => '0');
+              end if;
+
+            when WAIT_IDLE =>
+              state <= WAIT_IRQ;
+              
+          end case;
+        end if;
+      end if;
+    end if;
+  end process vic_fsm;
+
+
+end syn;
diff --git a/modules/wishbone/wb_virtual_uart/manifest.py b/modules/wishbone/wb_virtual_uart/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..9c9fdb422743c116ca5658477060e7945627142c
--- /dev/null
+++ b/modules/wishbone/wb_virtual_uart/manifest.py
@@ -0,0 +1,2 @@
+files = ["wb_virtual_uart.vhd",
+				 "wb_virtual_uart_slave.vhd" ];
diff --git a/modules/wishbone/wb_virtual_uart/wb_virtual_uart.vhd b/modules/wishbone/wb_virtual_uart/wb_virtual_uart.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..bf40a2031063c3ea98e9ace470957a0c0d231d18
--- /dev/null
+++ b/modules/wishbone/wb_virtual_uart/wb_virtual_uart.vhd
@@ -0,0 +1,92 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+entity wb_virtual_uart is
+  port(
+    rst_n_i     : in  std_logic;
+    clk_sys_i    : in  std_logic;
+    wb_addr_i   : in  std_logic_vector(2 downto 0);
+    wb_data_i   : in  std_logic_vector(31 downto 0);
+    wb_data_o   : out std_logic_vector(31 downto 0);
+    wb_cyc_i    : in  std_logic;
+    wb_sel_i    : in  std_logic_vector(3 downto 0);
+    wb_stb_i    : in  std_logic;
+    wb_we_i     : in  std_logic;
+    wb_ack_o    : out std_logic
+  );
+end wb_virtual_uart;
+
+architecture struct of wb_virtual_uart is
+
+  component wb_virtual_uart_slave
+    port (
+      rst_n_i                 : in  std_logic;
+      wb_clk_i                : in  std_logic;
+      wb_addr_i               : in  std_logic_vector(2 downto 0);
+      wb_data_i               : in  std_logic_vector(31 downto 0);
+      wb_data_o               : out std_logic_vector(31 downto 0);
+      wb_cyc_i                : in  std_logic;
+      wb_sel_i                : in  std_logic_vector(3 downto 0);
+      wb_stb_i                : in  std_logic;
+      wb_we_i                 : in  std_logic;
+      wb_ack_o                : out std_logic;
+      uart_sr_tx_busy_i       : in  std_logic;
+      uart_sr_rx_rdy_i        : in  std_logic;
+      uart_bcr_o              : out std_logic_vector(31 downto 0);
+      uart_tdr_tx_data_o      : out std_logic_vector(7 downto 0);
+      uart_tdr_tx_data_i      : in  std_logic_vector(7 downto 0);
+      uart_tdr_tx_data_load_o : out std_logic;
+      uart_rdr_rx_data_i      : in  std_logic_vector(7 downto 0);
+      rdr_rack_o              : out std_logic;
+      uart_debug_wr_req_i     : in  std_logic;
+      uart_debug_wr_full_o    : out std_logic;
+      uart_debug_wr_empty_o   : out std_logic;
+      uart_debug_wr_usedw_o   : out std_logic_vector(7 downto 0);
+      uart_debug_tx_i         : in  std_logic_vector(7 downto 0);
+      uart_debug_dupa_i       : in  std_logic_vector(31 downto 0));
+  end component;
+  
+ 
+  signal tx_data      : std_logic_vector(7 downto 0);
+  signal tx_data_load : std_logic;
+  signal tdr_load : std_logic;
+  signal fifo_full : std_logic;
+
+begin
+
+  tx_data_load <= (not fifo_full) and tdr_load;
+  
+  WB_SLAVE: wb_virtual_uart_slave
+    port map(
+      rst_n_i           => rst_n_i,
+      wb_clk_i          => clk_sys_i,
+      wb_addr_i         => wb_addr_i,
+      wb_data_i         => wb_data_i,
+      wb_data_o         => wb_data_o,
+      wb_cyc_i          => wb_cyc_i,
+      wb_sel_i          => wb_sel_i,
+      wb_stb_i          => wb_stb_i,
+      wb_we_i           => wb_we_i,
+      wb_ack_o          => wb_ack_o,
+      uart_sr_tx_busy_i => '0',
+      uart_sr_rx_rdy_i  => '0',
+      uart_bcr_o        => open,
+      uart_tdr_tx_data_o  => tx_data,
+      uart_tdr_tx_data_i  => x"00",
+      uart_tdr_tx_data_load_o => tdr_load,
+      uart_rdr_rx_data_i      => x"00",
+      rdr_rack_o              => open,
+  -- FIFO write request
+      uart_debug_wr_req_i     => tx_data_load,
+  -- FIFO full flag
+      uart_debug_wr_full_o    => fifo_full,
+  -- FIFO empty flag
+      uart_debug_wr_empty_o   => open,
+  -- FIFO number of used words
+      uart_debug_wr_usedw_o   => open,
+      uart_debug_tx_i         => tx_data,
+      uart_debug_dupa_i => x"00000000"
+    );
+
+
+end struct;
diff --git a/modules/wishbone/wb_virtual_uart/wb_virtual_uart.wb b/modules/wishbone/wb_virtual_uart/wb_virtual_uart.wb
new file mode 100644
index 0000000000000000000000000000000000000000..eb7fffa9910ffd1acd2356211e969f88ea5baf26
--- /dev/null
+++ b/modules/wishbone/wb_virtual_uart/wb_virtual_uart.wb
@@ -0,0 +1,105 @@
+-- -*- Mode: LUA; tab-width: 2 -*-
+
+peripheral {
+	 name = "Virtual UART";
+	 description = "A simple Wishbone FIFO that acts as UART";
+	 prefix = "UART";
+	 hdl_entity = "wb_virtual_uart_slave";
+
+	 reg {
+			name = "Status Register";
+			prefix = "SR";
+			
+			field {
+				 name = "TX busy";
+				 description = "1: UART is busy transmitting a byte\n0: UART is idle and ready to transmit next byte";
+				 prefix = "TX_BUSY";
+				 type = BIT;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+
+			field {
+				 name = "RX ready";
+				 description = "1: UART received a byte and its in RXD register\n0: no data in RXD register";
+
+				 prefix = "RX_RDY";
+				 type = BIT;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+			
+	 };
+
+	 reg {
+			name = "Baudrate control register";
+			description = "Register controlling the UART baudrate";
+			prefix = "BCR";
+
+			field {
+				 name = "Baudrate divider setting";
+				 description = "Baudrate setting. The value can be calculated using the following equation:\
+				 BRATE = ((Baudrate * 8) << 9 + (ClockFreq >> 8)) / (ClockFreq >> 7)";
+				 size = 32;
+				 type = SLV;
+				 access_bus = READ_WRITE;
+				 access_dev = READ_ONLY;
+			};
+	 };
+
+	 reg {
+			name = "Transmit data regsiter";
+			prefix = "TDR";
+			
+			field {
+				 name = "Transmit data";
+				 prefix = "TX_DATA";
+				 size = 8;
+				 type = SLV;
+				 access_bus = READ_WRITE;
+				 access_dev = READ_WRITE;
+				 load = LOAD_EXT;
+			};
+	 };
+	 
+	 reg {
+			name = "Receive data regsiter";
+			prefix = "RDR";
+			
+
+			field {
+				 ack_read = "rdr_rack_o";
+				 name = "Received data";
+				 prefix = "RX_DATA";
+				 size = 8;
+				 type = SLV;
+				 access_bus = READ_ONLY;
+				 access_dev = WRITE_ONLY;
+			};
+	 };
+
+  fifo_reg {
+		size = 2048;
+		direction = CORE_TO_BUS;
+		prefix = "debug";
+		name = "UART TX FIFO";
+		description = "This FIFO holds the TX chars that UART tries to send away";
+		flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
+		flags_dev = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
+		
+		field {
+			name = "Char sent by UART to TX";
+			prefix = "tx";
+			type = SLV;
+			size = 8;
+		};
+
+		field {
+			name = "Dupa";
+			prefix = "dupa";
+			type = SLV;
+			size = 32;
+		};
+
+	};
+};
diff --git a/modules/wishbone/wb_virtual_uart/wb_virtual_uart_slave.vhd b/modules/wishbone/wb_virtual_uart/wb_virtual_uart_slave.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..517b770cf73b591bbe3863bb633f956b1ac392c4
--- /dev/null
+++ b/modules/wishbone/wb_virtual_uart/wb_virtual_uart_slave.vhd
@@ -0,0 +1,353 @@
+---------------------------------------------------------------------------------------
+-- Title          : Wishbone slave core for Virtual UART
+---------------------------------------------------------------------------------------
+-- File           : wb_virtual_uart_slave.vhd
+-- Author         : auto-generated by wbgen2 from wb_virtual_uart.wb
+-- Created        : Sun Apr 10 20:25:49 2011
+-- Standard       : VHDL'87
+---------------------------------------------------------------------------------------
+-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wb_virtual_uart.wb
+-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
+---------------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+library wbgen2;
+use wbgen2.wbgen2_pkg.all;
+
+entity wb_virtual_uart_slave is
+  port (
+    rst_n_i                                  : in     std_logic;
+    wb_clk_i                                 : in     std_logic;
+    wb_addr_i                                : in     std_logic_vector(2 downto 0);
+    wb_data_i                                : in     std_logic_vector(31 downto 0);
+    wb_data_o                                : out    std_logic_vector(31 downto 0);
+    wb_cyc_i                                 : in     std_logic;
+    wb_sel_i                                 : in     std_logic_vector(3 downto 0);
+    wb_stb_i                                 : in     std_logic;
+    wb_we_i                                  : in     std_logic;
+    wb_ack_o                                 : out    std_logic;
+-- Port for BIT field: 'TX busy' in reg: 'Status Register'
+    uart_sr_tx_busy_i                        : in     std_logic;
+-- Port for BIT field: 'RX ready' in reg: 'Status Register'
+    uart_sr_rx_rdy_i                         : in     std_logic;
+-- Port for std_logic_vector field: 'Baudrate divider setting' in reg: 'Baudrate control register'
+    uart_bcr_o                               : out    std_logic_vector(31 downto 0);
+-- Port for std_logic_vector field: 'Transmit data' in reg: 'Transmit data regsiter'
+    uart_tdr_tx_data_o                       : out    std_logic_vector(7 downto 0);
+    uart_tdr_tx_data_i                       : in     std_logic_vector(7 downto 0);
+    uart_tdr_tx_data_load_o                  : out    std_logic;
+-- Port for std_logic_vector field: 'Received data' in reg: 'Receive data regsiter'
+    uart_rdr_rx_data_i                       : in     std_logic_vector(7 downto 0);
+    rdr_rack_o                               : out    std_logic;
+-- FIFO write request
+    uart_debug_wr_req_i                      : in     std_logic;
+-- FIFO full flag
+    uart_debug_wr_full_o                     : out    std_logic;
+-- FIFO empty flag
+    uart_debug_wr_empty_o                    : out    std_logic;
+-- FIFO number of used words
+    uart_debug_wr_usedw_o                    : out    std_logic_vector(10 downto 0);
+    uart_debug_tx_i                          : in     std_logic_vector(7 downto 0);
+    uart_debug_dupa_i                        : in     std_logic_vector(31 downto 0)
+  );
+end wb_virtual_uart_slave;
+
+architecture syn of wb_virtual_uart_slave is
+
+signal uart_bcr_int                             : std_logic_vector(31 downto 0);
+signal uart_debug_in_int                        : std_logic_vector(39 downto 0);
+signal uart_debug_out_int                       : std_logic_vector(39 downto 0);
+signal uart_debug_rdreq_int                     : std_logic      ;
+signal uart_debug_rdreq_int_d0                  : std_logic      ;
+signal uart_debug_full_int                      : std_logic      ;
+signal uart_debug_empty_int                     : std_logic      ;
+signal uart_debug_usedw_int                     : std_logic_vector(10 downto 0);
+signal ack_sreg                                 : std_logic_vector(9 downto 0);
+signal rddata_reg                               : std_logic_vector(31 downto 0);
+signal wrdata_reg                               : std_logic_vector(31 downto 0);
+signal bwsel_reg                                : std_logic_vector(3 downto 0);
+signal rwaddr_reg                               : std_logic_vector(2 downto 0);
+signal ack_in_progress                          : std_logic      ;
+signal wr_int                                   : std_logic      ;
+signal rd_int                                   : std_logic      ;
+signal bus_clock_int                            : std_logic      ;
+signal allones                                  : std_logic_vector(31 downto 0);
+signal allzeros                                 : std_logic_vector(31 downto 0);
+
+begin
+-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
+  wrdata_reg <= wb_data_i;
+  bwsel_reg <= wb_sel_i;
+  bus_clock_int <= wb_clk_i;
+  rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
+  wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
+  allones <= (others => '1');
+  allzeros <= (others => '0');
+-- 
+-- Main register bank access process.
+  process (bus_clock_int, rst_n_i)
+  begin
+    if (rst_n_i = '0') then 
+      ack_sreg <= "0000000000";
+      ack_in_progress <= '0';
+      rddata_reg <= "00000000000000000000000000000000";
+      uart_bcr_int <= "00000000000000000000000000000000";
+      uart_tdr_tx_data_load_o <= '0';
+      rdr_rack_o <= '0';
+      uart_debug_rdreq_int <= '0';
+    elsif rising_edge(bus_clock_int) then
+-- advance the ACK generator shift register
+      ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
+      ack_sreg(9) <= '0';
+      if (ack_in_progress = '1') then
+        if (ack_sreg(0) = '1') then
+          uart_tdr_tx_data_load_o <= '0';
+          rdr_rack_o <= '0';
+          ack_in_progress <= '0';
+        else
+          uart_tdr_tx_data_load_o <= '0';
+        end if;
+      else
+        if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
+          case rwaddr_reg(2 downto 0) is
+          when "000" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(0) <= uart_sr_tx_busy_i;
+              rddata_reg(1) <= uart_sr_rx_rdy_i;
+              rddata_reg(2) <= 'X';
+              rddata_reg(3) <= 'X';
+              rddata_reg(4) <= 'X';
+              rddata_reg(5) <= 'X';
+              rddata_reg(6) <= 'X';
+              rddata_reg(7) <= 'X';
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "001" => 
+            if (wb_we_i = '1') then
+              uart_bcr_int <= wrdata_reg(31 downto 0);
+            else
+              rddata_reg(31 downto 0) <= uart_bcr_int;
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "010" => 
+            if (wb_we_i = '1') then
+              uart_tdr_tx_data_load_o <= '1';
+            else
+              rddata_reg(7 downto 0) <= uart_tdr_tx_data_i;
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "011" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(7 downto 0) <= uart_rdr_rx_data_i;
+              rdr_rack_o <= '1';
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "100" => 
+            if (wb_we_i = '1') then
+            else
+              if (uart_debug_rdreq_int_d0 = '0') then
+                uart_debug_rdreq_int <= not uart_debug_rdreq_int;
+              else
+                rddata_reg(7 downto 0) <= uart_debug_out_int(7 downto 0);
+                ack_in_progress <= '1';
+                ack_sreg(0) <= '1';
+              end if;
+              rddata_reg(8) <= 'X';
+              rddata_reg(9) <= 'X';
+              rddata_reg(10) <= 'X';
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(16) <= 'X';
+              rddata_reg(17) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+          when "101" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(31 downto 0) <= uart_debug_out_int(39 downto 8);
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when "110" => 
+            if (wb_we_i = '1') then
+            else
+              rddata_reg(16) <= uart_debug_full_int;
+              rddata_reg(17) <= uart_debug_empty_int;
+              rddata_reg(10 downto 0) <= uart_debug_usedw_int;
+              rddata_reg(11) <= 'X';
+              rddata_reg(12) <= 'X';
+              rddata_reg(13) <= 'X';
+              rddata_reg(14) <= 'X';
+              rddata_reg(15) <= 'X';
+              rddata_reg(18) <= 'X';
+              rddata_reg(19) <= 'X';
+              rddata_reg(20) <= 'X';
+              rddata_reg(21) <= 'X';
+              rddata_reg(22) <= 'X';
+              rddata_reg(23) <= 'X';
+              rddata_reg(24) <= 'X';
+              rddata_reg(25) <= 'X';
+              rddata_reg(26) <= 'X';
+              rddata_reg(27) <= 'X';
+              rddata_reg(28) <= 'X';
+              rddata_reg(29) <= 'X';
+              rddata_reg(30) <= 'X';
+              rddata_reg(31) <= 'X';
+            end if;
+            ack_sreg(0) <= '1';
+            ack_in_progress <= '1';
+          when others =>
+-- prevent the slave from hanging the bus on invalid address
+            ack_in_progress <= '1';
+            ack_sreg(0) <= '1';
+          end case;
+        end if;
+      end if;
+    end if;
+  end process;
+  
+  
+-- Drive the data output bus
+  wb_data_o <= rddata_reg;
+-- TX busy
+-- RX ready
+-- Baudrate divider setting
+  uart_bcr_o <= uart_bcr_int;
+-- Transmit data
+  uart_tdr_tx_data_o <= wrdata_reg(7 downto 0);
+-- Received data
+-- extra code for reg/fifo/mem: UART TX FIFO
+  uart_debug_in_int(7 downto 0) <= uart_debug_tx_i;
+  uart_debug_in_int(39 downto 8) <= uart_debug_dupa_i;
+  uart_debug_INST : wbgen2_fifo_sync
+    generic map (
+      g_size               => 2048,
+      g_width              => 40,
+      g_usedw_size         => 11
+    )
+    port map (
+      wr_req_i             => uart_debug_wr_req_i,
+      wr_full_o            => uart_debug_wr_full_o,
+      wr_empty_o           => uart_debug_wr_empty_o,
+      wr_usedw_o           => uart_debug_wr_usedw_o,
+      rd_full_o            => uart_debug_full_int,
+      rd_empty_o           => uart_debug_empty_int,
+      rd_usedw_o           => uart_debug_usedw_int,
+      rd_req_i             => uart_debug_rdreq_int,
+      clk_i                => bus_clock_int,
+      wr_data_i            => uart_debug_in_int,
+      rd_data_o            => uart_debug_out_int
+    );
+  
+-- extra code for reg/fifo/mem: FIFO 'UART TX FIFO' data output register 0
+  process (bus_clock_int, rst_n_i)
+  begin
+    if (rst_n_i = '0') then 
+      uart_debug_rdreq_int_d0 <= '0';
+    elsif rising_edge(bus_clock_int) then
+      uart_debug_rdreq_int_d0 <= uart_debug_rdreq_int;
+    end if;
+  end process;
+  
+  
+-- extra code for reg/fifo/mem: FIFO 'UART TX FIFO' data output register 1
+  rwaddr_reg <= wb_addr_i;
+-- ACK signal generation. Just pass the LSB of ACK counter.
+  wb_ack_o <= ack_sreg(0);
+end syn;
diff --git a/modules/wishbone/wb_virtual_uart/wb_vuart.h b/modules/wishbone/wb_virtual_uart/wb_vuart.h
new file mode 100644
index 0000000000000000000000000000000000000000..95a41b4c75898829c0f754bc68db0e1bd18aec38
--- /dev/null
+++ b/modules/wishbone/wb_virtual_uart/wb_vuart.h
@@ -0,0 +1,103 @@
+/*
+  Register definitions for slave core: Virtual UART
+
+  * File           : wb_vuart.h
+  * Author         : auto-generated by wbgen2 from wb_virtual_uart.wb
+  * Created        : Thu Apr  7 00:51:02 2011
+  * Standard       : ANSI C
+
+    THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wb_virtual_uart.wb
+    DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
+
+*/
+
+#ifndef __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
+#define __WBGEN2_REGDEFS_WB_VIRTUAL_UART_WB
+
+#include <inttypes.h>
+
+#if defined( __GNUC__)
+#define PACKED __attribute__ ((packed))
+#else
+#error "Unsupported compiler?"
+#endif
+
+#ifndef __WBGEN2_MACROS_DEFINED__
+#define __WBGEN2_MACROS_DEFINED__
+#define WBGEN2_GEN_MASK(offset, size) (((1<<(size))-1) << (offset))
+#define WBGEN2_GEN_WRITE(value, offset, size) (((value) & ((1<<(size))-1)) << (offset))
+#define WBGEN2_GEN_READ(reg, offset, size) (((reg) >> (offset)) & ((1<<(size))-1))
+#define WBGEN2_SIGN_EXTEND(value, bits) (((value) & (1<<bits) ? ~((1<<(bits))-1): 0 ) | (value))
+#endif
+
+
+/* definitions for register: Status Register */
+
+/* definitions for field: TX busy in reg: Status Register */
+#define UART_SR_TX_BUSY                       WBGEN2_GEN_MASK(0, 1)
+
+/* definitions for field: RX ready in reg: Status Register */
+#define UART_SR_RX_RDY                        WBGEN2_GEN_MASK(1, 1)
+
+/* definitions for register: Baudrate control register */
+
+/* definitions for register: Transmit data regsiter */
+
+/* definitions for field: Transmit data in reg: Transmit data regsiter */
+#define UART_TDR_TX_DATA_MASK                 WBGEN2_GEN_MASK(0, 8)
+#define UART_TDR_TX_DATA_SHIFT                0
+#define UART_TDR_TX_DATA_W(value)             WBGEN2_GEN_WRITE(value, 0, 8)
+#define UART_TDR_TX_DATA_R(reg)               WBGEN2_GEN_READ(reg, 0, 8)
+
+/* definitions for register: Receive data regsiter */
+
+/* definitions for field: Received data in reg: Receive data regsiter */
+#define UART_RDR_RX_DATA_MASK                 WBGEN2_GEN_MASK(0, 8)
+#define UART_RDR_RX_DATA_SHIFT                0
+#define UART_RDR_RX_DATA_W(value)             WBGEN2_GEN_WRITE(value, 0, 8)
+#define UART_RDR_RX_DATA_R(reg)               WBGEN2_GEN_READ(reg, 0, 8)
+
+/* definitions for register: FIFO 'UART TX FIFO' data output register 0 */
+
+/* definitions for field: Char sent by UART to TX in reg: FIFO 'UART TX FIFO' data output register 0 */
+#define UART_DEBUG_R0_TX_MASK                 WBGEN2_GEN_MASK(0, 8)
+#define UART_DEBUG_R0_TX_SHIFT                0
+#define UART_DEBUG_R0_TX_W(value)             WBGEN2_GEN_WRITE(value, 0, 8)
+#define UART_DEBUG_R0_TX_R(reg)               WBGEN2_GEN_READ(reg, 0, 8)
+
+/* definitions for register: FIFO 'UART TX FIFO' data output register 1 */
+
+/* definitions for field: Dupa in reg: FIFO 'UART TX FIFO' data output register 1 */
+#define UART_DEBUG_R1_DUPA_MASK               WBGEN2_GEN_MASK(0, 32)
+#define UART_DEBUG_R1_DUPA_SHIFT              0
+#define UART_DEBUG_R1_DUPA_W(value)           WBGEN2_GEN_WRITE(value, 0, 32)
+#define UART_DEBUG_R1_DUPA_R(reg)             WBGEN2_GEN_READ(reg, 0, 32)
+
+/* definitions for register: FIFO 'UART TX FIFO' control/status register */
+
+/* definitions for field: FIFO full flag in reg: FIFO 'UART TX FIFO' control/status register */
+#define UART_DEBUG_CSR_FULL                   WBGEN2_GEN_MASK(16, 1)
+
+/* definitions for field: FIFO empty flag in reg: FIFO 'UART TX FIFO' control/status register */
+#define UART_DEBUG_CSR_EMPTY                  WBGEN2_GEN_MASK(17, 1)
+
+/* definitions for field: FIFO counter in reg: FIFO 'UART TX FIFO' control/status register */
+#define UART_DEBUG_CSR_USEDW_MASK             WBGEN2_GEN_MASK(0, 8)
+#define UART_DEBUG_CSR_USEDW_SHIFT            0
+#define UART_DEBUG_CSR_USEDW_W(value)         WBGEN2_GEN_WRITE(value, 0, 8)
+#define UART_DEBUG_CSR_USEDW_R(reg)           WBGEN2_GEN_READ(reg, 0, 8)
+/* [0x0]: REG Status Register */
+#define UART_REG_SR 0x00000000
+/* [0x4]: REG Baudrate control register */
+#define UART_REG_BCR 0x00000004
+/* [0x8]: REG Transmit data regsiter */
+#define UART_REG_TDR 0x00000008
+/* [0xc]: REG Receive data regsiter */
+#define UART_REG_RDR 0x0000000c
+/* [0x10]: REG FIFO 'UART TX FIFO' data output register 0 */
+#define UART_REG_DEBUG_R0 0x00000010
+/* [0x14]: REG FIFO 'UART TX FIFO' data output register 1 */
+#define UART_REG_DEBUG_R1 0x00000014
+/* [0x18]: REG FIFO 'UART TX FIFO' control/status register */
+#define UART_REG_DEBUG_CSR 0x00000018
+#endif
diff --git a/modules/wishbone/wbgen2/Manifest.py b/modules/wishbone/wbgen2/Manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9c5c160d3cefee47cda714a1ff568f586dbc772
--- /dev/null
+++ b/modules/wishbone/wbgen2/Manifest.py
@@ -0,0 +1,7 @@
+files = ["wbgen2_dpssram.vhd",
+				"wbgen2_eic.vhd",
+				"wbgen2_fifo_async.vhd",
+				"wbgen2_fifo_sync.vhd",
+				"wbgen2_pkg.vhd"]
+
+library = "wbgen2"
diff --git a/modules/wishbone/wbgen2/wbgen2_dpssram.vhd b/modules/wishbone/wbgen2/wbgen2_dpssram.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f5576651a990e5892aefa0227e599bc68ef091f4
--- /dev/null
+++ b/modules/wishbone/wbgen2/wbgen2_dpssram.vhd
@@ -0,0 +1,102 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+--use work.genram_pkg.all;
+--use work.common_components.all;
+
+library wbgen2;
+use wbgen2.wbgen2_pkg.all;
+
+entity wbgen2_dpssram is
+
+  generic (
+    g_data_width : natural := 32;
+    g_size       : natural := 1024;
+    g_addr_width : natural := 10;
+    g_dual_clock : boolean := true;
+    g_use_bwsel  : boolean := true);
+
+  port (
+    clk_a_i : in std_logic;
+    clk_b_i : in std_logic;
+
+    addr_a_i : in std_logic_vector(g_addr_width-1 downto 0);
+    addr_b_i : in std_logic_vector(g_addr_width-1 downto 0);
+
+    data_a_i : in std_logic_vector(g_data_width-1 downto 0);
+    data_b_i : in std_logic_vector(g_data_width-1 downto 0);
+
+    data_a_o : out std_logic_vector(g_data_width-1 downto 0);
+    data_b_o : out std_logic_vector(g_data_width-1 downto 0);
+
+    bwsel_a_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
+    bwsel_b_i : in std_logic_vector((g_data_width+7)/8-1 downto 0);
+
+    rd_a_i : in std_logic;
+    rd_b_i : in std_logic;
+
+    wr_a_i : in std_logic;
+    wr_b_i : in std_logic
+    );
+
+end wbgen2_dpssram;
+
+
+architecture syn of wbgen2_dpssram is
+    function f_log2_size (A : natural) return natural is
+  begin
+    for I in 1 to 64 loop               -- Works for up to 64 bits
+      if (2**I > A) then
+        return(I-1);
+      end if;
+    end loop;
+    return(63);
+  end function f_log2_size;
+
+  component generic_dpram
+    generic (
+      g_data_width               : natural;
+      g_size                     : natural;
+      g_with_byte_enable         : boolean;
+      g_addr_conflict_resolution : string := "read_first";
+      g_init_file                : string := "";
+      g_dual_clock               : boolean);
+    port (
+      rst_n_i : in  std_logic := '1';
+      clka_i  : in  std_logic;
+      bwea_i  : in  std_logic_vector(g_data_width/8-1 downto 0);
+      wea_i   : in  std_logic;
+      aa_i    : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      da_i    : in  std_logic_vector(g_data_width-1 downto 0);
+      qa_o    : out std_logic_vector(g_data_width-1 downto 0);
+      clkb_i  : in  std_logic;
+      bweb_i  : in  std_logic_vector(g_data_width/8-1 downto 0);
+      web_i   : in  std_logic;
+      ab_i    : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      db_i    : in  std_logic_vector(g_data_width-1 downto 0);
+      qb_o    : out std_logic_vector(g_data_width-1 downto 0));
+  end component;
+begin
+
+  wrapped_dpram: generic_dpram
+    generic map (
+      g_data_width               => g_data_width,
+      g_size                     => g_size,
+      g_with_byte_enable         => g_use_bwsel,
+      g_dual_clock               => g_dual_clock)
+    port map (
+      rst_n_i => '1',
+      clka_i  => clk_a_i,
+      bwea_i  => bwsel_a_i,
+      wea_i   => wr_a_i,
+      aa_i    => addr_a_i,
+      da_i    => data_a_i,
+      qa_o    => data_a_o,
+      clkb_i  => clk_b_i,
+      bweb_i  => bwsel_b_i,
+      web_i   => wr_b_i,
+      ab_i    => addr_b_i,
+      db_i    => data_b_i,
+      qb_o    => data_b_o);
+ 
+end syn;
diff --git a/modules/wishbone/wbgen2/wbgen2_eic.vhd b/modules/wishbone/wbgen2/wbgen2_eic.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..840590a4bf61bf207aeddb115b31bbec709ff099
--- /dev/null
+++ b/modules/wishbone/wbgen2/wbgen2_eic.vhd
@@ -0,0 +1,213 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+
+library wbgen2;
+use wbgen2.wbgen2_pkg.all;
+
+entity wbgen2_eic is
+  
+  generic (
+    g_num_interrupts : natural := 1;
+
+    g_irq00_mode : integer := 0;
+    g_irq01_mode : integer := 0;
+    g_irq02_mode : integer := 0;
+    g_irq03_mode : integer := 0;
+    g_irq04_mode : integer := 0;
+    g_irq05_mode : integer := 0;
+    g_irq06_mode : integer := 0;
+    g_irq07_mode : integer := 0;
+    g_irq08_mode : integer := 0;
+    g_irq09_mode : integer := 0;
+    g_irq0a_mode : integer := 0;
+    g_irq0b_mode : integer := 0;
+    g_irq0c_mode : integer := 0;
+    g_irq0d_mode : integer := 0;
+    g_irq0e_mode : integer := 0;
+    g_irq0f_mode : integer := 0;
+    g_irq10_mode : integer := 0;
+    g_irq11_mode : integer := 0;
+    g_irq12_mode : integer := 0;
+    g_irq13_mode : integer := 0;
+    g_irq14_mode : integer := 0;
+    g_irq15_mode : integer := 0;
+    g_irq16_mode : integer := 0;
+    g_irq17_mode : integer := 0;
+    g_irq18_mode : integer := 0;
+    g_irq19_mode : integer := 0;
+    g_irq1a_mode : integer := 0;
+    g_irq1b_mode : integer := 0;
+    g_irq1c_mode : integer := 0;
+    g_irq1d_mode : integer := 0;
+    g_irq1e_mode : integer := 0;
+    g_irq1f_mode : integer := 0
+    );
+  port(
+    rst_n_i : in std_logic;             -- reset & system clock, as always :)
+    clk_i   : in std_logic;
+
+    -- raw interrupt inputs
+    irq_i : in std_logic_vector(g_num_interrupts-1 downto 0);  
+
+    -- interrupt acknowledge signal, used for level-active interrupts to
+    -- indicate that the interrupt has been handled
+    irq_ack_o: out std_logic_vector(g_num_interrupts-1 downto 0);  
+
+-- interrupt mask regsiter (slv/bus read-only)
+    reg_imr_o : out std_logic_vector(g_num_interrupts-1 downto 0);
+
+-- interrupt enable/disable registers (slv/bus pass-through)
+    reg_ier_i        : in std_logic_vector(g_num_interrupts-1 downto 0);
+    reg_ier_wr_stb_i : in std_logic;
+
+    reg_idr_i        : in std_logic_vector(g_num_interrupts-1 downto 0);
+    reg_idr_wr_stb_i : in std_logic;
+
+-- interrupt status register (slv/bus write with LOAD_EXT)
+    reg_isr_o        : out std_logic_vector(g_num_interrupts-1 downto 0);
+    reg_isr_i        : in  std_logic_vector(g_num_interrupts-1 downto 0);
+    reg_isr_wr_stb_i : in  std_logic;
+
+-- multiplexed wishbone irq output
+    wb_irq_o : out std_logic
+
+    );
+
+end wbgen2_eic;
+
+architecture syn of wbgen2_eic is
+
+  subtype t_irq_mode is integer;
+  type t_irq_mode_vec is array (0 to 31) of t_irq_mode;
+
+  constant c_IRQ_MODE_RISING_EDGE  : t_irq_mode := 0;
+  constant c_IRQ_MODE_FALLING_EDGE : t_irq_mode := 1;
+  constant c_IRQ_MODE_LEVEL_0      : t_irq_mode := 2;
+  constant c_IRQ_MODE_LEVEL_1      : t_irq_mode := 3;
+
+
+  signal irq_mode : t_irq_mode_vec;
+
+  signal irq_mask    : std_logic_vector(g_num_interrupts-1 downto 0);
+  signal irq_pending : std_logic_vector(g_num_interrupts-1 downto 0);
+
+  signal irq_i_d0 : std_logic_vector(g_num_interrupts-1 downto 0);
+  signal irq_i_d1 : std_logic_vector(g_num_interrupts-1 downto 0);
+  signal irq_i_d2 : std_logic_vector(g_num_interrupts-1 downto 0);
+  
+begin  -- syn
+
+  irq_mode(0)  <= g_irq00_mode;
+  irq_mode(1)  <= g_irq01_mode;
+  irq_mode(2)  <= g_irq02_mode;
+  irq_mode(3)  <= g_irq03_mode;
+  irq_mode(4)  <= g_irq04_mode;
+  irq_mode(5)  <= g_irq05_mode;
+  irq_mode(6)  <= g_irq06_mode;
+  irq_mode(7)  <= g_irq07_mode;
+  irq_mode(8)  <= g_irq08_mode;
+  irq_mode(9)  <= g_irq09_mode;
+  irq_mode(10) <= g_irq0a_mode;
+  irq_mode(11) <= g_irq0b_mode;
+  irq_mode(12) <= g_irq0c_mode;
+  irq_mode(13) <= g_irq0d_mode;
+  irq_mode(14) <= g_irq0e_mode;
+  irq_mode(15) <= g_irq0f_mode;
+  irq_mode(16) <= g_irq10_mode;
+  irq_mode(17) <= g_irq11_mode;
+  irq_mode(18) <= g_irq12_mode;
+  irq_mode(19) <= g_irq13_mode;
+  irq_mode(20) <= g_irq14_mode;
+  irq_mode(21) <= g_irq15_mode;
+  irq_mode(22) <= g_irq16_mode;
+  irq_mode(23) <= g_irq17_mode;
+  irq_mode(24) <= g_irq18_mode;
+  irq_mode(25) <= g_irq19_mode;
+  irq_mode(26) <= g_irq1a_mode;
+  irq_mode(27) <= g_irq1b_mode;
+  irq_mode(28) <= g_irq1c_mode;
+  irq_mode(29) <= g_irq1d_mode;
+  irq_mode(30) <= g_irq1e_mode;
+  irq_mode(31) <= g_irq1f_mode;
+
+
+  process(clk_i, rst_n_i)
+  begin
+    if(rst_n_i = '0') then
+      irq_i_d0    <= (others => '0');
+      irq_i_d1    <= (others => '0');
+      irq_i_d1    <= (others => '0');
+      irq_pending <= (others => '0');
+      irq_mask    <= (others => '0');
+      
+    elsif rising_edge(clk_i) then
+
+      for i in 0 to g_num_interrupts-1 loop
+        
+        irq_i_d0(i) <= irq_i(i);
+        irq_i_d1(i) <= irq_i_d0(i);
+        irq_i_d2(i) <= irq_i_d1(i);
+
+
+        if((reg_isr_i(i) = '1' and reg_isr_wr_stb_i = '1') or irq_mask(i) = '0') then
+          irq_pending(i) <= '0';
+          irq_i_d0(i) <= '0';
+          irq_i_d1(i) <= '0';
+          irq_i_d2(i) <= '0';
+        
+        else
+          
+          case irq_mode(i) is
+            when c_IRQ_MODE_LEVEL_0      => irq_pending(i) <= not irq_i_d2(i);
+            when c_IRQ_MODE_LEVEL_1      => irq_pending(i) <= irq_i_d2(i);
+            when c_IRQ_MODE_RISING_EDGE  => irq_pending(i) <= irq_pending(i) or ((not irq_i_d2(i)) and irq_i_d1(i));
+            when c_IRQ_MODE_FALLING_EDGE => irq_pending(i) <= irq_pending(i) or ((not irq_i_d1(i)) and irq_i_d2(i));
+            when others                  => null;
+          end case;
+        end if;
+      end loop;  -- i
+
+      if(reg_ier_wr_stb_i = '1') then
+        for i in 0 to g_num_interrupts-1 loop
+          if(reg_ier_i(i) = '1') then
+            irq_mask(i) <= '1';
+          end if;
+        end loop;
+      end if;
+
+      if(reg_idr_wr_stb_i = '1') then
+        for i in 0 to g_num_interrupts-1 loop
+          if(reg_idr_i(i) = '1') then
+            irq_mask(i) <= '0';
+          end if;
+        end loop;
+      end if;
+    end if;
+  end process;
+
+  -- generation of wb_irq_o
+
+  process(clk_i, rst_n_i)
+  begin
+    if(rst_n_i = '0') then
+      wb_irq_o <= '0';
+    elsif rising_edge(clk_i) then
+      if(irq_pending = std_logic_vector(to_unsigned(0, g_num_interrupts))) then
+        wb_irq_o <= '0';
+      else
+        wb_irq_o <= '1';
+      end if;
+      
+    end if;
+  end process;
+
+  gen_irq_ack: for i in 0 to g_num_interrupts-1 generate
+    irq_ack_o(i) <= '1' when (reg_isr_wr_stb_i = '1' and reg_isr_i(i) = '1') else '0';
+  end generate gen_irq_ack;
+
+  reg_imr_o <= irq_mask;
+  reg_isr_o <= irq_pending;
+
+end syn;
diff --git a/modules/wishbone/wbgen2/wbgen2_fifo_async.vhd b/modules/wishbone/wbgen2/wbgen2_fifo_async.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..0ffb664e92be97471bd50db4e301b4b5bef9f3f1
--- /dev/null
+++ b/modules/wishbone/wbgen2/wbgen2_fifo_async.vhd
@@ -0,0 +1,115 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+use work.genram_pkg.all;
+
+library wbgen2;
+use wbgen2.wbgen2_pkg.all;
+
+entity wbgen2_fifo_async is
+  generic (
+    g_size       : integer;
+    g_width      : integer;
+    g_usedw_size : integer
+    );
+
+  port
+    (
+      rd_clk_i  : in  std_logic;
+      rd_req_i  : in  std_logic;
+      rd_data_o : out std_logic_vector(g_width-1 downto 0);
+
+      rd_empty_o : out std_logic;
+      rd_full_o  : out std_logic;
+      rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
+
+
+      wr_clk_i  : in std_logic;
+      wr_req_i  : in std_logic;
+      wr_data_i : in std_logic_vector(g_width-1 downto 0);
+
+      wr_empty_o : out std_logic;
+      wr_full_o  : out std_logic;
+      wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0)
+    );
+end wbgen2_fifo_async;
+
+architecture rtl of wbgen2_fifo_async is
+
+  component generic_async_fifo
+    generic (
+      g_data_width             : natural;
+      g_size                   : natural;
+      g_show_ahead             : boolean;
+      g_with_rd_empty          : boolean;
+      g_with_rd_full           : boolean;
+      g_with_rd_almost_empty   : boolean;
+      g_with_rd_almost_full    : boolean;
+      g_with_rd_count          : boolean;
+      g_with_wr_empty          : boolean;
+      g_with_wr_full           : boolean;
+      g_with_wr_almost_empty   : boolean;
+      g_with_wr_almost_full    : boolean;
+      g_with_wr_count          : boolean;
+      g_almost_empty_threshold : integer;
+      g_almost_full_threshold  : integer);
+    port (
+      rst_n_i           : in  std_logic := '1';
+      clk_wr_i          : in  std_logic;
+      d_i               : in  std_logic_vector(g_data_width-1 downto 0);
+      we_i              : in  std_logic;
+      wr_empty_o        : out std_logic;
+      wr_full_o         : out std_logic;
+      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);
+      clk_rd_i          : in  std_logic;
+      q_o               : out std_logic_vector(g_data_width-1 downto 0);
+      rd_i              : in  std_logic;
+      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;
+      rd_count_o        : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
+  end component;
+
+begin
+
+  wrapped_fifo: generic_async_fifo
+    generic map (
+      g_data_width             => g_width,
+      g_size                   => g_size,
+      g_show_ahead             => false,
+      g_with_rd_empty          => true,
+      g_with_rd_full           => true,
+      g_with_rd_almost_empty   => false,
+      g_with_rd_almost_full    => false,
+      g_with_rd_count          => true,
+      g_with_wr_empty          => true,
+      g_with_wr_full           => true,
+      g_with_wr_almost_empty   => false,
+      g_with_wr_almost_full    => false,
+      g_with_wr_count          => true,
+      g_almost_empty_threshold => 0,
+      g_almost_full_threshold  => 0)
+    port map (
+      rst_n_i           => '1',
+      clk_wr_i          => wr_clk_i,
+      d_i               => wr_data_i,
+      we_i              => wr_req_i,
+      wr_empty_o        => wr_empty_o,
+      wr_full_o         => wr_full_o,
+      wr_almost_empty_o => open,
+      wr_almost_full_o  => open,
+      wr_count_o        => wr_usedw_o,
+      clk_rd_i          => rd_clk_i,
+      q_o               => rd_data_o,
+      rd_i              => rd_req_i,
+      rd_empty_o        => rd_empty_o,
+      rd_full_o         => rd_full_o,
+      rd_almost_empty_o => open,
+      rd_almost_full_o  => open,
+      rd_count_o        => rd_usedw_o);
+  
+end rtl;
diff --git a/modules/wishbone/wbgen2/wbgen2_fifo_sync.vhd b/modules/wishbone/wbgen2/wbgen2_fifo_sync.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..ea01ae9201bceb14ca559e27d07c61f9ccbcea36
--- /dev/null
+++ b/modules/wishbone/wbgen2/wbgen2_fifo_sync.vhd
@@ -0,0 +1,114 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+library wbgen2;
+use wbgen2.wbgen2_pkg.all;
+
+
+entity wbgen2_fifo_sync is
+  generic (
+    g_width      : integer;
+    g_size       : integer;
+    g_usedw_size : integer);
+
+  port
+    (
+      clk_i     : in std_logic;
+      wr_data_i : in std_logic_vector(g_width-1 downto 0);
+      wr_req_i  : in std_logic;
+
+      rd_data_o : out std_logic_vector(g_width-1 downto 0);
+      rd_req_i  : in  std_logic;
+
+      wr_empty_o : out std_logic;
+      wr_full_o  : out std_logic;
+      wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
+
+      rd_empty_o : out std_logic;
+      rd_full_o  : out std_logic;
+      rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0)
+
+      );
+end wbgen2_fifo_sync;
+
+
+architecture rtl of wbgen2_fifo_sync is
+
+
+  function f_log2_size (A : natural) return natural is
+  begin
+    for I in 1 to 64 loop               -- Works for up to 64 bits
+      if (2**I > A) then
+        return(I-1);
+      end if;
+    end loop;
+    return(63);
+  end function f_log2_size;
+
+  component generic_sync_fifo
+    generic (
+      g_data_width             : natural;
+      g_size                   : natural;
+      g_show_ahead             : boolean;
+      g_with_empty             : boolean;
+      g_with_full              : boolean;
+      g_with_almost_empty      : boolean;
+      g_with_almost_full       : boolean;
+      g_with_count             : boolean;
+      g_almost_empty_threshold : integer := 0;
+      g_almost_full_threshold  : integer := 0);
+    port (
+      rst_n_i        : in  std_logic := '1';
+      clk_i          : in  std_logic;
+      d_i            : in  std_logic_vector(g_data_width-1 downto 0);
+      we_i           : in  std_logic;
+      q_o            : out std_logic_vector(g_data_width-1 downto 0);
+      rd_i           : in  std_logic;
+      empty_o        : out std_logic;
+      full_o         : out std_logic;
+      almost_empty_o : out std_logic;
+      almost_full_o  : out std_logic;
+      count_o        : out std_logic_vector(f_log2_size(g_size)-1 downto 0));
+  end component;
+  
+  signal empty_int : std_logic;
+  signal full_int : std_logic;
+  signal usedw_int : std_logic_vector(g_usedw_size-1 downto 0);
+  
+begin
+
+  wrapped_fifo: generic_sync_fifo
+    generic map (
+      g_data_width             => g_width,
+      g_size                   => g_size,
+      g_show_ahead             => false,
+      g_with_empty             => true,
+      g_with_full              => true,
+      g_with_almost_empty      => false,
+      g_with_almost_full       => false,
+      g_with_count             => true)
+    port map (
+      rst_n_i        => '1',
+      clk_i          => clk_i,
+      d_i            => wr_data_i,
+      we_i           => wr_req_i,
+      q_o            => rd_data_o,
+      rd_i           => rd_req_i,
+      empty_o        => empty_int,
+      full_o         => full_int,
+      almost_empty_o => open,
+      almost_full_o  => open,
+      count_o        => usedw_int);
+  
+
+  rd_empty_o <= empty_int;
+  rd_full_o <= full_int;
+  rd_usedw_o <= usedw_int;
+
+  wr_empty_o <= empty_int;
+  wr_full_o <= full_int;
+  wr_usedw_o <= usedw_int;
+  
+  
+end rtl;
diff --git a/modules/wishbone/wbgen2/wbgen2_pkg.vhd b/modules/wishbone/wbgen2/wbgen2_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..4a0489f6f238be5fd50b58b100d2f0efe920e8ae
--- /dev/null
+++ b/modules/wishbone/wbgen2/wbgen2_pkg.vhd
@@ -0,0 +1,125 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library wbgen2;
+
+package wbgen2_pkg is
+
+  
+  component wbgen2_dpssram
+    generic (
+      g_data_width : natural;
+      g_size       : natural;
+      g_addr_width : natural;
+      g_dual_clock : boolean;
+      g_use_bwsel  : boolean);
+    port (
+      clk_a_i   : in  std_logic;
+      clk_b_i   : in  std_logic;
+      addr_a_i  : in  std_logic_vector(g_addr_width-1 downto 0);
+      addr_b_i  : in  std_logic_vector(g_addr_width-1 downto 0);
+      data_a_i  : in  std_logic_vector(g_data_width-1 downto 0);
+      data_b_i  : in  std_logic_vector(g_data_width-1 downto 0);
+      data_a_o  : out std_logic_vector(g_data_width-1 downto 0);
+      data_b_o  : out std_logic_vector(g_data_width-1 downto 0);
+      bwsel_a_i : in  std_logic_vector((g_data_width+7)/8-1 downto 0);
+      bwsel_b_i : in  std_logic_vector((g_data_width+7)/8-1 downto 0);
+      rd_a_i    : in  std_logic;
+      rd_b_i    : in  std_logic;
+      wr_a_i    : in  std_logic;
+      wr_b_i    : in  std_logic);
+  end component;
+
+  
+  component wbgen2_eic
+    generic (
+      g_num_interrupts : natural;
+      g_irq00_mode     : integer;
+      g_irq01_mode     : integer;
+      g_irq02_mode     : integer;
+      g_irq03_mode     : integer;
+      g_irq04_mode     : integer;
+      g_irq05_mode     : integer;
+      g_irq06_mode     : integer;
+      g_irq07_mode     : integer;
+      g_irq08_mode     : integer;
+      g_irq09_mode     : integer;
+      g_irq0a_mode     : integer;
+      g_irq0b_mode     : integer;
+      g_irq0c_mode     : integer;
+      g_irq0d_mode     : integer;
+      g_irq0e_mode     : integer;
+      g_irq0f_mode     : integer;
+      g_irq10_mode     : integer;
+      g_irq11_mode     : integer;
+      g_irq12_mode     : integer;
+      g_irq13_mode     : integer;
+      g_irq14_mode     : integer;
+      g_irq15_mode     : integer;
+      g_irq16_mode     : integer;
+      g_irq17_mode     : integer;
+      g_irq18_mode     : integer;
+      g_irq19_mode     : integer;
+      g_irq1a_mode     : integer;
+      g_irq1b_mode     : integer;
+      g_irq1c_mode     : integer;
+      g_irq1d_mode     : integer;
+      g_irq1e_mode     : integer;
+      g_irq1f_mode     : integer);
+    port (
+      rst_n_i          : in  std_logic;
+      clk_i            : in  std_logic;
+      irq_i            : in  std_logic_vector(g_num_interrupts-1 downto 0);
+      irq_ack_o        : out std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_imr_o        : out std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_ier_i        : in  std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_ier_wr_stb_i : in  std_logic;
+      reg_idr_i        : in  std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_idr_wr_stb_i : in  std_logic;
+      reg_isr_o        : out std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_isr_i        : in  std_logic_vector(g_num_interrupts-1 downto 0);
+      reg_isr_wr_stb_i : in  std_logic;
+      wb_irq_o         : out std_logic);
+  end component;
+
+  component wbgen2_fifo_async
+    generic (
+      g_size       : integer;
+      g_width      : integer;
+      g_usedw_size : integer);
+    port (
+      rd_clk_i   : in  std_logic;
+      rd_req_i   : in  std_logic;
+      rd_data_o  : out std_logic_vector(g_width-1 downto 0);
+      rd_empty_o : out std_logic;
+      rd_full_o  : out std_logic;
+      rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
+      wr_clk_i   : in  std_logic;
+      wr_req_i   : in  std_logic;
+      wr_data_i  : in  std_logic_vector(g_width-1 downto 0);
+      wr_empty_o : out std_logic;
+      wr_full_o  : out std_logic;
+      wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0));
+  end component;
+
+
+  component wbgen2_fifo_sync
+    generic (
+      g_width      : integer;
+      g_size       : integer;
+      g_usedw_size : integer);
+    port (
+      clk_i      : in  std_logic;
+      wr_data_i  : in  std_logic_vector(g_width-1 downto 0);
+      wr_req_i   : in  std_logic;
+      rd_data_o  : out std_logic_vector(g_width-1 downto 0);
+      rd_req_i   : in  std_logic;
+      wr_empty_o : out std_logic;
+      wr_full_o  : out std_logic;
+      wr_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0);
+      rd_empty_o : out std_logic;
+      rd_full_o  : out std_logic;
+      rd_usedw_o : out std_logic_vector(g_usedw_size -1 downto 0));
+  end component;
+  
+end wbgen2_pkg;
diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..15d2e045009dbd6754f4d24e8cc39db6b26badc3
--- /dev/null
+++ b/modules/wishbone/wishbone_pkg.vhd
@@ -0,0 +1,97 @@
+library ieee;
+
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+
+package wishbone_pkg is
+
+-- number of wishbone masters provided by CPU->WB bridge
+--  constant c_wishbone_num_masters : integer := 12;
+-- CPU address bus width
+  constant c_cpu_addr_width      : integer := 19;
+-- WB address bus width. Must be log2(c_wishbone_num_masters) smaller than
+-- c_cpu_addr_width as the most significant bits select the master port (peripheral)
+  constant c_wishbone_addr_width : integer := 14;
+
+
+  component wb_cpu_bridge
+    generic (
+      g_simulation :integer := 0;
+      g_wishbone_num_masters : integer);
+    port (
+      sys_rst_n_i : in    std_logic;
+      cpu_clk_i   : in    std_logic;
+      cpu_cs_n_i  : in    std_logic;
+      cpu_wr_n_i  : in    std_logic;
+      cpu_rd_n_i  : in    std_logic;
+      cpu_bs_n_i  : in    std_logic_vector(3 downto 0);
+      cpu_addr_i  : in    std_logic_vector(c_cpu_addr_width-1 downto 0);
+      cpu_data_b  : inout std_logic_vector(31 downto 0);
+      cpu_nwait_o : out   std_logic;
+      wb_clk_i    : in    std_logic;
+      wb_addr_o   : out   std_logic_vector(c_wishbone_addr_width - 1 downto 0);
+      wb_data_o   : out   std_logic_vector(31 downto 0);
+      wb_stb_o    : out   std_logic;
+      wb_we_o     : out   std_logic;
+      wb_sel_o    : out   std_logic_vector(3 downto 0);
+      wb_cyc_o    : out   std_logic_vector (g_wishbone_num_masters - 1 downto 0);
+      wb_data_i   : in    std_logic_vector (32 * g_wishbone_num_masters-1 downto 0);
+      wb_ack_i    : in    std_logic_vector(g_wishbone_num_masters-1 downto 0));
+  end component;
+
+  component wb_gpio_port
+    generic (
+      g_num_pins : natural);
+    port (
+      sys_rst_n_i : in    std_logic;
+      wb_clk_i    : in    std_logic;
+      wb_sel_i    : in    std_logic;
+      wb_cyc_i    : in    std_logic;
+      wb_stb_i    : in    std_logic;
+      wb_we_i     : in    std_logic;
+      wb_addr_i   : in    std_logic_vector(2 downto 0);
+      wb_data_i   : in    std_logic_vector(31 downto 0);
+      wb_data_o   : out   std_logic_vector(31 downto 0);
+      wb_ack_o    : out   std_logic;
+      gpio_b      : inout std_logic_vector(g_num_pins-1 downto 0));
+  end component;
+
+  component wb_spi_master
+    port (
+      refclk2_i   : in  std_logic;
+      sys_rst_n_i : in  std_logic;
+      wb_sel_i    : in  std_logic;
+      wb_cyc_i    : in  std_logic;
+      wb_stb_i    : in  std_logic;
+      wb_we_i     : in  std_logic;
+      wb_addr_i   : in  std_logic_vector(c_wishbone_addr_width-1 downto 0);
+      wb_data_i   : in  std_logic_vector(31 downto 0);
+      wb_data_o   : out std_logic_vector(31 downto 0);
+      wb_ack_o    : out std_logic;
+      spi_mosi_o  : out std_logic;
+      spi_miso_i  : in  std_logic;
+      spi_cs_o    : out std_logic;
+      spi_sck_o   : out std_logic);
+  end component;
+
+  component wb_vic
+    generic (
+      g_num_interrupts : natural);
+    port (
+      rst_n_i      : in  std_logic;
+      wb_clk_i     : in  std_logic;
+      wb_addr_i    : in  std_logic_vector(5 downto 0);
+      wb_data_i    : in  std_logic_vector(31 downto 0);
+      wb_data_o    : out std_logic_vector(31 downto 0);
+      wb_cyc_i     : in  std_logic;
+      wb_sel_i     : in  std_logic_vector(3 downto 0);
+      wb_stb_i     : in  std_logic;
+      wb_we_i      : in  std_logic;
+      wb_ack_o     : out std_logic;
+      irqs_i       : in  std_logic_vector(g_num_interrupts-1 downto 0);
+      irq_master_o : out std_logic);
+  end component;
+
+end wishbone_pkg;