From f852caa91432aa8d4a44fb9bc721dcbf7cf956a5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch>
Date: Tue, 7 Feb 2012 14:23:31 +0100
Subject: [PATCH] modules/wrsw_swcore/async_mpm: wip

---
 modules/wrsw_swcore/async/Manifest.py         |  20 +-
 modules/wrsw_swcore/async/mpm_async_fifo.vhd  |  99 ++++
 .../wrsw_swcore/async/mpm_async_fifo_ctrl.vhd | 196 +++++++
 .../wrsw_swcore/async/mpm_async_grow_fifo.vhd | 223 ++++++++
 .../async/mpm_async_shrink_fifo.vhd           | 158 +++++
 ...ifo_mem_cell.vhd => mpm_fifo_mem_cell.vhd} |   6 +-
 .../wrsw_swcore/async/mpm_pipelined_mux.vhd   |  87 +++
 modules/wrsw_swcore/async/mpm_private_pkg.vhd |  98 ++++
 modules/wrsw_swcore/async/mpm_read_path.vhd   | 360 ++++++++++++
 .../wrsw_swcore/async/mpm_rpath_io_block.vhd  | 315 ++++++++++
 modules/wrsw_swcore/async/mpm_top.vhd         | 205 +++++++
 modules/wrsw_swcore/async/mpm_write_path.vhd  | 303 ++++++++++
 modules/wrsw_swcore/async/swc_async_fifo.vhd  | 106 ----
 .../wrsw_swcore/async/swc_async_fifo_ctrl.vhd | 164 ------
 .../wrsw_swcore/async/swc_async_grow_fifo.vhd | 138 -----
 .../async/swc_async_multiport_mem.vhd         | 139 -----
 .../async/swc_async_shrink_fifo.vhd           | 122 ----
 modules/wrsw_swcore/async/swc_private_pkg.vhd |  50 --
 modules/wrsw_swcore/async/swc_swcore_pkg.vhd  | 540 ------------------
 19 files changed, 2060 insertions(+), 1269 deletions(-)
 create mode 100644 modules/wrsw_swcore/async/mpm_async_fifo.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_async_fifo_ctrl.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_async_grow_fifo.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_async_shrink_fifo.vhd
 rename modules/wrsw_swcore/async/{swc_fifo_mem_cell.vhd => mpm_fifo_mem_cell.vhd} (89%)
 create mode 100644 modules/wrsw_swcore/async/mpm_pipelined_mux.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_private_pkg.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_read_path.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_rpath_io_block.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_top.vhd
 create mode 100644 modules/wrsw_swcore/async/mpm_write_path.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_async_fifo.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_async_fifo_ctrl.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_async_grow_fifo.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_async_multiport_mem.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_async_shrink_fifo.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_private_pkg.vhd
 delete mode 100644 modules/wrsw_swcore/async/swc_swcore_pkg.vhd

diff --git a/modules/wrsw_swcore/async/Manifest.py b/modules/wrsw_swcore/async/Manifest.py
index 3caa079c..0f4e3ce0 100644
--- a/modules/wrsw_swcore/async/Manifest.py
+++ b/modules/wrsw_swcore/async/Manifest.py
@@ -1,7 +1,13 @@
-files = ["swc_async_grow_fifo.vhd", 
-         "swc_async_fifo_ctrl.vhd", 
-         "swc_fifo_mem_cell.vhd",
-         "swc_async_shrink_fifo.vhd", 
-         "swc_private_pkg.vhd", 
-         "swc_pipelined_mux.vhd",
-         "swc_async_multiport_mem.vhd"]
+files = ["mpm_async_grow_fifo.vhd", 
+         "mpm_async_fifo_ctrl.vhd", 
+         "mpm_fifo_mem_cell.vhd",
+         "mpm_async_shrink_fifo.vhd", 
+         "mpm_private_pkg.vhd", 
+         "mpm_pipelined_mux.vhd",
+         "mpm_top.vhd",
+         "mpm_write_path.vhd",
+         "mpm_read_path.vhd",
+         "mpm_async_fifo.vhd",
+         "mpm_rpath_io_block.vhd"]
+
+
diff --git a/modules/wrsw_swcore/async/mpm_async_fifo.vhd b/modules/wrsw_swcore/async/mpm_async_fifo.vhd
new file mode 100644
index 00000000..fb2d9f33
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_async_fifo.vhd
@@ -0,0 +1,99 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.genram_pkg.all;                -- for f_log2_size
+
+entity mpm_async_fifo is
+  
+  generic (
+    g_width : integer := 11 + 1;
+    g_size  : integer := 8);
+
+  port (
+    rst_n_a_i : in std_logic;
+    clk_wr_i  : in std_logic;
+    clk_rd_i  : in std_logic;
+
+    we_i : in std_logic;
+    d_i  : in std_logic_vector(g_width-1 downto 0);
+
+    rd_i : in  std_logic;
+    q_o  : out std_logic_vector(g_width-1 downto 0);
+
+    full_o  : out std_logic;
+    empty_o : out std_logic);
+
+end mpm_async_fifo;
+
+architecture rtl of mpm_async_fifo is
+
+  component mpm_fifo_mem_cell
+    generic (
+      g_width : integer;
+      g_size  : integer);
+    port (
+      clk_i : in  std_logic;
+      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      wd_i  : in  std_logic_vector(g_width-1 downto 0);
+      we_i  : in  std_logic;
+      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_o  : out std_logic_vector(g_width-1 downto 0));
+  end component;
+
+  component mpm_async_fifo_ctrl
+    generic (
+      g_size : integer);
+    port (
+      rst_n_a_i : in  std_logic;
+      clk_wr_i  : in  std_logic;
+      clk_rd_i  : in  std_logic;
+      rd_i      : in  std_logic;
+      wr_i      : in  std_logic;
+      wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      full_o    : out std_logic;
+      empty_o   : out std_logic);
+  end component;
+
+  signal q_comb           : std_logic_vector(g_width-1 downto 0);
+  signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
+  
+begin  -- rtl
+
+
+  U_Mem_Mem : mpm_fifo_mem_cell
+    generic map (
+      g_width => g_width,
+      g_size  => g_size)
+    port map (
+      clk_i => clk_wr_i,
+      wa_i  => wr_addr,
+      wd_i  => d_i,
+      we_i  => we_i,
+      ra_i  => rd_addr,
+      rd_o  => q_comb);
+
+
+  U_CTRL : mpm_async_fifo_ctrl
+    generic map (
+      g_size => g_size)
+    port map (
+      rst_n_a_i => rst_n_a_i,
+      clk_wr_i  => clk_wr_i,
+      clk_rd_i  => clk_rd_i,
+      rd_i      => rd_i,
+      wr_i      => we_i,
+      wr_addr_o => wr_addr,
+      rd_addr_o => rd_addr,
+      full_o    => full_o,
+      empty_o   => empty_o);
+
+  p_output_reg : process(clk_rd_i)
+  begin
+    if rising_edge(clk_rd_i) then
+      q_o <= q_comb;
+    end if;
+  end process;
+  
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_async_fifo_ctrl.vhd b/modules/wrsw_swcore/async/mpm_async_fifo_ctrl.vhd
new file mode 100644
index 00000000..645cd0d4
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_async_fifo_ctrl.vhd
@@ -0,0 +1,196 @@
+-------------------------------------------------------------------------------
+-- Title        : Dual clock (asynchronous) FIFO controller
+-- Project      : White Rabbit Switch
+-------------------------------------------------------------------------------
+-- File         : mpm_async_fifo_ctrl.vhd
+-- Author       : Tomasz WÅ‚ostowski
+-- Company      : CERN BE-CO-HT
+-- Created      : 2012-01-30
+-- Last update  : 2012-01-30
+-- Platform     : FPGA-generic
+-- Standard     : VHDL'93
+-- Dependencies : genram_pkg
+-------------------------------------------------------------------------------
+-- Description: Gray-encoded dual clock FIFO controller and address generator.
+-- Based on Xilinx Application Note "Asynchronous FIFO in Virtex-II FPGAs" by
+-- P. Alfke & Generic FIFO project by Rudolf Usselmann.
+-------------------------------------------------------------------------------
+--
+-- Copyright (c) 2012 CERN
+--
+-- This source file is free software; you can redistribute it   
+-- and/or modify it under the terms of the GNU Lesser General   
+-- Public License as published by the Free Software Foundation; 
+-- either version 2.1 of the License, or (at your option) any   
+-- later version.                                               
+--
+-- This source is distributed in the hope that it will be       
+-- useful, but WITHOUT ANY WARRANTY; without even the implied   
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
+-- PURPOSE.  See the GNU Lesser General Public License for more 
+-- details.                                                     
+--
+-- You should have received a copy of the GNU Lesser General    
+-- Public License along with this source; if not, download it   
+-- from http://www.gnu.org/licenses/lgpl-2.1.html
+--
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2012-01-30  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.genram_pkg.all;
+
+entity mpm_async_fifo_ctrl is
+  
+  generic (
+    g_size : integer);
+
+  port(
+    rst_n_a_i : in std_logic;
+    clk_wr_i  : in std_logic;
+    clk_rd_i  : in std_logic;
+
+    rd_i : in std_logic;
+    wr_i : in std_logic;
+
+    wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+    rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+
+    full_o       : out std_logic;
+    going_full_o : out std_logic;
+    empty_o      : out std_logic);
+
+end mpm_async_fifo_ctrl;
+
+architecture rtl of mpm_async_fifo_ctrl is
+
+  function f_bin2gray(bin : unsigned) return unsigned is
+  begin
+    return bin(bin'left) & (bin(bin'left-1 downto 0) xor bin(bin'left downto 1));
+  end f_bin2gray;
+
+  function f_gray2bin(gray : unsigned) return unsigned is
+    variable bin : unsigned(gray'left downto 0);
+  begin
+    -- gray to binary
+    for i in 0 to gray'left loop
+      bin(i) := '0';
+      for j in i to gray'left loop
+        bin(i) := bin(i) xor gray(j);
+      end loop;  -- j 
+    end loop;  -- i
+    return bin;
+  end f_gray2bin;
+
+  subtype t_counter is unsigned(f_log2_size(g_size) downto 0);
+
+  type t_counter_block is record
+    bin, bin_next, gray, gray_next : t_counter;
+    bin_x, gray_x                  : t_counter;
+  end record;
+
+
+  signal rcb, wcb            : t_counter_block;
+  signal full_int, empty_int : std_logic;
+  signal going_full          : std_logic;
+  
+begin  -- rtl
+
+  wcb.bin_next  <= wcb.bin + 1;
+  wcb.gray_next <= f_bin2gray(wcb.bin_next);
+
+  p_write_ptr : process(clk_wr_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      wcb.bin  <= (others => '0');
+      wcb.gray <= (others => '0');
+    elsif rising_edge(clk_wr_i) then
+      if(wr_i = '1' and full_int = '0') then
+        wcb.bin  <= wcb.bin_next;
+        wcb.gray <= wcb.gray_next;
+      end if;
+    end if;
+  end process;
+
+  rcb.bin_next  <= rcb.bin + 1;
+  rcb.gray_next <= f_bin2gray(rcb.bin_next);
+
+  p_read_ptr : process(clk_rd_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      rcb.bin  <= (others => '0');
+      rcb.gray <= (others => '0');
+    elsif rising_edge(clk_rd_i) then
+      if(rd_i = '1' and empty_int = '0') then
+        rcb.bin  <= rcb.bin_next;
+        rcb.gray <= rcb.gray_next;
+      end if;
+    end if;
+  end process;
+
+  p_sync_read_ptr : process(clk_wr_i)
+  begin
+    if rising_edge(clk_wr_i) then
+      rcb.gray_x <= rcb.gray;
+    end if;
+  end process;
+
+  p_sync_write_ptr : process(clk_rd_i)
+  begin
+    if rising_edge(clk_rd_i) then
+      wcb.gray_x <= wcb.gray;
+    end if;
+  end process;
+
+  wcb.bin_x <= f_gray2bin(wcb.gray_x);
+  rcb.bin_x <= f_gray2bin(rcb.gray_x);
+
+  p_gen_empty : process(clk_rd_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      empty_int <= '1';
+    elsif rising_edge (clk_rd_i) then
+      if(rcb.gray = wcb.gray_x or (rd_i = '1' and (wcb.gray_x = rcb.gray_next))) then
+        empty_int <= '1';
+      else
+        empty_int <= '0';
+      end if;
+    end if;
+  end process;
+
+  p_gen_going_full : process(wr_i, wcb, rcb)
+  begin
+    if ((wcb.bin (wcb.bin'left-2 downto 0) = rcb.bin_x(rcb.bin_x'left-2 downto 0))
+        and (wcb.bin(wcb.bin'left) /= rcb.bin_x(wcb.bin_x'left))) then
+      going_full <= '1';
+    elsif (wr_i = '1'
+           and (wcb.bin_next(wcb.bin'left-2 downto 0) = rcb.bin_x(rcb.bin_x'left-2 downto 0))
+           and (wcb.bin_next(wcb.bin'left) /= rcb.bin_x(rcb.bin_x'left))) then
+      going_full <= '1';
+    else
+      going_full <= '0';
+    end if;
+  end process;
+
+  p_register_full : process(clk_wr_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      full_int <= '0';
+    elsif rising_edge (clk_wr_i) then
+      full_int <= going_full;
+    end if;
+  end process;
+
+  full_o       <= full_int;
+  empty_o      <= empty_int;
+  going_full_o <= going_full;
+
+  wr_addr_o <= std_logic_vector(wcb.bin(wcb.bin'left-1 downto 0));
+  rd_addr_o <= std_logic_vector(rcb.bin(rcb.bin'left-1 downto 0));
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_async_grow_fifo.vhd b/modules/wrsw_swcore/async/mpm_async_grow_fifo.vhd
new file mode 100644
index 00000000..bae9df4d
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_async_grow_fifo.vhd
@@ -0,0 +1,223 @@
+
+-------------------------------------------------------------------------------
+-- Title        : Dual clock (asynchronous) asymmetric (1:N) FIFO
+-- Project      : White Rabbit Switch
+-------------------------------------------------------------------------------
+-- File         : swc_async_grow_fifo.vhd
+-- Author       : Tomasz WÅ‚ostowski
+-- Company      : CERN BE-CO-HT
+-- Created      : 2012-01-30
+-- Last update  : 2012-01-30
+-- Platform     : FPGA-generic
+-- Standard     : VHDL'93
+-- Dependencies : swc_fifo_mem_cell, swc_async_fifo_ctrl, genram_pkg
+-------------------------------------------------------------------------------
+-- Description: Asynchronous FIFO with asymmetric (deserializing) read/write
+-- ports. g_ratio words written to  input port d_i are combined into a single
+-- (g_ratio * g_width) word on port q_o. An additional symmetric
+-- sideband channel (side_i/side_o) is provided for passing auxillary data.
+-------------------------------------------------------------------------------
+--
+-- Copyright (c) 2012 CERN
+--
+-- This source file is free software; you can redistribute it   
+-- and/or modify it under the terms of the GNU Lesser General   
+-- Public License as published by the Free Software Foundation; 
+-- either version 2.1 of the License, or (at your option) any   
+-- later version.                                               
+--
+-- This source is distributed in the hope that it will be       
+-- useful, but WITHOUT ANY WARRANTY; without even the implied   
+-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
+-- PURPOSE.  See the GNU Lesser General Public License for more 
+-- details.                                                     
+--
+-- You should have received a copy of the GNU Lesser General    
+-- Public License along with this source; if not, download it   
+-- from http://www.gnu.org/licenses/lgpl-2.1.html
+--
+-------------------------------------------------------------------------------
+-- Revisions  :
+-- Date        Version  Author          Description
+-- 2012-01-30  1.0      twlostow        Created
+-------------------------------------------------------------------------------
+
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.genram_pkg.all;                -- for f_log2_size
+
+entity mpm_async_grow_fifo is
+  
+  generic (
+    -- base data width (narrow port)
+    g_width          : integer := 16;
+    -- wide/narrow data width ratio
+    g_ratio          : integer := 6;
+    -- number of wide words in FIFO
+    g_size           : integer := 8;
+    -- sideband channel (side_i/side_o) width
+    g_sideband_width : integer := 16);
+
+  port (
+    rst_n_a_i : in std_logic;
+    clk_wr_i  : in std_logic;
+    clk_rd_i  : in std_logic;
+
+    -- 1: write word available on (d_i) to the FIFO
+    we_i    : in std_logic;
+    -- 1: perform an aligned write (i.e. at the beginning of the wide word)
+    align_i : in std_logic;
+    -- data input
+    d_i     : in std_logic_vector(g_width-1 downto 0);
+
+    -- 1: performs a read of a single wide word, outputted on q_o
+    rd_i : in  std_logic;
+    -- registered data output
+    q_o  : out std_logic_vector(g_width * g_ratio-1 downto 0);
+
+    -- "Sideband" channel (for passing auxillary data, such as page indices)
+    side_i : in  std_logic_vector(g_sideband_width-1 downto 0);
+    side_o : out std_logic_vector(g_sideband_width-1 downto 0);
+
+    -- Full flag (clk_wr_i domain)
+    full_o  : out std_logic;
+    -- Empty flag (clk_rd_i domain)
+    empty_o : out std_logic);
+
+end mpm_async_grow_fifo;
+
+architecture rtl of mpm_async_grow_fifo is
+
+  component mpm_fifo_mem_cell
+    generic (
+      g_width : integer;
+      g_size  : integer);
+    port (
+      clk_i : in  std_logic;
+      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      wd_i  : in  std_logic_vector(g_width-1 downto 0);
+      we_i  : in  std_logic;
+      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_o  : out std_logic_vector(g_width-1 downto 0));
+  end component;
+
+  component mpm_async_fifo_ctrl
+    generic (
+      g_size : integer);
+    port (
+      rst_n_a_i    : in  std_logic;
+      clk_wr_i     : in  std_logic;
+      clk_rd_i     : in  std_logic;
+      rd_i         : in  std_logic;
+      wr_i         : in  std_logic;
+      wr_addr_o    : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_addr_o    : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      full_o       : out std_logic;
+      going_full_o : out std_logic;
+      empty_o      : out std_logic);
+  end component;
+
+  signal wr_sreg          : std_logic_vector(g_ratio-1 downto 0);
+  signal wr_cell          : std_logic_vector(g_ratio-1 downto 0);
+  signal real_we          : std_logic;
+  signal q_int            : std_logic_vector(g_width*g_ratio-1 downto 0);
+  signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
+  signal full_int         : std_logic;
+  signal side_comb        : std_logic_vector(g_sideband_width-1 downto 0);
+  
+begin  -- rtl
+
+  -- Genrate g_ratio memory cells, which are written sequentially (each memory
+  -- block corresponds to a bit in wr_cell shift register) and read all at
+  -- once, forming a deserializer.
+  gen_mem_cells : for i in 0 to g_ratio-1 generate
+
+    wr_cell(i) <= wr_sreg(i) and we_i;
+
+    U_Mem : mpm_fifo_mem_cell
+      generic map (
+        g_width => g_width,
+        g_size  => g_size)
+      port map (
+        clk_i => clk_wr_i,
+        wa_i  => wr_addr,
+        wd_i  => d_i,
+        we_i  => wr_cell(i),
+        ra_i  => rd_addr,
+        rd_o  => q_int(g_width*(i+1) -1 downto g_width*i));
+  end generate gen_mem_cells;
+
+  -- Extra memory cell for sideband channel
+  U_Sideband_Mem : mpm_fifo_mem_cell
+    generic map (
+      g_width => g_sideband_width,
+      g_size  => g_size)
+    port map (
+      clk_i => clk_wr_i,
+      wa_i  => wr_addr,
+      wd_i  => side_i,
+      we_i  => real_we,
+      ra_i  => rd_addr,
+      rd_o  => side_comb);
+
+  
+  U_CTRL : mpm_async_fifo_ctrl
+    generic map (
+      g_size => g_size)
+    port map (
+      rst_n_a_i => rst_n_a_i,
+      clk_wr_i  => clk_wr_i,
+      clk_rd_i  => clk_rd_i,
+      rd_i      => rd_i,
+      wr_i      => real_we,
+      wr_addr_o => wr_addr,
+      rd_addr_o => rd_addr,
+      going_full_o => full_int,
+--      full_o    => full_int,
+      empty_o   => empty_o);
+
+
+  -- Per-cell write shift register control
+  p_write_grow_sreg : process(clk_wr_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      wr_sreg(0)                     <= '1';
+      wr_sreg(wr_sreg'left downto 1) <= (others => '0');
+    elsif rising_edge(clk_wr_i) then
+      if(we_i = '1') then
+        if(align_i = '1') then
+          wr_sreg(0)                     <= '1';
+          wr_sreg(wr_sreg'left downto 1) <= (others => '0');
+        else
+          wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
+        end if;
+      end if;
+    end if;
+  end process;
+
+  real_we <= wr_cell(wr_cell'left) or (we_i and align_i);
+
+  -- Output register on q_o. Memory cells are combinatorial, the register is
+  -- here to improve the timing.
+  p_output_reg : process(clk_rd_i, rst_n_a_i)
+  begin
+    if (rst_n_a_i = '0') then
+      q_o    <= (others => '0');
+      side_o <= (others => '0');
+    elsif rising_edge(clk_rd_i) then
+      if(rd_i = '1') then
+        q_o    <= q_int;
+        side_o <= side_comb;
+      end if;
+    end if;
+  end process;
+
+  -- full flag is only active when there's no space left in the highest memory
+  -- cell
+  full_o <= full_int and wr_sreg(wr_sreg'left);
+  
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_async_shrink_fifo.vhd b/modules/wrsw_swcore/async/mpm_async_shrink_fifo.vhd
new file mode 100644
index 00000000..0af58025
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_async_shrink_fifo.vhd
@@ -0,0 +1,158 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.genram_pkg.all;                -- for f_log2_size
+
+entity mpm_async_shrink_fifo is
+  
+  generic (
+    g_width          : integer;         -- narrow port width
+    g_ratio          : integer;
+    g_size           : integer;
+    g_sideband_width : integer);
+
+  port (
+    rst_n_a_i : in std_logic;
+    clk_wr_i  : in std_logic;
+    clk_rd_i  : in std_logic;
+
+    we_i : in std_logic;
+    d_i  : in std_logic_vector(g_width*g_ratio-1 downto 0);
+
+    rd_i : in  std_logic;
+    q_o  : out std_logic_vector(g_width-1 downto 0);
+
+    side_i : in  std_logic_vector(g_sideband_width-1 downto 0);
+    side_o : out std_logic_vector(g_sideband_width-1 downto 0);
+
+    flush_i : in  std_logic := '0';
+    full_o  : out std_logic;
+    empty_o : out std_logic);
+
+end mpm_async_shrink_fifo;
+
+architecture rtl of mpm_async_shrink_fifo is
+
+  component mpm_fifo_mem_cell
+    generic (
+      g_width : integer;
+      g_size  : integer);
+    port (
+      clk_i : in  std_logic;
+      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      wd_i  : in  std_logic_vector(g_width-1 downto 0);
+      we_i  : in  std_logic;
+      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_o  : out std_logic_vector(g_width-1 downto 0));
+  end component;
+
+  component mpm_async_fifo_ctrl
+    generic (
+      g_size : integer);
+    port (
+      rst_n_a_i : in  std_logic;
+      clk_wr_i  : in  std_logic;
+      clk_rd_i  : in  std_logic;
+      rd_i      : in  std_logic;
+      wr_i      : in  std_logic;
+      wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
+      full_o    : out std_logic;
+      empty_o   : out std_logic);
+  end component;
+
+  signal rd_count                 : unsigned(3 downto 0);
+  signal real_rd                  : std_logic;
+  signal q_muxed                  : std_logic_vector(g_width-1 downto 0);
+  signal q_comb, q_reg            : std_logic_vector(g_width*g_ratio-1 downto 0);
+  signal wr_addr, rd_addr         : std_logic_vector(f_log2_size(g_size)-1 downto 0);
+  signal empty_wide, empty_narrow : std_logic;
+  signal line_flushed             : std_logic;
+  
+begin  -- rtl
+
+
+  gen_sb_mem : if(g_sideband_width > 0) generate
+    U_Sideband_Mem : mpm_fifo_mem_cell
+      generic map (
+        g_width => g_sideband_width,
+        g_size  => g_size)
+      port map (
+        clk_i => clk_wr_i,
+        wa_i  => wr_addr,
+        wd_i  => side_i,
+        we_i  => we_i,
+        ra_i  => rd_addr,
+        rd_o  => side_o);
+  end generate gen_sb_mem;
+
+  gen_mem_cells : for i in 0 to g_ratio-1 generate
+
+    U_Mem : mpm_fifo_mem_cell
+      generic map (
+        g_width => g_width,
+        g_size  => g_size)
+      port map (
+        clk_i => clk_wr_i,
+        wa_i  => wr_addr,
+        wd_i  => d_i(g_width*(i+1) -1 downto g_width*i),
+        we_i  => we_i,
+        ra_i  => rd_addr,
+        rd_o  => q_comb(g_width*(i+1) -1 downto g_width*i));
+  end generate gen_mem_cells;
+
+  U_CTRL : mpm_async_fifo_ctrl
+    generic map (
+      g_size => g_size)
+    port map (
+      rst_n_a_i => rst_n_a_i,
+      clk_wr_i  => clk_wr_i,
+      clk_rd_i  => clk_rd_i,
+      rd_i      => real_rd,
+      wr_i      => we_i,
+      wr_addr_o => wr_addr,
+      rd_addr_o => rd_addr,
+      full_o    => full_o,
+      empty_o   => empty_wide);
+
+  p_read_mux : process(clk_rd_i, rst_n_a_i)
+  begin
+    if rst_n_a_i = '0' then
+      rd_count     <= (others => '0');
+      q_reg        <= (others => '0');
+      line_flushed <= real_rd;
+      empty_narrow <= '1';
+    elsif rising_edge(clk_rd_i) then
+
+      if(empty_wide = '0') then
+        empty_narrow <= '0';
+      elsif(((rd_count = g_ratio-1 and rd_i = '1') or flush_i = '1') and empty_wide = '1') then
+        empty_narrow <= '1';
+      end if;
+
+      line_flushed <= real_rd;
+
+      if(real_rd = '1')then
+        q_reg <= q_comb;
+      end if;
+
+      if(rd_i = '1' or flush_i = '1') then
+        if(rd_count = g_ratio-1 or flush_i = '1') then
+          rd_count <= (others => '0');
+        else
+          rd_count <= rd_count + 1;
+        end if;
+
+        q_muxed <= q_reg(((to_integer(rd_count)+1)*g_width)-1 downto to_integer(rd_count)*g_width);
+      end if;
+      
+    end if;
+  end process;
+
+
+  real_rd <= '1'                       when (rd_count = 0) and rd_i = '1' else '0';
+  q_o     <= q_reg(g_width-1 downto 0) when line_flushed = '1'            else q_muxed;
+  empty_o <= empty_narrow;
+  
+end rtl;
diff --git a/modules/wrsw_swcore/async/swc_fifo_mem_cell.vhd b/modules/wrsw_swcore/async/mpm_fifo_mem_cell.vhd
similarity index 89%
rename from modules/wrsw_swcore/async/swc_fifo_mem_cell.vhd
rename to modules/wrsw_swcore/async/mpm_fifo_mem_cell.vhd
index b4f99334..e3d5b697 100644
--- a/modules/wrsw_swcore/async/swc_fifo_mem_cell.vhd
+++ b/modules/wrsw_swcore/async/mpm_fifo_mem_cell.vhd
@@ -4,7 +4,7 @@ use IEEE.numeric_std.all;
 
 use work.genram_pkg.all;
 
-entity swc_fifo_mem_cell is
+entity mpm_fifo_mem_cell is
   
   generic (
     g_width : integer;
@@ -19,9 +19,9 @@ entity swc_fifo_mem_cell is
     ra_i : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
     rd_o : out std_logic_vector(g_width-1 downto 0));
 
-end swc_fifo_mem_cell;
+end mpm_fifo_mem_cell;
 
-architecture rtl of swc_fifo_mem_cell is
+architecture rtl of mpm_fifo_mem_cell is
   type t_mem_array is array(0 to g_size-1) of std_logic_vector(g_width-1 downto 0);
 
   signal mem : t_mem_array;
diff --git a/modules/wrsw_swcore/async/mpm_pipelined_mux.vhd b/modules/wrsw_swcore/async/mpm_pipelined_mux.vhd
new file mode 100644
index 00000000..de51b48e
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_pipelined_mux.vhd
@@ -0,0 +1,87 @@
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.genram_pkg.all;
+use work.mpm_private_pkg.all;
+
+entity mpm_pipelined_mux is
+  
+  generic (
+    g_width  : integer := 16;
+    g_inputs : integer := 18);
+
+  port (
+    clk_i   : in std_logic;
+    rst_n_i : in std_logic;
+
+    d_i : in  std_logic_vector(g_inputs * g_width-1 downto 0);
+    q_o : out std_logic_vector(g_width-1 downto 0);
+
+    -- select input (one hot encoded)
+    sel_i : in std_logic_vector(g_inputs-1 downto 0)
+    );
+
+end mpm_pipelined_mux;
+
+architecture rtl of mpm_pipelined_mux is
+
+  type t_generic_slv_array is array (integer range <>, integer range <>) of std_logic;
+
+  constant c_first_stage_muxes : integer := (g_inputs+2)/3;
+
+  signal first_stage : t_generic_slv_array(0 to c_first_stage_muxes-1, g_width-1 downto 0);
+
+begin  -- rtl
+
+  -- 1st stage, optimized for 5-input LUTs: mux each 3-input groups or 0
+  -- if (sel == 11)
+  gen_1st_stage : for i in 0 to c_first_stage_muxes-1 generate
+    gen_each_bit : for j in 0 to g_width-1 generate
+      p_mux_or : process(clk_i)
+      begin
+        if rising_edge(clk_i) then
+          if rst_n_i = '0' then
+            first_stage(i, j) <= '0';
+          else
+            if(sel_i(3*i + 2 downto 3*i) = "001") then
+              first_stage(i, j) <= d_i(i * 3 * g_width + j);
+            elsif (sel_i(3*i + 2 downto 3*i) = "010") then
+              first_stage(i, j) <= d_i(i * 3 * g_width + g_width + j);
+            elsif (sel_i(3*i + 2 downto 3*i) = "100") then
+              first_stage(i, j) <= d_i(i * 3 * g_width + 2*g_width + j);
+            else
+              first_stage(i, j) <= '0';
+            end if;
+          end if;
+        end if;
+      end process;
+    end generate gen_each_bit;
+  end generate gen_1st_stage;
+
+  -- 2nd stage: simply OR together the results of the 1st stage
+  p_2nd_stage : process(clk_i)
+    variable row : std_logic_vector(c_first_stage_muxes-1 downto 0);
+  begin
+    if rising_edge(clk_i) then
+      for j in 0 to g_width-1 loop
+        if rst_n_i = '0' then
+          q_o(j) <= '0';
+        else
+          for i in 0 to c_first_stage_muxes-1 loop
+            row(i) := first_stage(i, j);
+          end loop;  -- i
+
+          if(unsigned(row) = 0) then
+            q_o(j) <= '0';
+          else
+            q_o(j) <= '1';
+          end if;
+        end if;
+      end loop;  -- j in 0 to g_width-1 loop
+    end if;
+  end process;
+  
+  
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_private_pkg.vhd b/modules/wrsw_swcore/async/mpm_private_pkg.vhd
new file mode 100644
index 00000000..4c5c2379
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_private_pkg.vhd
@@ -0,0 +1,98 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+package mpm_private_pkg is
+
+  -----------------------------------------------------------------------------
+  -- Components
+  -----------------------------------------------------------------------------
+
+  component mpm_pipelined_mux
+    generic (
+      g_width  : integer;
+      g_inputs : integer);
+    port (
+      clk_i   : in  std_logic;
+      rst_n_i : in  std_logic;
+      d_i     : in  std_logic_vector(g_inputs * g_width-1 downto 0);
+      q_o     : out std_logic_vector(g_width-1 downto 0);
+      sel_i   : in  std_logic_vector(g_inputs-1 downto 0));
+  end component;
+
+  component mpm_async_grow_fifo
+    generic (
+      g_width          : integer;
+      g_ratio          : integer;
+      g_size           : integer;
+      g_sideband_width : integer);
+    port (
+      rst_n_a_i    : in  std_logic;
+      clk_wr_i     : in  std_logic;
+      clk_rd_i     : in  std_logic;
+      we_i         : in  std_logic;
+      align_i      : in  std_logic;
+      d_i          : in  std_logic_vector(g_width-1 downto 0);
+      rd_i         : in  std_logic;
+      q_o          : out std_logic_vector(g_width * g_ratio-1 downto 0);
+      side_i       : in  std_logic_vector(g_sideband_width-1 downto 0);
+      side_o       : out std_logic_vector(g_sideband_width-1 downto 0);
+      full_o       : out std_logic;
+      empty_o      : out std_logic);
+  end component;
+
+  component mpm_async_shrink_fifo
+    generic (
+      g_width          : integer;
+      g_ratio          : integer;
+      g_size           : integer;
+      g_sideband_width : integer);
+    port (
+      rst_n_a_i : in  std_logic;
+      clk_wr_i  : in  std_logic;
+      clk_rd_i  : in  std_logic;
+      we_i      : in  std_logic;
+      d_i       : in  std_logic_vector(g_width*g_ratio-1 downto 0);
+      rd_i      : in  std_logic;
+      q_o       : out std_logic_vector(g_width-1 downto 0);
+      side_i    : in  std_logic_vector(g_sideband_width-1 downto 0);
+      side_o    : out std_logic_vector(g_sideband_width-1 downto 0);
+      flush_i   : in  std_logic := '0';
+      full_o    : out std_logic;
+      empty_o   : out std_logic);
+  end component;
+
+  component mpm_async_fifo
+    generic (
+      g_width : integer;
+      g_size  : integer);
+    port (
+      rst_n_a_i : in  std_logic;
+      clk_wr_i  : in  std_logic;
+      clk_rd_i  : in  std_logic;
+      we_i      : in  std_logic;
+      d_i       : in  std_logic_vector(g_width-1 downto 0);
+      rd_i      : in  std_logic;
+      q_o       : out std_logic_vector(g_width-1 downto 0);
+      full_o    : out std_logic;
+      empty_o   : out std_logic);
+  end component;
+  
+  function f_slice (
+    x     : std_logic_vector;
+    index : integer;
+    len   : integer) return std_logic_vector;
+
+end mpm_private_pkg;
+
+package body mpm_private_pkg is
+
+  function f_slice (
+    x     : std_logic_vector;
+    index : integer;
+    len   : integer) return std_logic_vector is
+  begin
+    return x((index + 1) * len - 1 downto index * len);
+  end f_slice;
+
+
+end mpm_private_pkg;
diff --git a/modules/wrsw_swcore/async/mpm_read_path.vhd b/modules/wrsw_swcore/async/mpm_read_path.vhd
new file mode 100644
index 00000000..1f12d343
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_read_path.vhd
@@ -0,0 +1,360 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.mpm_private_pkg.all;
+
+use work.gencores_pkg.all;              -- for f_rr_arbitrate
+use work.genram_pkg.all;                -- for f_log2_size
+
+entity mpm_read_path is
+  
+  generic (
+    g_data_width           : integer;
+    g_ratio                : integer;
+    g_page_size            : integer;
+    g_num_pages            : integer;
+    g_num_ports            : integer;
+    g_fifo_size            : integer;
+    g_page_addr_width      : integer;
+    g_partial_select_width : integer;
+    g_max_packet_size      : integer
+    );
+
+  port(
+    -- I/O ports clock (slow)
+    clk_io_i     : in std_logic;
+    -- Memory/Core clock (fast)
+    clk_core_i   : in std_logic;
+    rst_n_io_i   : in std_logic;
+    rst_n_core_i : in std_logic;
+
+-- read-write ports I/F (streaming)
+    rport_d_o        : out std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+    rport_dvalid_o   : out std_logic_vector (g_num_ports-1 downto 0);
+    rport_dlast_o    : out std_logic_vector (g_num_ports-1 downto 0);
+    rport_dsel_o     : out std_logic_vector(g_partial_select_width -1 downto 0);
+    rport_dreq_i     : in  std_logic_vector (g_num_ports-1 downto 0);
+    rport_abort_i    : in  std_logic_vector (g_num_ports-1 downto 0);
+    rport_pg_addr_i  : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+    rport_pg_req_o   : out std_logic_vector(g_num_ports-1 downto 0);
+    rport_pg_valid_i : in  std_logic_vector (g_num_ports-1 downto 0);
+
+    -- Linked List I/F (I/O clock domain)
+    ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
+    ll_data_i : in  std_logic_vector(g_page_addr_width+1 downto 0);
+
+    -- F. B. Memory I/F
+    fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
+    fbm_data_i : in  std_logic_vector(g_ratio * g_data_width -1 downto 0)
+    );
+
+end mpm_read_path;
+
+architecture rtl of mpm_read_path is
+
+  component mpm_rpath_io_block
+    generic (
+      g_data_width           : integer;
+      g_page_addr_width      : integer;
+      g_page_size            : integer;
+      g_partial_select_width : integer;
+      g_ratio                : integer;
+      g_max_packet_size      : integer);
+    port (
+      clk_io_i         : in  std_logic;
+      rst_n_io_i       : in  std_logic;
+      rport_d_o        : out std_logic_vector(g_page_addr_width-1 downto 0);
+      rport_dvalid_o   : out std_logic;
+      rport_dlast_o    : out std_logic;
+      rport_dsel_o     : out std_logic_vector(g_partial_select_width-1 downto 0);
+      rport_dreq_i     : in  std_logic;
+      rport_abort_i    : in  std_logic;
+      rport_pg_req_o   : out std_logic;
+      rport_pg_valid_i : in  std_logic;
+      rport_pg_addr_i  : in  std_logic_vector(g_page_addr_width-1 downto 0);
+      ll_req_o         : out std_logic;
+      ll_grant_i       : in  std_logic;
+      ll_addr_o        : out std_logic_vector(g_page_addr_width-1 downto 0);
+      ll_data_i        : in  std_logic_vector(g_page_addr_width + 1 downto 0);
+      pf_full_i        : in  std_logic;
+      pf_we_o          : out std_logic;
+      pf_pg_addr_o     : out std_logic_vector(g_page_addr_width-1 downto 0);
+      pf_pg_lines_o    : out std_logic_vector(f_log2_size(g_page_size / g_ratio)-1 downto 0);
+      df_empty_i       : in  std_logic;
+      df_flush_o       : out std_logic;
+      df_rd_o          : out std_logic;
+      df_d_i           : in  std_logic_vector(g_data_width-1 downto 0));
+  end component;
+
+
+  constant c_page_count_width    : integer := f_log2_size(g_max_packet_size / g_page_size + 1);
+  constant c_line_size_width     : integer := f_log2_size(g_page_size / g_ratio);
+  constant c_fbm_data_width      : integer := g_ratio * g_data_width;
+  constant c_fbm_entries         : integer := g_num_pages * g_page_size / g_ratio;
+  constant c_fbm_addr_width      : integer := f_log2_size(c_fbm_entries);
+  constant c_fifo_sideband_width : integer := c_fbm_addr_width;
+
+  type t_mpm_read_port is record
+    d        : std_logic_vector(g_data_width-1 downto 0);
+    d_valid  : std_logic;
+    d_last   : std_logic;
+    d_sel    : std_logic_vector(g_partial_select_width-1 downto 0);
+    d_req    : std_logic;
+    pg_addr  : std_logic_vector(g_page_addr_width-1 downto 0);
+    pg_valid : std_logic;
+    pg_req   : std_logic;
+    abort    : std_logic;
+
+  end record;
+
+  type t_mpm_read_port_array is array (integer range <>) of t_mpm_read_port;
+
+  type t_rport_io_state is record
+    -- Data FIFO output port
+    df_rd    : std_logic;
+    df_empty : std_logic;
+    df_flush : std_logic;
+    df_q     : std_logic_vector(c_fbm_data_width -1 downto 0);
+
+    -- Page FIFO input port
+    pf_full     : std_logic;
+    pf_we       : std_logic;
+    pf_pg_addr  : std_logic_vector(g_page_addr_width-1 downto 0);
+    pf_pg_lines : std_logic_vector(c_line_size_width-1 downto 0);
+    pf_d        : std_logic_vector(c_line_size_width + g_page_addr_width -1 downto 0);
+
+    -- Linked list address & arbitration
+    ll_req     : std_logic;
+    ll_grant_d : std_logic_vector(2 downto 0);
+    ll_addr    : std_logic_vector(g_page_addr_width-1 downto 0);
+  end record;
+
+  -- clk_core_i domain state
+  type t_rport_core_state is record
+    df_full : std_logic;
+    df_we   : std_logic;
+
+
+    
+    pf_q         : std_logic_vector(g_page_addr_width + c_line_size_width-1 downto 0);
+    pf_rd        : std_logic;
+    pf_empty     : std_logic;
+    pg_remaining : std_logic_vector(c_line_size_width - 1 downto 0);
+    fbm_addr     : std_logic_vector(c_fbm_addr_width - 1 downto 0);
+    mem_req      : std_logic;
+    mem_grant_d  : std_logic_vector(3 downto 0);
+  end record;
+
+-------------------------------------------------------------------------------
+-- Functions
+-------------------------------------------------------------------------------
+
+  type t_rport_core_state_array is array(integer range <>) of t_rport_core_state;
+  type t_rport_io_state_array is array(integer range <>) of t_rport_io_state;
+
+  signal mem_req, mem_grant : std_logic_vector(g_num_ports-1 downto 0);
+  signal ll_req, ll_grant   : std_logic_vector(g_num_ports-1 downto 0);
+
+  signal io   : t_rport_io_state_array(g_num_ports-1 downto 0);
+  signal core : t_rport_core_state_array(g_num_ports-1 downto 0);
+
+  signal rport : t_mpm_read_port_array(g_num_ports-1 downto 0);
+
+  signal rd_mux_a_in : std_logic_vector(g_num_ports * c_fbm_data_width -1 downto 0);
+  signal rd_mux_sel  : std_logic_vector(g_num_ports-1 downto 0);
+
+  signal fbm_data_reg : std_logic_vector(c_fbm_data_width-1 downto 0);
+
+begin  -- rtl
+
+-- I/O structure serialization/deserialization
+  gen_serialize_ios : for i in 0 to g_num_ports-1 generate
+
+    rport_d_o (g_data_width * (i+1) - 1 downto g_data_width * i) <=
+      rport(i).d;
+    rport_dvalid_o(i) <=
+      rport(i).d_valid;
+    rport_dlast_o(i) <=
+      rport(i).d_last;
+    rport_dsel_o(g_partial_select_width * (i+1) - 1 downto g_partial_select_width * i) <=
+      rport(i).d_sel;
+
+    rport(i).d_req    <= rport_dreq_i(i);
+    rport(i).abort    <= rport_abort_i(i);
+    rport(i).pg_addr  <= f_slice(rport_pg_addr_i, i, g_page_addr_width);
+    rport(i).pg_valid <= rport_pg_valid_i(i);
+    rport_pg_req_o(i) <= rport(i).pg_req;
+
+  end generate gen_serialize_ios;
+
+
+
+  -- The actual round-robin arbiter for muxing memory accesses.
+  p_mem_arbiter : process(clk_core_i)
+  begin
+    if rising_edge(clk_core_i) then
+      if rst_n_core_i = '0' then
+        mem_grant <= (others => '0');
+      else
+        f_rr_arbitrate(mem_req, mem_grant, mem_grant);
+      end if;
+    end if;
+  end process;
+
+  gen_mem_access_arbiter : for i in 0 to g_num_ports-1 generate
+
+    mem_req(i)             <= core(i).mem_req and not core(i).mem_grant_d(0);
+    core(i).mem_grant_d(0) <= mem_grant(i);
+
+    -- Delay the grant signal to generate enables for each pipeline stage
+    process(clk_core_i)
+    begin
+      if rising_edge(clk_core_i) then
+        if rst_n_core_i = '0' then
+          core(i).mem_grant_d(3 downto 1) <= (others => '0');
+        else
+          core(i).mem_grant_d(3) <= core(i).mem_grant_d(2);
+          core(i).mem_grant_d(2) <= core(i).mem_grant_d(1);
+          core(i).mem_grant_d(1) <= core(i).mem_grant_d(0);
+        end if;
+      end if;
+    end process;
+  end generate gen_mem_access_arbiter;
+
+  gen_mux_inputs : for i in 0 to g_num_ports-1 generate
+    rd_mux_a_in(c_fbm_addr_width * (i + 1) - 1 downto c_fbm_addr_width * i) <= core(i).fbm_addr;
+    rd_mux_sel(i)                                                           <= core(i).mem_grant_d(0);
+  end generate gen_mux_inputs;
+
+  U_Rd_Address_Mux : mpm_pipelined_mux
+    generic map (
+      g_width  => c_fbm_addr_width,
+      g_inputs => g_num_ports)
+    port map (
+      clk_i   => clk_core_i,
+      rst_n_i => rst_n_core_i,
+      d_i     => rd_mux_a_in,
+      q_o     => fbm_addr_o,
+      sel_i   => rd_mux_sel);
+
+  p_fbm_data_reg : process(clk_core_i)
+  begin
+    if rising_edge(clk_core_i) then
+      fbm_data_reg <= fbm_data_i;
+    end if;
+  end process;
+
+
+  gen_fifos : for i in 0 to g_num_ports-1 generate
+    U_Page_Fifo : mpm_async_fifo
+      generic map (
+        g_width => g_page_addr_width + 1,
+        g_size  => 8)
+      port map (
+        rst_n_a_i => rst_n_core_i,
+        clk_wr_i  => clk_io_i,
+        clk_rd_i  => clk_core_i,
+        we_i      => io(i).pf_we,
+        d_i       => io(i).pf_d,
+        rd_i      => core(i).pf_rd,
+        q_o       => core(i).pf_q,
+        full_o    => io(i).pf_full,
+        empty_o   => core(i).pf_empty);
+
+    U_Output_Fifo : mpm_async_shrink_fifo
+      generic map (
+        g_width          => g_data_width,
+        g_ratio          => g_ratio,
+        g_size           => g_fifo_size,
+        g_sideband_width => 0)
+      port map (
+        rst_n_a_i => rst_n_core_i,
+        clk_wr_i  => clk_core_i,
+        clk_rd_i  => clk_io_i,
+        we_i      => core(i).df_we,
+        d_i       => fbm_data_reg,
+        rd_i      => io(i).df_rd,
+        q_o       => io(i).df_q,
+        side_i => "",
+        flush_i   => io(i).df_flush,
+        full_o    => core(i).df_full,
+        empty_o   => io(i).df_empty);
+
+  end generate gen_fifos;
+
+
+-- The arbiter for accessing the linked list
+  p_ll_arbiter : process(clk_io_i)
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' then
+        ll_grant <= (others => '0');
+      else
+        f_rr_arbitrate(ll_req, ll_grant, ll_grant);
+      end if;
+    end if;
+  end process;
+
+  gen_ll_access_arbiter : for i in 0 to g_num_ports-1 generate
+    ll_req(i)           <= io(i).ll_req and not io(i).ll_grant_d(0);
+    io(i).ll_grant_d(0) <= ll_grant(i);
+  end generate gen_ll_access_arbiter;
+
+  p_ll_mux_addr : process(clk_io_i)
+    variable muxed : std_logic_vector(g_page_addr_width-1 downto 0);
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' then
+        ll_addr_o <= (others => '0');
+      else
+        for i in 0 to g_num_ports-1 loop
+          if(io(i).ll_grant_d(0) = '1') then
+            muxed := io(i).ll_addr;
+          end if;
+        end loop;  -- i
+        ll_addr_o <= muxed;
+      end if;
+    end if;
+  end process;
+
+
+  gen_output_controllers : for i in 0 to g_num_ports-1 generate
+    U_Output_Ctrl : mpm_rpath_io_block
+      generic map (
+        g_data_width           => g_data_width,
+        g_page_addr_width      => g_page_addr_width,
+        g_page_size            => g_page_size,
+        g_partial_select_width => g_partial_select_width,
+        g_ratio                => g_ratio,
+        g_max_packet_size      => g_max_packet_size)
+      port map (
+        clk_io_i         => clk_io_i,
+        rst_n_io_i       => rst_n_io_i,
+        rport_d_o        => rport(i).d,
+        rport_dvalid_o   => rport(i).d_valid,
+        rport_dlast_o    => rport(i).d_last,
+        rport_dsel_o     => rport(i).d_sel,
+        rport_dreq_i     => rport(i).d_req,
+        rport_abort_i    => rport(i).abort,
+        rport_pg_req_o   => rport(i).pg_req,
+        rport_pg_valid_i => rport(i).pg_valid,
+        rport_pg_addr_i  => rport(i).pg_addr,
+        ll_req_o         => io(i).ll_req,
+        ll_grant_i       => io(i).ll_grant_d(2),
+        ll_addr_o        => io(i).ll_addr,
+        ll_data_i        => ll_data_i,
+        pf_full_i        => io(i).pf_full,
+        pf_we_o          => io(i).pf_we,
+        pf_pg_addr_o     => io(i).pf_pg_addr,
+        pf_pg_lines_o    => io(i).pf_pg_lines,
+        df_empty_i       => io(i).df_empty,
+        df_flush_o       => io(i).df_flush,
+        df_rd_o          => io(i).df_rd,
+        df_d_i           => io(i).df_q);
+
+    io(i).pf_d <= io(i).pf_pg_lines & io(i).pf_pg_addr;
+  end generate gen_output_controllers;
+  
+
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_rpath_io_block.vhd b/modules/wrsw_swcore/async/mpm_rpath_io_block.vhd
new file mode 100644
index 00000000..37e723a9
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_rpath_io_block.vhd
@@ -0,0 +1,315 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.gencores_pkg.all;
+use work.genram_pkg.all;
+
+entity mpm_rpath_io_block is
+  
+  generic (
+    g_data_width           : integer;
+    g_page_addr_width      : integer;
+    g_page_size            : integer;
+    g_partial_select_width : integer;
+    g_ratio                : integer;
+    g_max_packet_size      : integer);
+
+  port (
+    clk_io_i : in std_logic;
+    rst_n_io_i  : in std_logic;
+
+-- Read Port Interface
+    rport_d_o        : out std_logic_vector(g_page_addr_width-1 downto 0);
+    rport_dvalid_o   : out std_logic;
+    rport_dlast_o    : out std_logic;
+    rport_dsel_o     : out std_logic_vector(g_partial_select_width-1 downto 0);
+    rport_dreq_i     : in  std_logic;
+    rport_abort_i    : in  std_logic;
+    rport_pg_req_o   : out std_logic;
+    rport_pg_valid_i : in  std_logic;
+    rport_pg_addr_i  : in  std_logic_vector(g_page_addr_width-1 downto 0);
+
+-- Linked List Interface
+    ll_req_o   : out std_logic;
+    ll_grant_i : in  std_logic;
+    ll_addr_o  : out std_logic_vector(g_page_addr_width-1 downto 0);
+    ll_data_i  : in  std_logic_vector(g_page_addr_width + 1 downto 0);
+
+-- Page FIFO interface
+    pf_full_i     : in  std_logic;
+    pf_we_o       : out std_logic;
+    pf_pg_addr_o  : out std_logic_vector(g_page_addr_width-1 downto 0);
+    pf_pg_lines_o : out std_logic_vector(f_log2_size(g_page_size / g_ratio)-1 downto 0);
+
+-- Data FIFO interface
+    df_empty_i : in  std_logic;
+    df_flush_o : out std_logic;
+    df_rd_o    : out std_logic;
+    df_d_i     : in  std_logic_vector(g_data_width-1 downto 0)
+    );
+
+end mpm_rpath_io_block;
+
+architecture behavioral of mpm_rpath_io_block is
+
+  constant c_lines_per_page   : integer := g_page_size/g_ratio;
+  constant c_page_lines_width : integer := f_log2_size(c_lines_per_page + 1);
+  constant c_page_size_width  : integer := f_log2_size(g_page_size + 1);
+  constant c_word_count_width : integer := f_log2_size(g_max_packet_size + 1);
+
+  function f_fast_div_pagesize
+    (x : unsigned;
+     y : integer) return unsigned is
+
+    type t_div_factor is record
+      inc   : boolean;
+      mul   : integer;
+      shift : integer;
+    end record;
+
+    type t_div_factor_array is array (1 to 10) of t_div_factor;
+
+    constant c_div_factors : t_div_factor_array :=
+      ((false, 1, 0),
+       (false, 1, 1),
+       (true, 85, 8),
+       (false, 1, 2),
+       (true, 51, 8),
+       (true, 85, 9),
+       (true, 73, 9),
+       (false, 1, 3),
+       (true, 227, 11),
+       (true, 51, 9));
+
+    variable tmp    : unsigned(x'left + 11 downto 0);
+    variable result : unsigned(c_page_lines_width-1 downto 0);
+
+  begin
+
+    if(c_div_factors(y).inc) then
+      tmp := (x+1) * to_unsigned(c_div_factors(y).mul, 11);
+    else
+      tmp := x * to_unsigned(c_div_factors(y).mul, 11);
+    end if;
+
+    return tmp(c_page_lines_width - 1 + c_div_factors(y).shift downto c_div_factors(y).shift);
+  end f_fast_div_pagesize;
+
+
+  type t_ll_entry is record
+    valid     : std_logic;
+    eof       : std_logic;
+    next_page : std_logic_vector(g_page_addr_width-1 downto 0);
+    dsel      : std_logic_vector(g_partial_select_width-1 downto 0);
+    size      : std_logic_vector(f_log2_size(g_page_size)-1 downto 0);
+  end record;
+
+
+
+  -- Page fetcher signals
+  type   t_page_fetch_state is (FIRST_PAGE, NEXT_LINK, WAIT_LAST_ACK, WAIT_ACK);
+  signal page_state : t_page_fetch_state;
+  signal cur_page   : std_logic_vector(g_page_addr_width-1 downto 0);
+  signal cur_ll     : t_ll_entry;
+
+  -- Page fetch <> FIFO / output FSM signals
+
+  -- Address of the current page
+  signal fetch_pg_addr  : std_logic_vector(g_page_addr_width-1 downto 0);
+  -- Number of words in the page (1 = 1 word...g_page_size-1 == full page)
+  signal fetch_pg_words : unsigned(c_page_lines_width-1 downto 0);
+  -- Number of FBM lines used by this page (1 = 1 line, etc.)
+  signal fetch_pg_lines : unsigned(c_page_lines_width-1 downto 0);
+  -- Partial select bits for the last word of the packet
+  signal fetch_dsel     : std_logic_vector(g_partial_select_width-1 downto 0);
+  -- Is the page the last one in the current chain?
+  signal fetch_last     : std_logic;
+  -- Is the page the first one in the current chain?
+  signal fetch_first    : std_logic;
+  -- Acknowledge of the transfer on pg_addr/ast/valid/remaining/dsel lines. The
+  -- fetcher will proceed with the next page/packet only after getting an ACK.
+  signal fetch_ack      : std_logic;
+  -- When HI, pg_addr/last/remaining/dsel contain a valid page entry.
+  signal fetch_valid    : std_logic;
+  -- When HI, fetcher aborts fetching the current page chain and proceeds to the
+  -- next packet.
+  signal fetch_abort    : std_logic;
+
+  signal saved_dsel : std_logic_vector(g_partial_select_width-1 downto 0);
+
+-- Datapath signals
+  signal df_we_d0      : std_logic;
+  signal last_page     : std_logic;
+  signal words_total   : unsigned(c_word_count_width-1 downto 0);
+  signal words_xmitted : unsigned(c_word_count_width-1 downto 0);
+
+  signal d_last_int, d_valid_int, df_rd_int : std_logic;
+  signal pf_we_int : std_logic;
+  
+begin  -- behavioral
+
+
+  fetch_abort <= '0';                   -- FIXME: add support for ABORT
+
+  p_gen_page_ack : process(clk_io_i)
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' then
+        fetch_ack <= '0';
+      else
+        fetch_ack <= pf_we_int;
+      end if;
+    end if;
+  end process;
+
+  pf_we_int     <= fetch_valid and not pf_full_i;
+  pf_we_o <= pf_we_int;
+  pf_pg_addr_o  <= fetch_pg_addr;
+  pf_pg_lines_o <= std_logic_vector(fetch_pg_lines);
+
+  p_count_words : process(clk_io_i)
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' or (d_last_int = '1' and d_valid_int = '1') then
+        words_total   <= (others => '0');
+        words_xmitted <= to_unsigned(1, words_xmitted'length);
+      else
+
+        if(fetch_last = '1' and fetch_ack = '1') then
+          saved_dsel <= fetch_dsel;
+        end if;
+
+        if(df_rd_int = '1') then
+          words_xmitted <= words_xmitted + 1;
+        end if;
+
+        if(fetch_ack = '1') then
+          if(fetch_first = '1') then
+            words_total <= fetch_pg_words;
+          else
+            words_total <= words_total + fetch_pg_words;
+          end if;
+        end if;
+      end if;
+    end if;
+  end process;
+
+  d_last_int <= '1' when (words_total = words_xmitted) else '0';
+
+
+  df_rd_int <= rport_dreq_i and not df_empty_i;
+  df_rd_o   <= df_rd_int;
+
+  p_gen_d_valid : process(clk_io_i)
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' then
+        d_valid_int <= '0';
+      else
+        d_valid_int <= df_rd_int;
+      end if;
+    end if;
+  end process;
+
+  df_flush_o <= df_rd_int and d_last_int;
+
+  rport_dvalid_o <= d_valid_int;
+  rport_dlast_o  <= d_last_int;
+  rport_d_o      <= df_d_i;
+  rport_dsel_o <= saved_dsel when (words_total = words_xmitted) else (others => '1');
+  
+
+-------------------------------------------------------------------------------
+-- Page fetcher logic
+-------------------------------------------------------------------------------  
+
+  -- pointer to the next page (shared with page size and partial select)
+  cur_ll.next_page <= ll_data_i(g_page_addr_width-1 downto 0);
+  -- 1: last page in the chain
+  cur_ll.eof       <= ll_data_i(g_page_addr_width);
+  -- 1: page is valid
+  cur_ll.valid     <= ll_data_i(g_page_addr_width+1);
+  -- 1: number of the words in page (1 = 1 word .. g_page_size-1 = full page)
+  cur_ll.size      <= ll_data_i(c_page_size_width-1 downto 0);
+  -- 1: partial select bits (number of bytes in the last word of the page. For
+  -- 16-bit datapath: 0 = 1 byte, 1 = 2 bytes, etc.)
+  cur_ll.dsel      <= ll_data_i(g_page_addr_width-1 downto g_page_addr_width-g_partial_select_width);
+
+  p_page_fsm : process(clk_io_i)
+  begin
+    if rising_edge(clk_io_i) then
+      if rst_n_io_i = '0' then
+        page_state <= FIRST_PAGE;
+
+        fetch_valid    <= '0';
+        rport_pg_req_o <= '0';
+        ll_req_o       <= '0';
+
+      else
+        case page_state is
+-- request the 1st page of the packet from the Read port interface. Once got
+-- the 1st address, go to FIRST_LL state
+          when FIRST_PAGE =>
+
+            if(rport_pg_valid_i = '1') then
+              rport_pg_req_o <= '0';
+              cur_page       <= rport_pg_addr_i;
+              ll_req_o       <= '1';
+              ll_addr_o      <= rport_pg_addr_i;
+              page_state     <= NEXT_LINK;
+              fetch_first    <= '1';
+            else
+              rport_pg_req_o <= '1';
+            end if;
+
+-- fetch the length (or the link to the next packet) from the LL for the
+-- current page
+          when NEXT_LINK =>
+            if(fetch_abort = '1') then
+              page_state <= FIRST_PAGE;
+              ll_req_o   <= '0';
+            elsif(ll_grant_i = '1' and cur_ll.valid = '1') then
+              cur_page <= cur_ll.next_page;
+
+              if(cur_ll.eof = '1') then
+                page_state     <= WAIT_LAST_ACK;
+                fetch_pg_words <= unsigned(cur_ll.size);
+                fetch_pg_lines <= f_fast_div_pagesize(unsigned(cur_ll.size), g_ratio);
+                fetch_dsel     <= cur_ll.dsel;
+                fetch_valid    <= '1';
+                fetch_last     <= '1';
+              else
+                page_state    <= WAIT_ACK;
+                fetch_pg_addr <= cur_page;
+                fetch_valid   <= '1';
+                fetch_last    <= '0';
+              end if;
+              ll_req_o <= '0';
+            else
+              ll_req_o <= '1';
+            end if;
+
+          when WAIT_ACK =>
+            if(fetch_abort = '1') then
+              page_state <= FIRST_PAGE;
+            elsif(fetch_ack = '1') then
+              ll_req_o    <= '1';
+              fetch_first <= '0';
+              page_state  <= NEXT_LINK;
+            end if;
+
+          when WAIT_LAST_ACK =>
+            if(fetch_ack = '1') then
+              rport_pg_req_o <= '1';
+              fetch_first    <= '0';
+              page_state     <= FIRST_PAGE;
+            end if;
+            
+        end case;
+      end if;
+    end if;
+  end process;
+
+
+end behavioral;
diff --git a/modules/wrsw_swcore/async/mpm_top.vhd b/modules/wrsw_swcore/async/mpm_top.vhd
new file mode 100644
index 00000000..c68ec3ee
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_top.vhd
@@ -0,0 +1,205 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.gencores_pkg.all;              -- for f_rr_arbitrate
+use work.genram_pkg.all;                -- for f_log2_size
+
+use work.mpm_private_pkg.all;
+
+entity mpm_top is
+  generic (
+    g_data_width           : integer := 18;
+    g_ratio                : integer := 8;
+    g_page_size            : integer := 64;
+    g_num_pages            : integer := 2048;
+    g_num_ports            : integer := 18;
+    g_fifo_size            : integer := 8;
+    g_page_addr_width      : integer := 11;
+    g_partial_select_width : integer := 1;
+    g_max_packet_size      : integer := 10000
+    );
+
+  port(
+    -- I/O ports clock (slow)
+    clk_io_i   : in std_logic;
+    -- Memory/Core clock (fast)
+    clk_core_i : in std_logic;
+    rst_n_i    : in std_logic;
+
+-- read-write ports I/F (streaming)
+    wport_d_i       : in  std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+    wport_dvalid_i  : in  std_logic_vector (g_num_ports-1 downto 0);
+    wport_dlast_i   : in  std_logic_vector (g_num_ports-1 downto 0);
+    wport_pg_addr_i : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+    wport_pg_req_o  : out std_logic_vector(g_num_ports -1 downto 0);
+    wport_dreq_o    : out std_logic_vector (g_num_ports-1 downto 0);
+
+
+    rport_d_o        : out std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+    rport_dvalid_o   : out std_logic_vector (g_num_ports-1 downto 0);
+    rport_dlast_o    : out std_logic_vector (g_num_ports-1 downto 0);
+    rport_dsel_o     : out std_logic_vector(g_partial_select_width -1 downto 0);
+    rport_dreq_i     : in  std_logic_vector (g_num_ports-1 downto 0);
+    rport_abort_i    : in  std_logic_vector (g_num_ports-1 downto 0);
+    rport_pg_addr_i  : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+    rport_pg_valid_i : in  std_logic_vector (g_num_ports-1 downto 0);
+    rport_pg_req_o   : out std_logic_vector (g_num_ports-1 downto 0);
+
+    ll_addr_o : out std_logic_vector(g_page_addr_width-1 downto 0);
+    ll_data_i : in  std_logic_vector(g_page_addr_width+1 downto 0)
+    );
+
+end mpm_top;
+
+architecture rtl of mpm_top is
+
+  signal rst_n_core : std_logic;
+  signal rst_n_io   : std_logic;
+
+  component mpm_write_path
+    generic (
+      g_data_width           : integer;
+      g_ratio                : integer;
+      g_page_size            : integer;
+      g_num_pages            : integer;
+      g_num_ports            : integer;
+      g_fifo_size            : integer;
+      g_page_addr_width      : integer;
+      g_partial_select_width : integer);
+    port (
+      clk_io_i        : in  std_logic;
+      clk_core_i      : in  std_logic;
+      rst_n_io_i      : in  std_logic;
+      rst_n_core_i    : in  std_logic;
+      wport_d_i       : in  std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+      wport_dvalid_i  : in  std_logic_vector (g_num_ports-1 downto 0);
+      wport_dlast_i   : in  std_logic_vector (g_num_ports-1 downto 0);
+      wport_pg_addr_i : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+      wport_pg_req_o  : out std_logic_vector(g_num_ports -1 downto 0);
+      wport_dreq_o    : out std_logic_vector (g_num_ports-1 downto 0);
+      fbm_addr_o      : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
+      fbm_data_o      : out std_logic_vector(g_ratio * g_data_width -1 downto 0);
+      fbm_we_o        : out std_logic);
+  end component;
+
+  component mpm_read_path
+    generic (
+      g_data_width           : integer;
+      g_ratio                : integer;
+      g_page_size            : integer;
+      g_num_pages            : integer;
+      g_num_ports            : integer;
+      g_fifo_size            : integer;
+      g_page_addr_width      : integer;
+      g_partial_select_width : integer;
+      g_max_packet_size      : integer);
+    port (
+      clk_io_i         : in  std_logic;
+      clk_core_i       : in  std_logic;
+      rst_n_i          : in  std_logic;
+      rport_d_o        : out std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+      rport_dvalid_o   : out std_logic_vector (g_num_ports-1 downto 0);
+      rport_dlast_o    : out std_logic_vector (g_num_ports-1 downto 0);
+      rport_dsel_o     : out std_logic_vector(g_partial_select_width -1 downto 0);
+      rport_dreq_i     : in  std_logic_vector (g_num_ports-1 downto 0);
+      rport_abort_i    : in  std_logic_vector (g_num_ports-1 downto 0);
+      rport_pg_addr_i  : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+      rport_pg_req_o   : out std_logic_vector(g_num_ports-1 downto 0);
+      rport_pg_valid_i : in  std_logic_vector (g_num_ports-1 downto 0);
+      ll_addr_o        : out std_logic_vector(g_page_addr_width-1 downto 0);
+      ll_data_i        : in  std_logic_vector(g_page_addr_width+1 downto 0);
+      fbm_addr_o       : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
+      fbm_data_i       : in  std_logic_vector(g_ratio * g_data_width -1 downto 0));
+  end component;
+
+  signal fbm_wr_addr, fbm_rd_addr : std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
+  signal fbm_wr_data, fbm_rd_data : std_logic_vector(g_ratio * g_data_width -1 downto 0);
+  signal fbm_we                   : std_logic;
+  
+begin  -- rtl
+
+
+
+  -- Reset synchronizer for the core clock domain
+  U_Sync_Reset_Coreclk : gc_sync_ffs
+    port map (
+      clk_i    => clk_core_i,
+      rst_n_i  => '1',
+      data_i   => rst_n_i,
+      synced_o => rst_n_core);
+
+  rst_n_io <= rst_n_i;
+
+  U_Write_Path : mpm_write_path
+    generic map (
+      g_data_width           => g_data_width,
+      g_ratio                => g_ratio,
+      g_page_size            => g_page_size,
+      g_num_pages            => g_num_pages,
+      g_num_ports            => g_num_ports,
+      g_fifo_size            => g_fifo_size,
+      g_page_addr_width      => g_page_addr_width,
+      g_partial_select_width => g_partial_select_width)
+    port map (
+      clk_io_i        => clk_io_i,
+      clk_core_i      => clk_core_i,
+      rst_n_io_i      => rst_n_io,
+      rst_n_core_i    => rst_n_core,
+      wport_d_i       => wport_d_i,
+      wport_dvalid_i  => wport_dvalid_i,
+      wport_dlast_i   => wport_dlast_i,
+      wport_pg_addr_i => wport_pg_addr_i,
+      wport_pg_req_o  => wport_pg_req_o,
+      wport_dreq_o    => wport_dreq_o,
+      fbm_addr_o      => fbm_wr_addr,
+      fbm_data_o      => fbm_wr_data,
+      fbm_we_o        => fbm_we);
+
+  U_Read_Path : mpm_read_path
+    generic map (
+      g_data_width           => g_data_width,
+      g_ratio                => g_ratio,
+      g_page_size            => g_page_size,
+      g_num_pages            => g_num_pages,
+      g_num_ports            => g_num_ports,
+      g_fifo_size            => g_fifo_size,
+      g_page_addr_width      => g_page_addr_width,
+      g_partial_select_width => g_partial_select_width,
+      g_max_packet_size      => g_max_packet_size)
+    port map (
+      clk_io_i         => clk_io_i,
+      clk_core_i       => clk_core_i,
+      rst_n_i          => rst_n_i,
+      rport_d_o        => rport_d_o,
+      rport_dvalid_o   => rport_dvalid_o,
+      rport_dlast_o    => rport_dlast_o,
+      rport_dsel_o     => rport_dsel_o,
+      rport_dreq_i     => rport_dreq_i,
+      rport_abort_i    => rport_abort_i,
+      rport_pg_addr_i  => rport_pg_addr_i,
+      rport_pg_req_o   => rport_pg_req_o,
+      rport_pg_valid_i => rport_pg_valid_i,
+      ll_addr_o        => ll_addr_o,
+      ll_data_i        => ll_data_i,
+      fbm_addr_o       => fbm_rd_addr,
+      fbm_data_i       => fbm_rd_data);
+
+
+  -- The memory itself.
+  U_F_B_Memory : generic_dpram
+    generic map (
+      g_data_width => g_data_width * g_ratio,
+      g_size       => g_num_pages * (g_page_size / g_ratio))
+    port map (
+      rst_n_i => rst_n_core,
+      clka_i  => clk_core_i,
+      wea_i   => fbm_we,
+      aa_i    => fbm_wr_addr,
+      da_i    => fbm_wr_data,
+      clkb_i  => clk_core_i,
+      web_i   => '0',
+      ab_i    => fbm_rd_addr,
+      qb_o    => fbm_rd_data);
+
+end rtl;
diff --git a/modules/wrsw_swcore/async/mpm_write_path.vhd b/modules/wrsw_swcore/async/mpm_write_path.vhd
new file mode 100644
index 00000000..78ef5b6d
--- /dev/null
+++ b/modules/wrsw_swcore/async/mpm_write_path.vhd
@@ -0,0 +1,303 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.mpm_private_pkg.all;
+
+use work.gencores_pkg.all;              -- for f_rr_arbitrate
+use work.genram_pkg.all;                -- for f_log2_size
+
+entity mpm_write_path is
+  
+  generic (
+    g_data_width           : integer := 10;
+    g_ratio                : integer := 4;
+    g_page_size            : integer := 64;
+    g_num_pages            : integer := 2048;
+    g_num_ports            : integer := 18;
+    g_fifo_size            : integer := 4;
+    g_page_addr_width      : integer := 11;
+    g_partial_select_width : integer := 1
+    );
+
+  port(
+    -- I/O ports clock (slow)
+    clk_io_i   : in std_logic;
+    -- Memory/Core clock (fast)
+    clk_core_i : in std_logic;
+
+    rst_n_io_i   : in std_logic;
+    rst_n_core_i : in std_logic;
+
+-- read-write ports I/F (streaming)
+    wport_d_i       : in  std_logic_vector (g_num_ports * g_data_width -1 downto 0);
+    wport_dvalid_i  : in  std_logic_vector (g_num_ports-1 downto 0);
+    wport_dlast_i   : in  std_logic_vector (g_num_ports-1 downto 0);
+    wport_pg_addr_i : in  std_logic_vector (g_num_ports * g_page_addr_width -1 downto 0);
+    wport_pg_req_o  : out std_logic_vector(g_num_ports -1 downto 0);
+    wport_dreq_o    : out std_logic_vector (g_num_ports-1 downto 0);
+
+-- F. B. Memory output
+    fbm_addr_o : out std_logic_vector(f_log2_size(g_num_pages * g_page_size / g_ratio)-1 downto 0);
+    fbm_data_o : out std_logic_vector(g_ratio * g_data_width -1 downto 0);
+    fbm_we_o   : out std_logic
+    );
+
+end mpm_write_path;
+
+architecture rtl of mpm_write_path is
+
+  constant c_line_size_width     : integer := f_log2_size(g_page_size / g_ratio);
+  constant c_fbm_data_width      : integer := g_ratio * g_data_width;
+  constant c_fbm_entries         : integer := g_num_pages * g_page_size / g_ratio;
+  constant c_fbm_addr_width      : integer := f_log2_size(c_fbm_entries);
+  constant c_fifo_sideband_width : integer := c_fbm_addr_width;
+
+  type t_mpm_write_port is record
+    -- data input
+    d       : std_logic_vector(g_data_width-1 downto 0);
+    -- 1: got valid data word on d
+    d_valid : std_logic;
+    -- 1: end-of-packet
+    d_last  : std_logic;
+    -- address of the page to be written to (important only on the 1st write to
+    -- the page)
+    pg_addr : std_logic_vector(g_page_addr_width-1 downto 0);
+    pg_req  : std_logic;
+    dreq    : std_logic;
+  end record;
+
+
+  type t_wport_state is record
+    -- clk_io_i domain
+    pg_addr     : unsigned(g_page_addr_width-1 downto 0);
+    pg_offset   : unsigned(c_line_size_width-1 downto 0);
+    word_count  : unsigned(f_log2_size(g_ratio)-1 downto 0);
+    fbm_addr_in : unsigned(c_fbm_addr_width-1 downto 0);
+    fifo_full   : std_logic;
+    fifo_we     : std_logic;
+    fifo_align  : std_logic;
+
+    -- clk_core_i domain
+    fifo_rd      : std_logic;
+    fifo_empty   : std_logic;
+    fifo_q       : std_logic_vector(c_fbm_data_width -1 downto 0);
+    fbm_addr_out : std_logic_vector(c_fbm_addr_width-1 downto 0);
+    grant_d      : std_logic_vector(3 downto 0);
+  end record;
+
+  type t_mpm_write_port_array is array (integer range <>) of t_mpm_write_port;
+  type t_wport_state_array is array(integer range <>) of t_wport_state;
+
+  signal wstate : t_wport_state_array(g_num_ports-1 downto 0);
+  signal wport  : t_mpm_write_port_array(g_num_ports-1 downto 0);
+
+
+  signal arb_req, arb_grant : std_logic_vector(g_num_ports-1 downto 0);
+
+  signal wr_mux_a_in : std_logic_vector(g_num_ports * c_fbm_addr_width -1 downto 0);
+  signal wr_mux_d_in : std_logic_vector(g_num_ports * c_fbm_data_width -1 downto 0);
+  signal fbm_we_d    : std_logic_vector(2 downto 0);
+
+  signal wr_mux_sel : std_logic_vector(g_num_ports-1 downto 0);
+  
+begin  -- rtl
+
+-- I/O structure serialization/deserialization
+  gen_serialize_ios : for i in 0 to g_num_ports-1 generate
+    wport(i).d        <= f_slice(wport_d_i, i, g_data_width);
+    wport(i).d_valid  <= wport_dvalid_i(i);
+    wport(i).d_last   <= wport_dlast_i(i);
+    wport(i).pg_addr  <= f_slice(wport_pg_addr_i, i, g_page_addr_width);
+    wport_dreq_o(i)   <= wport(i).dreq;
+    wport_pg_req_o(i) <= wport(i).pg_req;
+  end generate gen_serialize_ios;
+
+  -----------------------------------------------------------------------------
+  -- Write side logic
+  -----------------------------------------------------------------------------
+  -----------------------------------------------------------------------------
+  gen_input_arbiter_ios : for i in 0 to g_num_ports-1 generate
+
+    -- arbiter request vector generation: If there is any data in the input
+    -- FIFOs, it's request line becomes active. Another requst from the same
+    -- port can be served 3 cycles later (pipeline delay)
+    arb_req(i) <= not wstate(i).fifo_empty and not (wstate(i).grant_d(0) or wstate(i).grant_d(1) or wstate(i).grant_d(2));
+
+    wstate(i).grant_d(0) <= arb_grant(i);
+
+    -- Delay the grant signal to generate enables for each pipeline stage
+    process(clk_core_i)
+    begin
+      if rising_edge(clk_core_i) then
+        if rst_n_core_i = '0' then
+          wstate(i).grant_d(3 downto 1) <= (others => '0');
+        else
+          wstate(i).grant_d(3) <= wstate(i).grant_d(2);
+          wstate(i).grant_d(2) <= wstate(i).grant_d(1);
+          wstate(i).grant_d(1) <= wstate(i).grant_d(0);
+        end if;
+      end if;
+    end process;
+  end generate gen_input_arbiter_ios;
+
+      -- The actual round-robin arbiter.
+    p_input_arbiter : process(clk_core_i)
+    begin
+      if rising_edge(clk_core_i) then
+        if rst_n_core_i = '0' then
+          arb_grant <= (others => '0');
+        else
+          f_rr_arbitrate(arb_req, arb_grant, arb_grant);
+        end if;
+      end if;
+    end process;
+
+
+
+  -- write side address counter. Calculates the address of the entry in the F.B. Memory
+  -- the incoming data shall be written to.
+  -- It contains two nested counters:
+  -- - word_count, which counts the number of words in the line of the FBM currently
+  --   being written. Each line contains g_ratio words of g_data_width.
+  -- - pg_offset, which counts up every time the previous counter overflow,
+  --   addressing subsequent cells of the FBM.
+  -- When we reach the end of the current page, both counters are reset, so we
+  -- can proceed with the next page.
+
+  gen_input_addr_counters : for i in 0 to g_num_ports-1 generate
+    process(clk_io_i)
+    begin
+      if rising_edge(clk_io_i) then
+-- Reset or last data transfer in the frame? Go to the beginning of the page.
+        if (rst_n_io_i = '0') or (wport(i).d_valid = '1' and wport(i).d_last = '1') then
+          wstate(i).pg_offset  <= (others => '0');
+          wstate(i).word_count <= (others => '0');
+        else
+          if(wport(i).d_valid = '1') then
+            if(wstate(i).word_count = g_ratio-1) then
+              wstate(i).word_count <= (others => '0');
+
+              -- end-of-page?
+              if(wstate(i).pg_offset = g_page_size / g_ratio - 1) then
+                wstate(i).pg_offset <= (others => '0');
+              else
+                wstate(i).pg_offset <= wstate(i).pg_offset + 1;
+              end if;
+            else
+              wstate(i).word_count <= wstate(i).word_count + 1;
+            end if;
+          end if;
+        end if;
+      end if;
+    end process;
+
+    -- Generate a page request signal on the last word of the current page.
+    -- This way, the source won't have to keep track of the words written per
+    -- each page and so will save some resources.
+    wport(i).pg_req <= '1' when (wport(i).d_valid = '1'
+                                 and wstate(i).pg_offset = g_page_size/g_ratio-1
+                                 and wstate(i).word_count = g_ratio -1)
+                       else '0';
+
+    -- combine the current page address and page-internal offset into final
+    -- FBM address
+    wstate(i).fbm_addr_in <= resize(unsigned(wport(i).pg_addr) * (g_page_size/g_ratio) + wstate(i).pg_offset, c_fbm_addr_width);
+  end generate gen_input_addr_counters;
+
+
+  -- Input FIFO blocks
+  gen_input_fifos : for i in 0 to g_num_ports-1 generate
+
+    -- Dual-clock "growing" FIFO. Takes N bit words in clk_io_i clock domain and outputs (N*M)
+    -- parallelized words in clk_core_i domain. This allows for significant
+    -- reduction of the size of multipumped memory input registers, but a
+    -- higher core clock frequency is required. In our case N = g_data_width
+    -- and M = g_ratio.
+    --
+    -- The FIFO also provides a "sideband" channel working
+    -- synchronously with the wide port and used to pass FBM addresses. Thanks
+    -- to that, the fast clock domain only does the multiplexing.
+
+    U_Input_FIFOx : mpm_async_grow_fifo
+      generic map (
+        g_width          => g_data_width,
+        g_ratio          => g_ratio,
+        g_size           => g_fifo_size,
+        g_sideband_width => c_fifo_sideband_width)
+      port map (
+        rst_n_a_i => rst_n_core_i,
+        clk_wr_i  => clk_io_i,
+        clk_rd_i  => clk_core_i,
+
+        we_i    => wstate(i).fifo_we,
+        align_i => wstate(i).fifo_align,
+        d_i     => wport(i).d,
+
+        side_i => std_logic_vector(wstate(i).fbm_addr_in),
+        side_o => wstate(i).fbm_addr_out,
+
+        rd_i    => wstate(i).fifo_rd,
+        q_o     => wstate(i).fifo_q,
+        full_o  => wstate(i).fifo_full,
+        empty_o => wstate(i).fifo_empty);
+
+
+    wport(i).dreq        <= not wstate(i).fifo_full;
+    wstate(i).fifo_we    <= wport(i).d_valid;
+    wstate(i).fifo_align <= wport(i).d_last;
+    wstate(i).fifo_rd    <= wstate(i).grant_d(0);  -- and not wstate(i).grant_d(1);
+  end generate gen_input_fifos;
+
+
+  gen_mux_inputs : for i in 0 to g_num_ports-1 generate
+    wr_mux_d_in(c_fbm_data_width * (i + 1) - 1 downto c_fbm_data_width * i) <= wstate(i).fifo_q;
+    wr_mux_a_in(c_fbm_addr_width * (i + 1) - 1 downto c_fbm_addr_width * i) <= wstate(i).fbm_addr_out;
+    wr_mux_sel(i)                                                           <= wstate(i).grant_d(1);
+  end generate gen_mux_inputs;
+
+  U_Data_Mux : mpm_pipelined_mux
+    generic map (
+      g_width  => c_fbm_data_width,
+      g_inputs => g_num_ports)
+    port map (
+      clk_i   => clk_core_i,
+      rst_n_i => rst_n_core_i,
+      d_i     => wr_mux_d_in,
+      q_o     => fbm_data_o,
+      sel_i   => wr_mux_sel);
+
+  U_WR_Address_Mux : mpm_pipelined_mux
+    generic map (
+      g_width  => c_fbm_addr_width,
+      g_inputs => g_num_ports)
+    port map (
+      clk_i   => clk_core_i,
+      rst_n_i => rst_n_core_i,
+      d_i     => wr_mux_a_in,
+      q_o     => fbm_addr_o,
+      sel_i   => wr_mux_sel);
+
+  
+  p_write_pipe : process(clk_core_i)
+  begin
+    if rising_edge(clk_core_i) then
+      if rst_n_core_i = '0' then
+        fbm_we_d <= (others => '0');
+      else
+        if(unsigned(wr_mux_sel) /= 0) then
+          fbm_we_d(0) <= '1';
+        else
+          fbm_we_d(0) <= '0';
+        end if;
+        fbm_we_d(1) <= fbm_we_d(0);
+        fbm_we_d(2) <= fbm_we_d(1);
+      end if;
+    end if;
+  end process;
+
+
+  fbm_we_o <= fbm_we_d(1);
+  
+
+end rtl;
diff --git a/modules/wrsw_swcore/async/swc_async_fifo.vhd b/modules/wrsw_swcore/async/swc_async_fifo.vhd
deleted file mode 100644
index 3ec9c39f..00000000
--- a/modules/wrsw_swcore/async/swc_async_fifo.vhd
+++ /dev/null
@@ -1,106 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-use work.genram_pkg.all;                -- for f_log2_size
-
-entity swc_async_grow_fifo is
-  
-  generic (
-    g_width : integer;
-    g_ratio : integer;
-    g_size  : integer);
-
-  port (
-    rst_n_i  : in std_logic;
-    clk_wr_i : in std_logic;
-    clk_rd_i : in std_logic;
-
-    we_i : in std_logic;
-    d_i  : in std_logic_vector(g_width-1 downto 0);
-
-    rd_i : in  std_logic;
-    q_o  : out std_logic_vector(g_width * g_ratio-1 downto 0);
-
-    wr_full_o  : out std_logic;
-    rd_empty_o : out std_logic);
-
-end swc_async_grow_fifo;
-
-architecture rtl of swc_async_grow_fifo is
-
-  component swc_fifo_mem_cell
-    generic (
-      g_width : integer;
-      g_size  : integer);
-    port (
-      clk_i : in  std_logic;
-      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      wd_i  : in  std_logic_vector(g_width-1 downto 0);
-      we_i  : in  std_logic;
-      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_o  : out std_logic_vector(g_width-1 downto 0));
-  end component;
-
-  component swc_async_fifo_ctrl
-    generic (
-      g_size : integer);
-    port (
-      rst_n_i   : in  std_logic;
-      clk_wr_i  : in  std_logic;
-      clk_rd_i  : in  std_logic;
-      rd_i      : in  std_logic;
-      wr_i      : in  std_logic;
-      wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      full_o    : out std_logic;
-      empty_o   : out std_logic);
-  end component;
-  
-  signal wr_sreg        : std_logic_vector(g_ratio-1 downto 0);
-  signal wr_cell        : std_logic_vector(g_ratio-1 downto 0);
-  signal real_we             : std_logic;
-  signal q_int               : std_logic_vector(g_width*g_ratio-1 downto 0);
-  signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
-  
-begin  -- rtl
-
-  gen_mem_cells : for i in 0 to g_ratio-1 generate
-
-    wr_cell(i) <= we_i and wr_sreg(i);
-    U_Mem : swc_fifo_mem_cell
-      generic map (
-        g_width => g_width * g_ratio,
-        g_size  => g_size)
-      port map (
-        clk_i => clk_wr_i,
-        wa_i  => wr_addr,
-        wd_i  => d_i,
-        we_i  => rd_addr,
-        ra_i  => std_logic_vector(rd_ptr),
-        rd_o  => q_int(g_width*(i+1) -1 downto g_width*i));
-  end generate gen_mem_cells;
-
-  p_write_grow_sreg : process(clk_wr_i, rst_n_i)
-  begin
-    if rst_n_i = '0' then
-      wr_sreg(0)                     <= '1';
-      wr_sreg(wr_sreg'left downto 1) <= (others => '0');
-      real_we                        <= '0';
-    elsif rising_edge(clk_wr_i) then
-      if(we_i = '1') then
-        wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
-
-        if(wr_sreg(wr_sreg'left) = '1' and full_int = '0') then
-          real_we <= '1';
-        else
-          real_we <= '0';
-        end if;
-      else
-        real_we <= '0';
-      end if;
-    end if;
-  end process;
-
-  
-end rtl;
diff --git a/modules/wrsw_swcore/async/swc_async_fifo_ctrl.vhd b/modules/wrsw_swcore/async/swc_async_fifo_ctrl.vhd
deleted file mode 100644
index 9ceed766..00000000
--- a/modules/wrsw_swcore/async/swc_async_fifo_ctrl.vhd
+++ /dev/null
@@ -1,164 +0,0 @@
--------------------------------------------------------------------------------
--- Title        : Dual clock (asynchronous) FIFO controller
--- Project      : White Rabbit Switch
--------------------------------------------------------------------------------
--- File         : swc_async_fifo_ctrl.vhd
--- Author       : Tomasz WÅ‚ostowski
--- Company      : CERN BE-CO-HT
--- Created      : 2012-01-30
--- Last update  : 2012-01-30
--- Platform     : FPGA-generic
--- Standard     : VHDL'93
--- Dependencies : genram_pkg
--------------------------------------------------------------------------------
--- Description: Gray-encoded dual clock FIFO controller and address generator.
--- Based on Xilinx Application Note "Asynchronous FIFO in Virtex-II FPGAs" by
--- P. Alfke & example code from http://www.asic-world.com.
--------------------------------------------------------------------------------
---
--- Copyright (c) 2012 CERN
---
--- This source file is free software; you can redistribute it   
--- and/or modify it under the terms of the GNU Lesser General   
--- Public License as published by the Free Software Foundation; 
--- either version 2.1 of the License, or (at your option) any   
--- later version.                                               
---
--- This source is distributed in the hope that it will be       
--- useful, but WITHOUT ANY WARRANTY; without even the implied   
--- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
--- PURPOSE.  See the GNU Lesser General Public License for more 
--- details.                                                     
---
--- You should have received a copy of the GNU Lesser General    
--- Public License along with this source; if not, download it   
--- from http://www.gnu.org/licenses/lgpl-2.1.html
---
--------------------------------------------------------------------------------
--- Revisions  :
--- Date        Version  Author          Description
--- 2012-01-30  1.0      twlostow        Created
--------------------------------------------------------------------------------
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-use work.genram_pkg.all;
-
-entity swc_async_fifo_ctrl is
-  
-  generic (
-    g_size : integer);
-
-  port(
-    rst_n_a_i  : in std_logic;
-    clk_wr_i : in std_logic;
-    clk_rd_i : in std_logic;
-
-    rd_i : in std_logic;
-    wr_i : in std_logic;
-
-    wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-    rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-
-    full_o  : out std_logic;
-    empty_o : out std_logic);
-  
-end swc_async_fifo_ctrl;
-
-architecture rtl of swc_async_fifo_ctrl is
-
-  -- Gray-encoded increase-by-1 function. Takes a gray-encoded integer x and returns
-  -- gray-encoded value of (x+1).
-  function f_gray_inc(x : unsigned) return unsigned is
-    variable bin, tmp : unsigned(x'left downto 0);
-  begin
-  -- gray to binary
-    for i in 0 to x'left loop
-      bin(i) := '0';
-      for j in i to x'left loop
-        bin(i) := bin(i) xor x(j);
-      end loop;  -- j 
-    end loop;  -- i
-    -- increase
-    tmp := bin + 1;
-    -- binary to gray
-    return tmp(tmp'left) & (tmp(tmp'left-1 downto 0) xor tmp(tmp'left downto 1));
-  end f_gray_inc;
-
-  signal wr_ptr, rd_ptr : unsigned(f_log2_size(g_size) -1 downto 0);
-  signal full_int, empty_int : std_logic;
-  signal same_addr           : std_logic;
-  signal rst_stat, set_stat  : std_logic;
-  signal set_full, set_empty : std_logic;
-  signal stat                : std_logic;
-begin  -- rtl
-
-  p_write_ptr : process(clk_wr_i, rst_n_a_i)
-  begin
-    if rst_n_a_i = '0' then
-      wr_ptr <= (others => '0');
-    elsif rising_edge(clk_wr_i) then
-      if(wr_i = '1' and full_int = '0') then
-        wr_ptr <= f_gray_inc(wr_ptr);
-      end if;
-    end if;
-  end process;
-
-
-  p_read_ptr : process(clk_rd_i, rst_n_a_i)
-  begin
-    if rst_n_a_i = '0' then
-      rd_ptr <= (others => '0');
-    elsif rising_edge(clk_rd_i) then
-      if(rd_i = '1' and empty_int = '0') then
-        rd_ptr <= f_gray_inc(rd_ptr);
-      end if;
-    end if;
-  end process;
-
-  p_quardant_status : process(rd_ptr, wr_ptr)
-  begin
-    set_stat <= (wr_ptr(wr_ptr'left-1) xnor rd_ptr(rd_ptr'left))
-                and (wr_ptr(wr_ptr'left) xor rd_ptr(rd_ptr'left-1));
-    rst_stat <= (wr_ptr(wr_ptr'left-1) xor rd_ptr(rd_ptr'left))
-                and (wr_ptr(wr_ptr'left) xnor rd_ptr(rd_ptr'left-1));
-  end process;
-
-  process(set_stat, rst_stat, rst_n_a_i)
-  begin
-    if(rst_stat = '1' or rst_n_a_i = '0') then
-      stat <= '0';
-    elsif(set_stat = '1') then
-      stat <= '1';
-    end if;
-  end process;
-
-  set_full  <= '1' when (stat = '1' and wr_ptr = rd_ptr) else '0';
-  set_empty <= '1' when (stat = '0' and wr_ptr = rd_ptr) else '0';
-
-  p_full_flag : process(clk_wr_i, set_full)
-  begin
-    if(set_full = '1') then
-      full_int <= '1';
-    elsif rising_edge(clk_wr_i) then
-      full_int <= set_full;
-    end if;
-  end process;
-
-  p_empty_flag : process(clk_rd_i, set_empty)
-  begin
-    if(set_empty = '1') then
-      empty_int <= '1';
-    elsif rising_edge(clk_rd_i) then
-      empty_int <= set_empty;
-    end if;
-  end process;
-
-  full_o  <= full_int;
-  empty_o <= empty_int;
-
-  wr_addr_o <= std_logic_vector(wr_ptr);
-  rd_addr_o <= std_logic_vector(rd_ptr);
-end rtl;
diff --git a/modules/wrsw_swcore/async/swc_async_grow_fifo.vhd b/modules/wrsw_swcore/async/swc_async_grow_fifo.vhd
deleted file mode 100644
index 613fe465..00000000
--- a/modules/wrsw_swcore/async/swc_async_grow_fifo.vhd
+++ /dev/null
@@ -1,138 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-use work.genram_pkg.all;                -- for f_log2_size
-
-entity swc_async_grow_fifo is
-  
-  generic (
-    g_width          : integer := 16;
-    g_ratio          : integer := 6;
-    g_size           : integer := 8;
-    g_sideband_width : integer := 16);
-
-  port (
-    rst_n_i  : in std_logic;
-    clk_wr_i : in std_logic;
-    clk_rd_i : in std_logic;
-
-    we_i    : in std_logic;
-    align_i : in std_logic;             -- 1: aligned write
-    d_i     : in std_logic_vector(g_width-1 downto 0);
-
-    rd_i   : in  std_logic;
-    q_o    : out std_logic_vector(g_width * g_ratio-1 downto 0);
-
-    -- "Sideband" channel (for passing aux data)
-    side_i  : in std_logic_vector(g_sideband_width-1 downto 0);
-    side_o : out std_logic_vector(g_sideband_width-1 downto 0);
-
-    full_o  : out std_logic;
-    empty_o : out std_logic);
-
-end swc_async_grow_fifo;
-
-architecture rtl of swc_async_grow_fifo is
-
-  component swc_fifo_mem_cell
-    generic (
-      g_width : integer;
-      g_size  : integer);
-    port (
-      clk_i : in  std_logic;
-      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      wd_i  : in  std_logic_vector(g_width-1 downto 0);
-      we_i  : in  std_logic;
-      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_o  : out std_logic_vector(g_width-1 downto 0));
-  end component;
-
-  component swc_async_fifo_ctrl
-    generic (
-      g_size : integer);
-    port (
-      rst_n_i   : in  std_logic;
-      clk_wr_i  : in  std_logic;
-      clk_rd_i  : in  std_logic;
-      rd_i      : in  std_logic;
-      wr_i      : in  std_logic;
-      wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      full_o    : out std_logic;
-      empty_o   : out std_logic);
-  end component;
-
-  signal wr_sreg          : std_logic_vector(g_ratio-1 downto 0);
-  signal wr_cell          : std_logic_vector(g_ratio-1 downto 0);
-  signal real_we          : std_logic;
-  signal q_int            : std_logic_vector(g_width*g_ratio-1 downto 0);
-  signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
-  signal full_int         : std_logic;
-  
-begin  -- rtl
-
-  gen_mem_cells : for i in 0 to g_ratio-1 generate
-
-    wr_cell(i) <= wr_sreg(i) and we_i;
-
-    U_Mem : swc_fifo_mem_cell
-      generic map (
-        g_width => g_width,
-        g_size  => g_size)
-      port map (
-        clk_i => clk_wr_i,
-        wa_i  => wr_addr,
-        wd_i  => d_i,
-        we_i  => wr_cell(i),
-        ra_i  => rd_addr,
-        rd_o  => q_int(g_width*(i+1) -1 downto g_width*i));
-  end generate gen_mem_cells;
-
-  U_CTRL : swc_async_fifo_ctrl
-    generic map (
-      g_size => g_size)
-    port map (
-      rst_n_i   => rst_n_i,
-      clk_wr_i  => clk_wr_i,
-      clk_rd_i  => clk_rd_i,
-      rd_i      => rd_i,
-      wr_i      => real_we,
-      wr_addr_o => wr_addr,
-      rd_addr_o => rd_addr,
-      full_o    => full_int,
-      empty_o   => empty_o);
-
-  p_write_grow_sreg : process(clk_wr_i, rst_n_i)
-  begin
-    if rst_n_i = '0' then
-      wr_sreg(0)                     <= '1';
-      wr_sreg(wr_sreg'left downto 1) <= (others => '0');
-    elsif rising_edge(clk_wr_i) then
-      if(we_i = '1') then
-        if(align_i = '1') then
-          wr_sreg(0)                     <= '1';
-          wr_sreg(wr_sreg'left downto 1) <= (others => '0');
-        else
-          wr_sreg <= wr_sreg(wr_sreg'left-1 downto 0) & wr_sreg(wr_sreg'left);
-        end if;
-      end if;
-    end if;
-  end process;
-
-  real_we <= wr_cell(wr_cell'left);
-
-  p_output_reg : process(clk_rd_i, rst_n_i)
-  begin
-    if (rst_n_i = '0') then
-      q_o <= (others => '0');
-    elsif rising_edge(clk_rd_i) then
-      if(rd_i = '1') then
-        q_o <= q_int;
-      end if;
-    end if;
-  end process;
-
-  full_o <= full_int and wr_sreg(wr_sreg'left);
-  
-end rtl;
diff --git a/modules/wrsw_swcore/async/swc_async_multiport_mem.vhd b/modules/wrsw_swcore/async/swc_async_multiport_mem.vhd
deleted file mode 100644
index 10d6d3f4..00000000
--- a/modules/wrsw_swcore/async/swc_async_multiport_mem.vhd
+++ /dev/null
@@ -1,139 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-use work.swc_private_pkg.all;
-use work.genram_pkg.all;
-
-entity swc_async_multiport_mem is
-  
-  generic (
-    g_ratio     : integer;
-    g_page_size : integer;
-    g_num_pages : integer;
-    g_num_ports : integer
-    );
-
-  port(
-    -- I/O ports clock (slow)
-    clk_io_i   : in std_logic;
-    -- Memory/Core clock (fast)
-    clk_core_i : in std_logic;
-    rst_n_i    : in std_logic;
-
--- read-write ports I/F (streaming)
-    wport_i : in  t_mpm_write_in_array(0 to g_num_ports-1);
-    wport_o : out t_mpm_write_out_array(0 to g_num_ports-1);
-
-    rport_i : in  t_mpm_read_in_array(0 to g_num_ports-1);
-    rport_o : out t_mpm_read_out_array(0 to g_num_ports-1);
-
--- linked list I/F
-
-    ll_addr_o : out std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
-    ll_data_o : out std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
-    ll_data_i : in  std_logic_vector(f_log2_size(g_num_pages)-1 downto 0);
-    ll_we_o   : out std_logic
-    );
-
-end swc_async_multiport_mem;
-
-architecture rtl of swc_async_multiport_mem is
-
-  
-  component swc_async_grow_fifo
-    generic (
-      g_width : integer;
-      g_ratio : integer;
-      g_size  : integer);
-    port (
-      rst_n_i  : in  std_logic;
-      clk_wr_i : in  std_logic;
-      clk_rd_i : in  std_logic;
-      align_i  : in  std_logic;
-      we_i     : in  std_logic;
-      d_i      : in  std_logic_vector(g_width-1 downto 0);
-      rd_i     : in  std_logic;
-      q_o      : out std_logic_vector(g_width * g_ratio-1 downto 0);
-      full_o   : out std_logic;
-      empty_o  : out std_logic);
-  end component;
-
-  type t_fifo_slv_array is array(0 to g_num_ports-1) of std_logic_vector(c_data_path_width downto 0);
-
-  type t_wport_state is record
-    cur_page    : unsigned(c_page_addr_width-1 downto 0);
-    cur_offset  : unsigned(f_log2_size(g_page_size)-1 downto 0);
-    cur_valid   : std_logic;
-    next_page   : unsigned(c_page_addr_width-1 downto 0);
-    next_offset : unsigned(f_log2_size(g_page_size)-1 downto 0);
-    next_valid  : std_logic;
-
-    fifo_empty  : std_logic;
-    fifo_full   : std_logic;
-    fifo_nempty : std_logic;
-    fifo_rd     : std_logic;
-    fifo_q      : std_logic_vector((c_data_path_width+1) * g_ratio - 1 downto 0);
-  end record;
-
-  type t_wport_state_array is array(0 to g_num_ports-1) of t_wport_state;
-
-  signal w_req, w_sel, w_mask : std_logic_vector(f_log2_size(g_num_ports)-1 downto 0);
-  signal wstate               : t_wport_state_array;
-
-  procedure f_rr_arbitrate (
-    signal req       : in  std_logic_vector;
-    signal pre_grant : in  std_logic_vector;
-    signal grant     : out std_logic_vector)is
-
-    variable reqs  : std_logic_vector(g_width - 1 downto 0);
-    variable gnts  : std_logic_vector(g_width - 1 downto 0);
-    variable gnt   : std_logic_vector(g_width - 1 downto 0);
-    variable gntM  : std_logic_vector(g_width - 1 downto 0);
-    variable zeros : std_logic_vector(g_width - 1 downto 0);
-    
-  begin
-    zeros := (others => '0');
-
-    -- bit twiddling magic :
-    s_gnt  := req and std_logic_vector(unsigned(not req) + 1);
-    s_reqs := req and not (std_logic_vector(unsigned(pre_grant) - 1) or pre_grant);
-    s_gnts := reqs and std_logic_vector(unsigned(not reqs)+1);
-    s_gntM := gnt when reqs = zeros else gnts;
-
-    if((req and pre_grant) = s_zeros) then
-      grant       <= gntM;
-      s_pre_grant <= gntM;  -- remember current grant vector, for the next operation
-    end if;
-    
-  end f_rr_arbitrate;
-  
-  
-begin  -- rtl
-
-  gen_input_fifos : for i in 0 to g_num_ports-1 generate
-
-    U_Input_FIFOx : swc_async_grow_fifo
-      generic map (
-        g_width => c_data_path_width + 1,
-        g_ratio => g_ratio,
-        g_size  => c_mpm_async_fifo_depth)
-      port map (
-        rst_n_i                           => rst_n_i,
-        clk_wr_i                          => clk_io_i,
-        clk_rd_i                          => clk_core_i,
-        we_i                              => wport_i(i).d_valid,
-        d_i(c_data_path_width-2 downto 0) => wport_i(i).d,
-        d_i(c_data_path_width-1)          => wport_i(i).d_eof,
-        align_i                           => wport_i(i).d_eof,
-
-        rd_i    => wstate(i).fifo_rd,
-        q_o     => wstate(i).fifo_q,
-        full_o  => wstate(i).fifo_full,
-        empty_o => wstate(i).fifo_empty);
-  end generate gen_input_fifos;
-
-
-
-  
-end rtl;
diff --git a/modules/wrsw_swcore/async/swc_async_shrink_fifo.vhd b/modules/wrsw_swcore/async/swc_async_shrink_fifo.vhd
deleted file mode 100644
index 8ee4f9a3..00000000
--- a/modules/wrsw_swcore/async/swc_async_shrink_fifo.vhd
+++ /dev/null
@@ -1,122 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.numeric_std.all;
-
-use work.genram_pkg.all;                -- for f_log2_size
-
-entity swc_async_shrink_fifo is
-  
-  generic (
-    g_width : integer;                  -- narrow port width
-    g_ratio : integer;
-    g_size  : integer);
-
-  port (
-    rst_n_i  : in std_logic;
-    clk_wr_i : in std_logic;
-    clk_rd_i : in std_logic;
-
-    we_i : in std_logic;
-    d_i  : in std_logic_vector(g_width*g_ratio-1 downto 0);
-
-    rd_i : in  std_logic;
-    q_o  : out std_logic_vector(g_width-1 downto 0);
-
-    full_o  : out std_logic;
-    empty_o : out std_logic);
-
-end swc_async_shrink_fifo;
-
-architecture rtl of swc_async_shrink_fifo is
-
-  component swc_fifo_mem_cell
-    generic (
-      g_width : integer;
-      g_size  : integer);
-    port (
-      clk_i : in  std_logic;
-      wa_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      wd_i  : in  std_logic_vector(g_width-1 downto 0);
-      we_i  : in  std_logic;
-      ra_i  : in  std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_o  : out std_logic_vector(g_width-1 downto 0));
-  end component;
-
-  component swc_async_fifo_ctrl
-    generic (
-      g_size : integer);
-    port (
-      rst_n_i   : in  std_logic;
-      clk_wr_i  : in  std_logic;
-      clk_rd_i  : in  std_logic;
-      rd_i      : in  std_logic;
-      wr_i      : in  std_logic;
-      wr_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      rd_addr_o : out std_logic_vector(f_log2_size(g_size)-1 downto 0);
-      full_o    : out std_logic;
-      empty_o   : out std_logic);
-  end component;
-
-  signal rd_count         : unsigned(3 downto 0);
-  signal real_rd          : std_logic;
-  signal q_int            : std_logic_vector(g_width*g_ratio-1 downto 0);
-  signal wr_addr, rd_addr : std_logic_vector(f_log2_size(g_size)-1 downto 0);
-  signal empty_int        : std_logic;
-  signal line_flushed     : std_logic;
-begin  -- rtl
-
-  gen_mem_cells : for i in 0 to g_ratio-1 generate
-
-    U_Mem : swc_fifo_mem_cell
-      generic map (
-        g_width => g_width,
-        g_size  => g_size)
-      port map (
-        clk_i => clk_wr_i,
-        wa_i  => wr_addr,
-        wd_i  => d_i(g_width*(i+1) -1 downto g_width*i),
-        we_i  => we_i,
-        ra_i  => rd_addr,
-        rd_o  => q_int(g_width*(i+1) -1 downto g_width*i));
-  end generate gen_mem_cells;
-
-  U_CTRL : swc_async_fifo_ctrl
-    generic map (
-      g_size => g_size)
-    port map (
-      rst_n_i   => rst_n_i,
-      clk_wr_i  => clk_wr_i,
-      clk_rd_i  => clk_rd_i,
-      rd_i      => real_rd,
-      wr_i      => we_i,
-      wr_addr_o => wr_addr,
-      rd_addr_o => rd_addr,
-      full_o    => full_o,
-      empty_o   => empty_int);
-
-  p_read_mux : process(clk_rd_i, rst_n_i)
-  begin
-    if rst_n_i = '0' then
-      rd_count <= (others => '0');
-      q_o      <= (others => '0');
-    elsif rising_edge(clk_rd_i) then
-      if(rd_i = '1' and empty_int = '0') then
-        if(rd_count = g_ratio-1) then
-          rd_count <= (others => '0');
-        else
-          rd_count <= rd_count + 1;
-        end if;
-
-        q_o <= q_int(((to_integer(rd_count)+1)*g_width)-1 downto to_integer(rd_count)*g_width);
-      end if;
-      
-    end if;
-  end process;
-
-
-  line_flushed <= '1' when (rd_count = g_ratio-1) else '0';
-  real_rd      <= line_flushed and rd_i;
-
-  empty_o <= empty_int and line_flushed;
-  
-end rtl;
diff --git a/modules/wrsw_swcore/async/swc_private_pkg.vhd b/modules/wrsw_swcore/async/swc_private_pkg.vhd
deleted file mode 100644
index 1467c278..00000000
--- a/modules/wrsw_swcore/async/swc_private_pkg.vhd
+++ /dev/null
@@ -1,50 +0,0 @@
-library ieee;
-use ieee.std_logic_1164.all;
-
-package swc_private_pkg is
-
-  constant c_data_path_width      : integer                                        := 18;
-  constant c_eof_marker           : std_logic_vector(c_data_path_width-1 downto 0) := "11XXXXXXXXXXXXXXXX";
-  constant c_mpm_async_fifo_depth : integer                                        := 8;
-  constant c_page_addr_width      : integer                                        := 12;
-
-  type t_generic_slv_array is array (integer range <>, integer range <>) of std_logic;
-
-  type t_mpm_write_in is record
-    d        : std_logic_vector(c_data_path_width-1 downto 0);
-    d_valid  : std_logic;
-    d_eof    : std_logic;
-    pg_addr  : std_logic_vector(c_page_addr_width-1 downto 0);
-    pg_valid : std_logic;
-  end record;
-
-  type t_mpm_write_out is record
-    d_req  : std_logic;
-    pg_req : std_logic;
-  end record;
-
-  type t_mpm_write_in_array is array (integer range <>) of t_mpm_write_in;
-  type t_mpm_write_out_array is array (integer range <>) of t_mpm_write_out;
-
-
-  type t_mpm_read_out is record
-    d       : std_logic_vector(c_data_path_width-1 downto 0);
-    d_valid : std_logic;
-    d_eof   : std_logic;
-    pg_req  : std_logic;
-  end record;
-
-  type t_mpm_read_in is record
-    pg_addr  : std_logic_vector(c_page_addr_width-1 downto 0);
-    pg_valid : std_logic;
-    d_req    : std_logic;
-  end record;
-
-  type t_mpm_read_in_array is array (integer range <>) of t_mpm_read_in;
-  type t_mpm_read_out_array is array (integer range <>) of t_mpm_read_out;
-
-  
-  
-  
-
-end swc_private_pkg;
diff --git a/modules/wrsw_swcore/async/swc_swcore_pkg.vhd b/modules/wrsw_swcore/async/swc_swcore_pkg.vhd
deleted file mode 100644
index b20c8917..00000000
--- a/modules/wrsw_swcore/async/swc_swcore_pkg.vhd
+++ /dev/null
@@ -1,540 +0,0 @@
--------------------------------------------------------------------------------
--- Title      : Switching Core Package
--- Project    : WhiteRabbit switch
--------------------------------------------------------------------------------
--- File       : swc_swcore_pkg.vhd
--- Author     : Tomasz Wlostowski
--- Company    : CERN BE-Co-HT
--- Created    : 2010-04-08
--- Last update: 2011-12-15
--- Platform   : FPGA-generic
--- Standard   : VHDL'87
--------------------------------------------------------------------------------
--- Description: 
--------------------------------------------------------------------------------
---
--- Copyright (c) 2010 Tomasz Wlostowski, Maciej Lipinski / CERN
---
--- This source file is free software; you can redistribute it   
--- and/or modify it under the terms of the GNU Lesser General   
--- Public License as published by the Free Software Foundation; 
--- either version 2.1 of the License, or (at your option) any   
--- later version.                                               
---
--- This source is distributed in the hope that it will be       
--- useful, but WITHOUT ANY WARRANTY; without even the implied   
--- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
--- PURPOSE.  See the GNU Lesser General Public License for more 
--- details.                                                     
---
--- You should have received a copy of the GNU Lesser General    
--- Public License along with this source; if not, download it   
--- from http://www.gnu.org/licenses/lgpl-2.1.html
---
--------------------------------------------------------------------------------
--- Revisions  :
--- Date        Version  Author   Description
--- 2010-04-08  1.0      twlostow Created
--- 2010-11-22  2.0      mlipinsk added staff
--------------------------------------------------------------------------------
-
-library ieee;
-use ieee.std_logic_1164.all;
-use ieee.math_real.CEIL;
-use ieee.math_real.log2;
-
-package swc_swcore_pkg is
-
-  type t_swcore_gen_parameters is record
-    num_ports: integer;
-    mem_pages: integer;
-    page_size: integer;
-    
-  end record;
-  
-
--- number of switch ports
-  constant c_swc_num_ports       : integer := 11;
--- size of the packet memory in words (1 word = 1 ctrl + data sequence)
-  constant c_swc_packet_mem_size : integer := 65536;
-
-  constant c_swc_packet_mem_multiply : integer := 16;
-  constant c_swc_data_width          : integer := 16;
-  constant c_swc_ctrl_width          : integer := 4; --16;
-  constant c_swc_page_size           : integer := 64;
-
-
-  constant c_swc_output_prio_num     : integer := 8;
-  
-  constant c_swc_max_pck_size        : integer := 10 * 1024; -- 10 kB
-  
-
-  -- 
-  constant c_swc_input_fifo_size            : integer := 2 * c_swc_packet_mem_multiply;
-  constant c_swc_input_fifo_size_log2  : integer := integer(CEIL(LOG2(real(c_swc_input_fifo_size - 1))));
-  constant c_swc_fifo_full_in_advance  : integer := c_swc_input_fifo_size - 3;
-  
-  constant c_swc_num_ports_width       : integer := integer(CEIL(LOG2(real(c_swc_num_ports-1))));
-  constant c_swc_packet_mem_num_pages  : integer := (c_swc_packet_mem_size / c_swc_page_size); -- 65536/64 = 1024
-
-  constant c_swc_output_fifo_size      : integer := 64; --old value: 16;
-
-  constant c_swc_freeing_fifo_size     : integer := (c_swc_packet_mem_num_pages/2);
-  constant c_swc_freeing_fifo_log2     : integer := integer(CEIL(LOG2(real(c_swc_freeing_fifo_size-1))));
-  
-  constant c_swc_page_addr_width       : integer := integer(CEIL(LOG2(real(c_swc_packet_mem_num_pages-1))));
-  constant c_swc_usecount_width        : integer := integer(CEIL(LOG2(real(c_swc_num_ports-1))));
-  constant c_swc_page_offset_width     : integer := integer(CEIL(LOG2(real(c_swc_page_size / c_swc_packet_mem_multiply))));
-  constant c_swc_packet_mem_addr_width : integer := c_swc_page_addr_width + c_swc_page_offset_width;
-  constant c_swc_pump_width            : integer := c_swc_data_width + c_swc_ctrl_width;
-
-  constant c_swc_output_fifo_addr_width : integer := integer(CEIL(LOG2(real(c_swc_output_fifo_size-1))));
-  constant c_swc_output_prio_num_width  : integer := integer(CEIL(LOG2(real(c_swc_output_prio_num -1)))); 
-  
-  constant c_swc_max_pck_size_width     : integer := integer(CEIL(LOG2(real(c_swc_max_pck_size -1))));-- 14 bits
-
-  -- TODO: probably need later to use the global constant
-  constant c_swc_prio_width : integer := 3;
-
-  type t_slv_array is array(integer range <>, integer range <>) of std_logic;
-
--- type declarations for memory input/output registers in data pump
-  subtype t_pump_entry is std_logic_vector(c_swc_pump_width-1 downto 0);
-  type t_pump_reg is array (c_swc_packet_mem_multiply-1 downto 0) of t_pump_entry;
-
-  component swc_prio_encoder
-    generic (
-      g_num_inputs  : integer range 2 to 64;
-      g_output_bits : integer range 1 to 6);
-    port (
-      in_i     : in  std_logic_vector(g_num_inputs-1 downto 0);
-      out_o    : out std_logic_vector(g_output_bits-1 downto 0);
-      onehot_o : out std_logic_vector(g_num_inputs-1 downto 0);
-      mask_o   : out std_logic_vector(g_num_inputs-1 downto 0);
-      zero_o   : out std_logic);
-  end component;
-
-  component swc_page_allocator
-    generic (
-      g_num_pages      : integer;
-      g_page_addr_bits : integer;
-      g_use_count_bits : integer);
-    port (
-      clk_i          : in  std_logic;
-      rst_n_i        : in  std_logic;
-      alloc_i        : in  std_logic;
-      free_i         : in  std_logic;
-      force_free_i   : in std_logic;
-      set_usecnt_i   : in std_logic;
-      usecnt_i       : in  std_logic_vector(g_use_count_bits-1 downto 0);
-      pgaddr_i       : in  std_logic_vector(g_page_addr_bits -1 downto 0);
-      pgaddr_o       : out std_logic_vector(g_page_addr_bits -1 downto 0);
-      pgaddr_valid_o : out std_logic;
-      idle_o         : out std_logic;
-      done_o         : out std_logic;
-      nomem_o        : out std_logic);
-  end component;
-
-  component swc_rr_arbiter
-    generic (
-      g_num_ports      : natural;
-      g_num_ports_log2 : natural);
-    port (
-      rst_n_i       : in  std_logic;
-      clk_i         : in  std_logic;
-      next_i        : in  std_logic;
-      request_i     : in  std_logic_vector(g_num_ports -1 downto 0);
-      grant_o       : out std_logic_vector(g_num_ports_log2 - 1 downto 0);
-      grant_valid_o : out std_logic);
-  end component;
-
-  component swc_packet_mem_write_pump
-    port (
-      clk_i               : in  std_logic;
-      rst_n_i             : in  std_logic;
-      pgaddr_i            : in  std_logic_vector(c_swc_page_addr_width-1 downto 0);
-      pgreq_i             : in  std_logic;
-      pgend_o             : out std_logic;
-      pckstart_i          : in std_logic;
-      drdy_i              : in  std_logic;
-      full_o              : out std_logic;
-      flush_i             : in  std_logic;
-      ll_addr_o           : out std_logic_vector(c_swc_page_addr_width -1 downto 0);
-      ll_data_o           : out std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      ll_wr_req_o         : out std_logic;
-      ll_wr_done_i        : in std_logic;
-      sync_i              : in  std_logic;
-      addr_o              : out std_logic_vector(c_swc_packet_mem_addr_width -1 downto 0);
-      d_i                 : in  std_logic_vector(c_swc_pump_width -1 downto 0);
-      q_o                 : out std_logic_vector(c_swc_pump_width * c_swc_packet_mem_multiply - 1 downto 0);
-      we_o                : out std_logic);
-  end component;
-
-  component swc_packet_mem_read_pump
-    port (
-      clk_i               : in  std_logic;
-      rst_n_i             : in  std_logic;
-      pgreq_i             : in  std_logic;
-      pgaddr_i            : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      pgend_o             : out std_logic;
-      pckend_o            : out std_logic;
-      drdy_o              : out std_logic;
-      dreq_i              : in  std_logic;
-      sync_read_i         : in  std_logic;
-      ll_read_addr_o      : out std_logic_vector(c_swc_page_addr_width -1 downto 0);
-      ll_read_data_i      : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      ll_read_req_o       : out std_logic;
-      ll_read_valid_data_i: in  std_logic;
-      sync_i              : in  std_logic;
-      d_o                 : out std_logic_vector(c_swc_pump_width - 1 downto 0);
-      addr_o              : out std_logic_vector(c_swc_packet_mem_addr_width - 1 downto 0);
-      q_i                 : in  std_logic_vector(c_swc_pump_width * c_swc_packet_mem_multiply -1 downto 0));
-  end component;
-  
-  component swc_multiport_linked_list is
-    port (
-      rst_n_i               : in  std_logic;
-      clk_i                 : in  std_logic;
-
-      write_i               : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      write_done_o          : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      write_addr_i          : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      write_data_i          : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      
-      
-      free_i                : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_done_o           : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_addr_i           : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      
-      
-      read_pump_read_i      : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      read_pump_read_done_o : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      read_pump_addr_i      : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-            
-      free_pck_read_i       : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_pck_read_done_o  : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_pck_addr_i       : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      
-      data_o                : out std_logic_vector(c_swc_page_addr_width - 1 downto 0)
-      );
-  
-  end component;
-  
-  component swc_input_block is
-    port (
-      clk_i   : in std_logic;
-      rst_n_i : in std_logic;
-  -------------------------------------------------------------------------------
-  -- Fabric I/F  
-  ------------------------------------------------------------------------------
-      tx_sof_p1_i   : in  std_logic;
-      tx_eof_p1_i   : in  std_logic;
-      tx_data_i     : in  std_logic_vector(c_swc_data_width - 1 downto 0);
-      tx_ctrl_i     : in  std_logic_vector(c_swc_ctrl_width - 1 downto 0);
-      tx_valid_i    : in  std_logic;
-      tx_bytesel_i  : in  std_logic;
-      tx_dreq_o     : out std_logic;
-      tx_abort_p1_i : in  std_logic;
-      tx_rerror_p1_i : in  std_logic;
-  -------------------------------------------------------------------------------
-  -- I/F with Page allocator (MMU)
-  -------------------------------------------------------------------------------    
-      mmu_page_alloc_req_o  : out  std_logic;
-      mmu_page_alloc_done_i : in std_logic;
-      mmu_pageaddr_i : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      mmu_pageaddr_o : out  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      mmu_force_free_o   : out std_logic;
-      mmu_force_free_done_i : in std_logic;
-      mmu_force_free_addr_o : out std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      mmu_set_usecnt_o   : out std_logic;
-      mmu_set_usecnt_done_i  : in  std_logic;
-      mmu_usecnt_o       : out  std_logic_vector(c_swc_usecount_width - 1 downto 0);
-      mmu_nomem_i         : in std_logic;
-  -------------------------------------------------------------------------------
-  -- I/F with Routing Table Unit (RTU)
-  -------------------------------------------------------------------------------      
-      rtu_rsp_valid_i     : in std_logic;
-      rtu_rsp_ack_o       : out std_logic;
-      rtu_dst_port_mask_i : in std_logic_vector(c_swc_num_ports  - 1 downto 0);
-      rtu_drop_i          : in std_logic;
-      rtu_prio_i          : in std_logic_vector(c_swc_prio_width - 1 downto 0);
-  -------------------------------------------------------------------------------
-  -- I/F with Multiport Memory (MPU)
-  -------------------------------------------------------------------------------    
-      mpm_pckstart_o : out  std_logic;
-      mpm_pageaddr_o : out  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      mpm_pagereq_o : out std_logic;
-      mpm_pageend_i  : in std_logic;
-      mpm_data_o  : out  std_logic_vector(c_swc_data_width - 1 downto 0);
-      mpm_ctrl_o  : out  std_logic_vector(c_swc_ctrl_width - 1 downto 0);
-      mpm_drdy_o  : out  std_logic;
-      mpm_full_i  : in std_logic;
-      mpm_flush_o : out  std_logic;  
-      mpm_wr_sync_i : in  std_logic; 
-  -------------------------------------------------------------------------------
-  -- I/F with Page Transfer Arbiter (PTA)
-  -------------------------------------------------------------------------------     
-      pta_transfer_pck_o : out  std_logic;
-      pta_transfer_ack_i : in   std_logic;
-      pta_pageaddr_o : out  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      pta_mask_o     : out  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      pta_pck_size_o : out  std_logic_vector(c_swc_max_pck_size_width - 1 downto 0);
-      pta_prio_o     : out  std_logic_vector(c_swc_prio_width - 1 downto 0)
-      
-      );
-  end component;
-  
-  
-  component swc_multiport_page_allocator is
-    port (
-      rst_n_i             : in std_logic;
-      clk_i               : in std_logic;
-      alloc_i             : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_i              : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      force_free_i        : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      set_usecnt_i        : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      alloc_done_o        : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      free_done_o         : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      force_free_done_o   : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      set_usecnt_done_o   : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      pgaddr_free_i       : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      pgaddr_force_free_i : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      pgaddr_usecnt_i     : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      usecnt_i            : in  std_logic_vector(c_swc_num_ports * c_swc_usecount_width - 1 downto 0);
-      pgaddr_alloc_o      : out std_logic_vector(c_swc_page_addr_width-1 downto 0);
-      nomem_o             : out std_logic
-      );
-  
-  end component;
-  
-  component swc_packet_mem is
-    port (
-      clk_i   : in std_logic;
-      rst_n_i : in std_logic;
-      ------------------- writing to the shared memory --------------------------
-      wr_pagereq_i  : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-      wr_pckstart_i : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-      wr_pageaddr_i : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      wr_pageend_o  : out std_logic_vector(c_swc_num_ports -1 downto 0);
-      wr_ctrl_i  : in  std_logic_vector(c_swc_num_ports * c_swc_ctrl_width - 1 downto 0);
-      wr_data_i  : in  std_logic_vector(c_swc_num_ports * c_swc_data_width - 1 downto 0);
-      wr_drdy_i  : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-      wr_full_o  : out std_logic_vector(c_swc_num_ports-1 downto 0);
-      wr_flush_i : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-      wr_sync_o : out std_logic_vector(c_swc_num_ports -1 downto 0);
-      ------------------- reading from the shared memory --------------------------
-      rd_pagereq_i   : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-      rd_pageaddr_i  : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      rd_pageend_o   : out std_logic_vector(c_swc_num_ports -1 downto 0);
-      rd_pckend_o    : out  std_logic_vector(c_swc_num_ports-1 downto 0);
-      rd_drdy_o      : out std_logic_vector(c_swc_num_ports -1 downto 0);
-      rd_dreq_i      : in  std_logic_vector(c_swc_num_ports -1 downto 0);
-      rd_sync_read_i : in std_logic_vector(c_swc_num_ports -1 downto 0);
-      rd_data_o      : out std_logic_vector(c_swc_num_ports * c_swc_data_width - 1 downto 0);
-      rd_ctrl_o      : out std_logic_vector(c_swc_num_ports * c_swc_ctrl_width - 1 downto 0);
-      rd_sync_o      : out std_logic_vector(c_swc_num_ports -1 downto 0);
---      pa_free_o              : out  std_logic_vector(c_swc_num_ports -1 downto 0);
---      pa_free_done_i         : in   std_logic_vector(c_swc_num_ports -1 downto 0);
---      pa_free_pgaddr_o       : out  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      
-      write_o               : out  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      write_done_i          : in   std_logic_vector(c_swc_num_ports - 1 downto 0);
-      write_addr_o          : out  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      write_data_o          : out  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      read_pump_read_o      : out  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      read_pump_read_done_i : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      read_pump_addr_o      : out  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-      data_i                : in   std_logic_vector(c_swc_page_addr_width - 1 downto 0)
-      );
-      
-    end component;
-  
-  
-  component swc_pck_transfer_input is
-    port (
-      clk_i              : in std_logic;
-      rst_n_i            : in std_logic;
-      
-      pto_transfer_pck_o : out  std_logic;
-      pto_pageaddr_o     : out  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      pto_output_mask_o  : out  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      pto_read_mask_i    : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      pto_prio_o         : out  std_logic_vector(c_swc_prio_width - 1 downto 0);
-      pto_pck_size_o     : out  std_logic_vector(c_swc_max_pck_size_width - 1 downto 0);
-      
-      ib_transfer_pck_i  : in  std_logic;
-      ib_pageaddr_i      : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      ib_mask_i          : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      ib_prio_i          : in  std_logic_vector(c_swc_prio_width - 1 downto 0);
-      ib_pck_size_i      : in  std_logic_vector(c_swc_max_pck_size_width - 1 downto 0);
-      ib_transfer_ack_o  : out std_logic;
-      ib_busy_o          : out std_logic
-      
-      );
-  end component;  
-  
-  
-  component swc_pck_transfer_output is
-    port (
-      clk_i                    : in  std_logic;
-      rst_n_i                  : in  std_logic;
-      
-      ob_transfer_data_valid_o : out std_logic;
-      ob_pageaddr_o            : out std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      ob_prio_o                : out std_logic_vector(c_swc_prio_width - 1 downto 0);
-      ob_pck_size_o            : out std_logic_vector(c_swc_max_pck_size_width - 1 downto 0);
-      ob_transfer_data_ack_i   : in  std_logic;
-      
-      pti_transfer_data_valid_i: in  std_logic;
-      pti_transfer_data_ack_o  : out std_logic;
-      pti_pageaddr_i           : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      pti_prio_i               : in  std_logic_vector(c_swc_prio_width - 1 downto 0);
-      pti_pck_size_i           : in  std_logic_vector(c_swc_max_pck_size_width - 1 downto 0)
-      
-      );
-  end component;
-  
-  component swc_pck_transfer_arbiter is
-    port (
-      clk_i              : in  std_logic;
-      rst_n_i            : in  std_logic;
-      
-      ob_data_valid_o    : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      ob_ack_i           : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      ob_pageaddr_o      : out std_logic_vector(c_swc_num_ports * c_swc_page_addr_width    - 1 downto 0);
-      ob_prio_o          : out std_logic_vector(c_swc_num_ports * c_swc_prio_width         - 1 downto 0);
-      ob_pck_size_o      : out std_logic_vector(c_swc_num_ports * c_swc_max_pck_size_width - 1 downto 0);
-      
-      ib_transfer_pck_i  : in  std_logic_vector(c_swc_num_ports - 1 downto 0);
-      ib_transfer_ack_o  : out std_logic_vector(c_swc_num_ports - 1 downto 0);
-      ib_busy_o          : out std_logic_vector(c_swc_num_ports - 1 downto 0);  
-      ib_pageaddr_i      : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width    - 1 downto 0);
-      ib_mask_i          : in  std_logic_vector(c_swc_num_ports * c_swc_num_ports          - 1 downto 0);
-      ib_prio_i          : in  std_logic_vector(c_swc_num_ports * c_swc_prio_width         - 1 downto 0);
-      ib_pck_size_i      : in  std_logic_vector(c_swc_num_ports * c_swc_max_pck_size_width - 1 downto 0)
-      );  
-  end component;
-  
-  component swc_ob_prio_queue is
-    port (
-      clk_i             : in   std_logic;
-      rst_n_i           : in   std_logic;
-      write_i           : in   std_logic;
-      read_i            : in   std_logic;
-      not_full_o        : out  std_logic;
-      not_empty_o       : out  std_logic;
-      wr_en_o           : out  std_logic;
-      wr_addr_o         : out  std_logic_vector(c_swc_output_fifo_addr_width - 1 downto 0);
-      rd_addr_o         : out  std_logic_vector(c_swc_output_fifo_addr_width - 1 downto 0)
-      );
-  end component;
-  
-  component swc_output_block is
-    port (
-      clk_i                     : in std_logic;
-      rst_n_i                   : in std_logic;
-      pta_transfer_data_valid_i : in   std_logic;
-      pta_pageaddr_i            : in   std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      pta_prio_i                : in   std_logic_vector(c_swc_prio_width - 1 downto 0);
-      pta_pck_size_i            : in   std_logic_vector(c_swc_max_pck_size_width - 1 downto 0);
-      pta_transfer_data_ack_o   : out  std_logic;
-      mpm_pgreq_o               : out std_logic;
-      mpm_pgaddr_o              : out std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      mpm_pckend_i              : in  std_logic;
-      mpm_pgend_i               : in  std_logic;
-      mpm_drdy_i                : in  std_logic;
-      mpm_dreq_o                : out std_logic;
-      mpm_data_i                : in  std_logic_vector(c_swc_data_width - 1 downto 0);
-      mpm_ctrl_i                : in  std_logic_vector(c_swc_ctrl_width - 1 downto 0); 
-      mpm_sync_i                : in  std_logic;
-      ppfm_free_o            : out  std_logic;
-      ppfm_free_done_i       : in   std_logic;
-      ppfm_free_pgaddr_o     : out  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      rx_sof_p1_o               : out std_logic;
-      rx_eof_p1_o               : out std_logic;
-      rx_dreq_i                 : in  std_logic;
-      rx_ctrl_o                 : out std_logic_vector(c_swc_ctrl_width - 1 downto 0);
-      rx_data_o                 : out std_logic_vector(c_swc_data_width - 1 downto 0);
-      rx_valid_o                : out std_logic;
-      rx_bytesel_o              : out std_logic;
-      rx_idle_o                 : out std_logic;
-      rx_rerror_p1_o            : out std_logic;
-      rx_terror_p1_i            : in  std_logic;
-      rx_tabort_p1_i            : in  std_logic
-      );  
-  end component;
-
-component  swc_multiport_pck_pg_free_module is
-  port (
-    clk_i   : in std_logic;
-    rst_n_i : in std_logic;
-
-    ib_force_free_i         : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-    ib_force_free_done_o    : out std_logic_vector(c_swc_num_ports-1 downto 0);
-    ib_force_free_pgaddr_i  : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-
-    ob_free_i               : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-    ob_free_done_o          : out std_logic_vector(c_swc_num_ports-1 downto 0);
-    ob_free_pgaddr_i        : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-    
-    ll_read_addr_o          : out std_logic_vector(c_swc_num_ports * c_swc_page_addr_width -1 downto 0);
-    --ll_read_data_i          : in  std_logic_vector(c_swc_num_ports * c_swc_page_addr_width - 1 downto 0);
-    ll_read_data_i          : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-    ll_read_req_o           : out std_logic_vector(c_swc_num_ports-1 downto 0);
-    ll_read_valid_data_i    : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-
-    mmu_free_o              : out std_logic_vector(c_swc_num_ports-1 downto 0);
-    mmu_free_done_i         : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-    mmu_free_pgaddr_o       : out std_logic_vector(c_swc_num_ports * c_swc_page_addr_width -1 downto 0);
-    
-    mmu_force_free_o        : out std_logic_vector(c_swc_num_ports-1 downto 0);
-    mmu_force_free_done_i   : in  std_logic_vector(c_swc_num_ports-1 downto 0);
-    mmu_force_free_pgaddr_o : out std_logic_vector(c_swc_num_ports * c_swc_page_addr_width -1 downto 0)
-    );
- end component;
-  
-
-  component swc_pck_pg_free_module is
-  
-    port (
-      clk_i   : in std_logic;
-      rst_n_i : in std_logic;
-  
-      ib_force_free_i         : in  std_logic;
-      ib_force_free_done_o    : out std_logic;
-      ib_force_free_pgaddr_i  : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-  
-      ob_free_i               : in  std_logic;
-      ob_free_done_o          : out std_logic;
-      ob_free_pgaddr_i        : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      
-      ll_read_addr_o          : out std_logic_vector(c_swc_page_addr_width -1 downto 0);
-      ll_read_data_i          : in  std_logic_vector(c_swc_page_addr_width - 1 downto 0);
-      ll_read_req_o           : out std_logic;
-      ll_read_valid_data_i    : in  std_logic;
-  
-      mmu_free_o              : out std_logic;
-      mmu_free_done_i         : in  std_logic;
-      mmu_free_pgaddr_o       : out std_logic_vector(c_swc_page_addr_width -1 downto 0);
-          
-      mmu_force_free_o        : out std_logic;
-      mmu_force_free_done_i   : in  std_logic;
-      mmu_force_free_pgaddr_o : out std_logic_vector(c_swc_page_addr_width -1 downto 0)
-  
-         
-      );
-  end component;
-  
-end swc_swcore_pkg;
-
-
-
-
-
-
-package body swc_swcore_pkg is
-
-
-
-
-end swc_swcore_pkg;
-- 
GitLab