diff --git a/ips/hw/scalp_router/src/hdl/scalp_axis_to_sp.vhd b/ips/hw/scalp_router/src/hdl/scalp_axis_to_sp.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..005d0a27c94ffd25fa6d0c11802955cc1540cf95
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_axis_to_sp.vhd
@@ -0,0 +1,259 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_axis_to_sp.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: AXI Stream to Scalp Packet converter.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+-- 31      23      15      7       0
+--  0       7      15     23      31
+--     8       8       8       8
+-- ---------------------------------
+-- | x_dst | y_dst | z_dst | type  |
+-- ---------------------------------
+-- | x_src | y_srd | z_src |  pad  |
+-- ---------------------------------
+--        16              16
+-- ---------------------------------
+-- | payload_size  |     pad       |
+-- ---------------------------------
+--
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+--                .
+--                .
+--                .
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+
+-- Register map
+--
+-- 31                              0
+-- ---------------------------------
+-- |             H0                | Dst addr + Type
+-- ---------------------------------
+-- ---------------------------------
+-- |             H1                | Src addr + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |             H2                | Pld size + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |              P                | N x Payload
+-- ---------------------------------
+
+entity scalp_axis_to_sp is
+
+    generic (
+        C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+        C_SCALP_RANDOM_READY        : boolean                                              := true);
+
+    port (
+        -- Sys clk and sys nrst
+        SysClkxCI           : in  std_ulogic;
+        SysRstxRNAI         : in  std_ulogic;
+        -- Axis
+        ScalpAxism2sxDI     : in  t_axi4m2s;
+        ScalpAxiss2mxDO     : out t_axi4s2m;
+        -- Scalp Packet
+        ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+        ScalpPacketValidxSO : out std_ulogic);
+
+end entity scalp_axis_to_sp;
+
+architecture behavioral of scalp_axis_to_sp is
+
+    signal ScalpAxism2sxD      : t_axi4m2s                                            := C_NO_AXI4_M2S;
+    signal ScalpAxiss2mxD      : t_axi4s2m                                            := C_NO_AXI4_S2M;
+    signal ScalpPacketStatexDP : t_scalp_packet_states                                := E_SP_IDLE;
+    signal ScalpPacketStatexDN : t_scalp_packet_states                                := E_SP_IDLE;
+    signal ScalpPacketCntxDP   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 0;
+    signal ScalpPacketCntxDN   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 0;
+    signal ScalpPacketValidxSP : std_ulogic                                           := '0';
+    signal ScalpPacketValidxSN : std_ulogic                                           := '0';
+    signal ScalpPacketH0xDP    : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))      := (others => '0');
+    signal ScalpPacketH0xDN    : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))      := (others => '0');
+    signal ScalpPacketH1xDP    : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))      := (others => '0');
+    signal ScalpPacketH1xDN    : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))      := (others => '0');
+    signal ScalpPacketxD       : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)))
+        := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+            SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal RandNumxD : integer    := 0;
+    signal ReadyxS   : std_ulogic := '1';
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        ScalpPacketxAS      : ScalpPacketxDO      <= ScalpPacketxD;
+        ScalpPacketValidxAS : ScalpPacketValidxSO <= ScalpPacketValidxSP;
+        ScalpAxism2sxAS     : ScalpAxism2sxD      <= ScalpAxism2sxDI;
+        ScalpAxiss2mxAS     : ScalpAxiss2mxDO     <= ScalpAxiss2mxD;
+    end block EntityIOxB;
+
+    RandomReadyxP : process is
+        variable SeedB1xD        : integer := 999;
+        variable SeedB2xD        : integer := 999;
+        variable MinCyclesxD     : integer := 1;
+        variable MaxCyclesxD     : integer := 3;
+        variable WaitingCyclesxD : integer := 0;
+        variable MinValRealxD    : real    := 0.0;
+        variable MaxValReadxD    : real    := 1.0;
+        variable RandomValuexD   : real    := 0.0;
+        variable ThresholdxD     : real    := 0.3;
+        variable RandxD          : real    := 0.0;
+
+        -- Random Integer Value
+        impure function scalp_rand_int (
+            MinValxD : integer;
+            MaxValxD : integer)
+            return integer is
+            variable RandxD : real;
+        begin  -- function scalp_rand_int
+            uniform(SeedB1xD, SeedB2xD, RandxD);
+            return integer(round(RandxD * real(MaxValxD - MinValxD + 1) + real(MinValxD) - 0.5));
+        end function scalp_rand_int;
+
+        -- Random Real Value
+        impure function scalp_rand_real (
+            MinValxD : real;
+            MaxValxD : real)
+            return real is
+            variable RandxD : real;
+        begin  -- function scalp_rand_real
+            uniform(SeedB1xD, SeedB2xD, RandxD);
+            return RandxD * (MaxValxD - MinValxD) + MinValxD;
+        end function scalp_rand_real;
+
+    begin  -- process RandomReadyxP
+        -- Axis ReadyxS Default Value
+        ScalpAxiss2mxD.ReadyxS <= '1';
+        ReadyxS                <= '1';
+
+        if C_SCALP_RANDOM_READY = true then
+            RandomValuexD := scalp_rand_real(MinValRealxD, MaxValReadxD);
+
+            if RandomValuexD < ThresholdxD then
+                ScalpAxiss2mxD.ReadyxS <= '0';
+                ReadyxS                <= '0';
+            else
+                ScalpAxiss2mxD.ReadyxS <= '1';
+                ReadyxS                <= '1';
+            end if;
+        end if;
+
+        WaitingCyclesxD := scalp_rand_int(MinCyclesxD, MaxCyclesxD);
+
+        for i in 0 to (WaitingCyclesxD - 1) loop
+            wait until rising_edge(SysClkxCI);
+        end loop;  -- i
+    end process RandomReadyxP;
+
+    StateMachineUpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process StateMachineUpdateRegxP
+        if SysRstxRNAI = '0' then
+            ScalpPacketStatexDP <= E_SP_H0;
+            ScalpPacketCntxDP   <= 0;
+            ScalpPacketValidxSP <= '0';
+            ScalpPacketH0xDP    <= (others => '0');
+            ScalpPacketH1xDP    <= (others => '0');
+        elsif rising_edge(SysClkxCI) then
+            ScalpPacketStatexDP <= ScalpPacketStatexDN;
+            ScalpPacketCntxDP   <= ScalpPacketCntxDN;
+            ScalpPacketValidxSP <= ScalpPacketValidxSN;
+            ScalpPacketH0xDP    <= ScalpPacketH0xDN;
+            ScalpPacketH1xDP    <= ScalpPacketH1xDN;
+        end if;
+    end process StateMachineUpdateRegxP;
+
+    AxisToSpOutAndStatesCombinatoricxP : process (ReadyxS,
+                                                  ScalpAxism2sxD.DataxD,
+                                                  ScalpAxism2sxD.LastxS,
+                                                  ScalpAxism2sxD.ValidxS,
+                                                  ScalpPacketCntxDP,
+                                                  ScalpPacketH0xDP,
+                                                  ScalpPacketH1xDP,
+                                                  ScalpPacketStatexDP,
+                                                  ScalpPacketValidxSP) is
+    begin  -- process AxisToSpOutAndStatesCombinatoricxP
+        -- Default values
+        -- State and counter
+        ScalpPacketStatexDN <= ScalpPacketStatexDP;
+        ScalpPacketCntxDN   <= ScalpPacketCntxDP;
+        -- Scalp Packet Header
+        ScalpPacketH0xDN    <= ScalpPacketH0xDP;
+        ScalpPacketH1xDN    <= ScalpPacketH1xDP;
+        -- Scalp Packet
+        ScalpPacketValidxSN <= ScalpPacketValidxSP;
+
+        case ScalpPacketStatexDP is
+            when E_SP_H0 =>
+                    ScalpPacketCntxDN   <= 0;
+                    ScalpPacketH0xDN    <= (others => '0');
+                    ScalpPacketH1xDN    <= (others => '0');
+                    ScalpPacketValidxSN <= '0';
+
+                    if ScalpAxism2sxD.ValidxS = '1' and ReadyxS = '1' then
+                        ScalpPacketValidxSN <= '0';
+                        ScalpPacketH0xDN    <= ScalpAxism2sxD.DataxD;
+                        ScalpPacketStatexDN <= E_SP_H1;
+                    end if;
+            when E_SP_H1 =>
+                    if ScalpAxism2sxD.ValidxS = '1' and ReadyxS = '1' then
+                        ScalpPacketH1xDN    <= ScalpAxism2sxD.DataxD;
+                        ScalpPacketStatexDN <= E_SP_H2;
+                    end if;
+            when E_SP_H2 =>
+                    if ScalpAxism2sxD.ValidxS = '1' and ReadyxS = '1' then
+                        ScalpPacketxD.SpHeaderxD
+                            <= scalp_axis_to_sp_header_ul(ScalpPacketH0xDP, ScalpPacketH1xDP, ScalpAxism2sxD.DataxD);
+                        ScalpPacketStatexDN <= E_SP_P;
+                    end if;
+            when E_SP_P =>
+                    if ScalpAxism2sxD.ValidxS = '1' and ReadyxS = '1' then
+                        ScalpPacketxD.SpPayloadxD(ScalpPacketCntxDP)
+                            <= scalp_axis_to_sp_word_ul(ScalpAxism2sxD.DataxD, ScalpPacketCntxDP);
+                        ScalpPacketCntxDN <= ScalpPacketCntxDP + 1;
+
+                        if ScalpAxism2sxD.LastxS = '1' then
+                            ScalpPacketValidxSN <= '1';
+                            ScalpPacketStatexDN <= E_SP_H0;
+                        end if;
+                    end if;
+            when others => null;
+        end case;
+    end process AxisToSpOutAndStatesCombinatoricxP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_booking_vector.vhd b/ips/hw/scalp_router/src/hdl/scalp_booking_vector.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..c93f76bc8cd50aa7951b63413498c77458b1891a
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_booking_vector.vhd
@@ -0,0 +1,117 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_booking_vector.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Manage the booking vector.
+--
+-- Last update: 2020-02-13
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.scalp_misc.all;
+
+entity scalp_booking_vector is
+
+    generic (
+        C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255 := 7;
+        C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255 := 6;
+        C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255 := 1);
+
+    port (
+        SysClkxCI             : in  std_ulogic;
+        SysRstxRNAI           : in  std_ulogic;
+        IfDstIdxxDI           : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+        IfDstIdxValidxSI      : in  std_ulogic;
+        SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+        BookingVectorxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        BookingVectorValidxSO : out std_ulogic);
+
+end entity scalp_booking_vector;
+
+architecture behavioral of scalp_booking_vector is
+
+    signal IfDstIdxValidxS            : std_ulogic                                                          := '0';
+    signal IfDstIdxxD                 : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal SchedulerAckxD             : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal BookingVectorxDP           : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal BookingVectorxDN           : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal BookingVectorValidxS       : std_ulogic                                                          := '0';
+    -- Booking vector state signals
+    signal ScalpBookingVectorStatexDP : t_scalp_booking_vector_states                                       := E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK;
+    signal ScalpBookingVectorStatexDN : t_scalp_booking_vector_states                                       := E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK;
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        IfDstIdxxAS           : IfDstIdxxD            <= IfDstIdxxDI;
+        IfDstIdxValidxAS      : IfDstIdxValidxS       <= IfDstIdxValidxSI;
+        RXSchedulerAckxAS     : SchedulerAckxD        <= SchedulerAckxDI;
+        TXBookingVectorxAS    : BookingVectorxDO      <= BookingVectorxDP;
+        BookingVectorValidxAS : BookingVectorValidxSO <= BookingVectorValidxS;
+    end block EntityIOxB;
+
+    StateMachineUpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process StateMachineUpdateRegxP
+        if SysRstxRNAI = '0' then
+            BookingVectorxDP           <= (others => '0');
+            ScalpBookingVectorStatexDP <= E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK;
+        elsif rising_edge(SysClkxCI) then
+            BookingVectorxDP           <= BookingVectorxDN;
+            ScalpBookingVectorStatexDP <= ScalpBookingVectorStatexDN;
+        end if;
+    end process StateMachineUpdateRegxP;
+
+    BookingVectorStateMachinexP : process (BookingVectorxDP, IfDstIdxValidxS,
+                                           IfDstIdxxD,
+                                           ScalpBookingVectorStatexDP,
+                                           SchedulerAckxD(0)) is
+    begin  -- process BookingVectorStateMachinexP
+        -- Default value
+        BookingVectorxDN           <= BookingVectorxDP;
+        ScalpBookingVectorStatexDN <= ScalpBookingVectorStatexDP;
+        BookingVectorValidxS       <= '0';
+
+        case ScalpBookingVectorStatexDP is
+            when E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK =>
+                    if IfDstIdxValidxS = '1' then
+                        BookingVectorxDN(IfDstIdxxD) <= '1';
+                        ScalpBookingVectorStatexDN   <= E_SCALP_BOOKING_VECTOR_VALID_INDEX;
+                        BookingVectorValidxS         <= '1';
+                    end if;
+
+            when E_SCALP_BOOKING_VECTOR_VALID_INDEX =>
+                    BookingVectorValidxS <= '1';
+                    -- !!! SchedulerAckxD(0) Only if the acknowledgment signals are multiplexed.
+                    if SchedulerAckxD(0) = '1' then
+                        BookingVectorxDN           <= (others => '0');
+                        ScalpBookingVectorStatexDN <= E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK;
+                        BookingVectorValidxS       <= '0';
+                    end if;
+
+            when others => null;
+        end case;
+    end process BookingVectorStateMachinexP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_fifo_double_register.vhd b/ips/hw/scalp_router/src/hdl/scalp_fifo_double_register.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..e6ecfa797de70cdf5383b178af051d0e1274735e
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_fifo_double_register.vhd
@@ -0,0 +1,129 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_fifo_double_register.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Small fifo built with two registers.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+
+entity scalp_fifo_double_register is
+
+    port (
+        -- System Clock and Reset
+        SysClkxCI      : in  std_ulogic;
+        SysRstxRNAI    : in  std_ulogic;
+        -- Axis Ports (Slave Side)
+        Axism2sLinkxDI : in  t_axi4m2s;
+        Axiss2mLinkxDO : out t_axi4s2m;
+        -- Axis Ports (Master Side)
+        Axism2sLinkxDO : out t_axi4m2s;
+        Axiss2mLinkxDI : in  t_axi4s2m);
+
+end entity scalp_fifo_double_register;
+
+architecture behavioral of scalp_fifo_double_register is
+
+    -- Signals
+    -- Axis Data, Valid, Last, Keep
+    signal Axism2s0xD  : t_axi4m2s := C_NO_AXI4_M2S;
+    signal Axism2s1xDP : t_axi4m2s := C_NO_AXI4_M2S;
+    signal Axism2s1xDN : t_axi4m2s := C_NO_AXI4_M2S;
+    signal Axism2s2xDP : t_axi4m2s := C_NO_AXI4_M2S;
+    signal Axism2s2xDN : t_axi4m2s := C_NO_AXI4_M2S;
+    signal Axism2s3xD  : t_axi4m2s := C_NO_AXI4_M2S;
+    -- Axis Ready
+    signal Axiss2m0xD  : t_axi4s2m := C_NO_AXI4_S2M;
+    signal Axiss2m1xDP : t_axi4s2m := C_NO_AXI4_S2M;
+    signal Axiss2m1xDN : t_axi4s2m := C_NO_AXI4_S2M;
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        -- Axis m2s
+        Axism2s0FromxAS : Axism2s0xD     <= Axism2sLinkxDI;
+        Axism2s3ToxAS   : Axism2sLinkxDO <= Axism2s3xD;
+        -- Axis s2m
+        Axiss2m0FromxAS : Axiss2m0xD     <= Axiss2mLinkxDI;
+        Axiss2m1FromxAS : Axiss2m1xDN    <= Axiss2m0xD;
+        Axiss2m1ToxAS   : Axiss2mLinkxDO <= Axiss2m1xDP;
+    end block EntityIOxB;
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB        
+        Axism2s3FromxAS : Axism2s3xD <= Axism2s1xDP when
+                                        (Axiss2m0xD.ReadyxS = '0' and Axiss2m1xDP.ReadyxS = '1') or
+                                        (Axiss2m0xD.ReadyxS = '1' and Axiss2m1xDP.ReadyxS = '1') else
+                                        Axism2s2xDP;
+    end block AsyncStatementsxB;
+
+    UpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process UpdateRegxP
+        if SysRstxRNAI = '0' then
+            -- Axis m2s
+            Axism2s1xDP <= C_NO_AXI4_M2S;
+            Axism2s2xDP <= C_NO_AXI4_M2S;
+            -- Axis s2m
+            Axiss2m1xDP <= C_NO_AXI4_S2M;
+        -- Enable Port
+        -- ScalpFifoEnablexSP <= '0';
+        elsif rising_edge(SysClkxCI) then
+            -- Axis m2s
+            Axism2s1xDP <= Axism2s1xDN;
+            Axism2s2xDP <= Axism2s2xDN;
+            -- Axis s2m
+            Axiss2m1xDP <= Axiss2m1xDN;
+        -- Enable Port
+        -- ScalpFifoEnablexSP <= ScalpFifoEnablexSN;
+        end if;
+    end process UpdateRegxP;
+
+    TransistionOnReadyxP : process (Axism2s0xD, Axism2s1xDP, Axism2s2xDP,
+                                    Axiss2m0xD.ReadyxS, Axiss2m1xDP.ReadyxS) is
+    begin  -- process TransistionOnReadyxP
+        -- Defaults values
+        Axism2s1xDN <= Axism2s1xDP;
+        Axism2s2xDN <= Axism2s2xDP;
+
+        if Axiss2m0xD.ReadyxS = '0' and Axiss2m1xDP.ReadyxS = '0' then
+            Axism2s1xDN <= Axism2s1xDP;
+            Axism2s2xDN <= Axism2s2xDP;
+        elsif Axiss2m0xD.ReadyxS = '0' and Axiss2m1xDP.ReadyxS = '1' then
+            Axism2s1xDN <= Axism2s0xD;
+            Axism2s2xDN <= Axism2s2xDP;
+        elsif Axiss2m0xD.ReadyxS = '1' and Axiss2m1xDP.ReadyxS = '0' then
+            Axism2s1xDN <= Axism2s1xDP;
+            Axism2s2xDN <= Axism2s0xD;
+        else
+            Axism2s1xDN <= Axism2s0xD;
+            Axism2s2xDN <= Axism2s0xD;
+        end if;
+    end process TransistionOnReadyxP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_matrix_index.vhd b/ips/hw/scalp_router/src/hdl/scalp_matrix_index.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..262889e3a9ed1ee8057a1769d3c27ed6374cba41
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_matrix_index.vhd
@@ -0,0 +1,81 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_matrix_index.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Determines the index of the output vector.
+--
+-- Last update: 2020-01-19
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+entity scalp_matrix_index is
+
+    generic (
+        C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255 := 7);
+
+    port (
+        IfSrcNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+        IfDstNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+        IfNumValidxSI    : in  std_ulogic;
+        IfDstIdxxDO      : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+        IfDstIdxValidxSO : out std_ulogic);
+
+end entity scalp_matrix_index;
+
+architecture behavioral of scalp_matrix_index is
+
+    signal IfNumValidxS    : std_ulogic                                             := '0';
+    signal IfDstIdxValidxS : std_ulogic                                             := '0';
+    signal IfSrcNumxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    signal IfDstNumxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    signal IfDstIdxxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+
+        IfSrcNumxAS      : IfSrcNumxD       <= IfSrcNumxDI;
+        IfDstNumxAS      : IfDstNumxD       <= IfDstNumxDI;
+        IfNumValidxAS    : IfNumValidxS     <= IfNumValidxSI;
+        IfDstIdxxAS      : IfDstIdxxDO      <= IfDstIdxxD;
+        IfDstIdxValidxAS : IfDstIdxValidxSO <= IfDstIdxValidxS;
+
+    end block EntityIOxB;
+
+    MatrixIndexxP : process (IfDstNumxD, IfNumValidxS, IfSrcNumxD) is
+    begin  -- process MatrixIndexxP
+        IfDstIdxxD      <= 0;
+        IfDstIdxValidxS <= '0';
+
+        if (IfSrcNumxD < IfDstNumxD) and (IfNumValidxS = '1') then
+            IfDstIdxxD      <= IfDstNumxD - (IfSrcNumxD + 1);
+            IfDstIdxValidxS <= '1';
+        elsif (IfSrcNumxD > IfDstNumxD) and (IfNumValidxS = '1') then
+            IfDstIdxxD      <= ((C_SCALP_INTERFACE_VECTOR_SIZE - 1) - IfSrcNumxD) + IfDstNumxD;
+            IfDstIdxValidxS <= '1';
+        end if;
+    end process MatrixIndexxP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_misc.vhd b/ips/hw/scalp_router/src/hdl/scalp_misc.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..282bb64088ef9c00f4699020d6169ff1783156d9
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_misc.vhd
@@ -0,0 +1,926 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_misc.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2018.2
+-- Description: Scalp Miscellanous
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.axi4_pkg.all;
+
+package scalp_misc is
+
+    constant C_SCALP_X_RANGE_VALUE             : integer range 0 to 255   := 255;
+    constant C_SCALP_Y_RANGE_VALUE             : integer range 0 to 255   := 255;
+    constant C_SCALP_Z_RANGE_VALUE             : integer range 0 to 255   := 255;
+    constant C_SCALP_PACKET_TYPE_RANGE_VALUE   : integer range 0 to 255   := 255;
+    constant C_SCALP_PACKET_LENGTH_RANGE_VALUE : integer range 0 to 65535 := 65535;
+    constant C_SCALP_ADDR_SIZE                 : integer range 0 to 255   := 8;
+    constant C_BYTE_SIZE                       : integer range 0 to 255   := 8;
+    -- Scalp router interfaces id.
+    constant C_NORTH_IF_ID                     : integer range 0 to 6     := 0;
+    constant C_EAST_IF_ID                      : integer range 0 to 6     := 1;
+    constant C_SOUTH_IF_ID                     : integer range 0 to 6     := 2;
+    constant C_WEST_IF_ID                      : integer range 0 to 6     := 3;
+    constant C_TOP_IF_ID                       : integer range 0 to 6     := 4;
+    constant C_BOTTOM_IF_ID                    : integer range 0 to 6     := 5;
+    constant C_LOCAL_IF_ID                     : integer range 0 to 6     := 6;
+    -- Scalp payload sizes
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_1     : integer range 0 to 256   := 1;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_2     : integer range 0 to 256   := 2;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_4     : integer range 0 to 256   := 4;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_8     : integer range 0 to 256   := 8;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_16    : integer range 0 to 256   := 16;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_32    : integer range 0 to 256   := 32;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_64    : integer range 0 to 256   := 64;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_128   : integer range 0 to 256   := 128;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE_256   : integer range 0 to 256   := 256;
+    -- Scalp Simulation
+    constant C_SCALP_SIMULATION                : boolean;
+
+    -- Scalp Booking Vector States
+    type t_scalp_booking_vector_states is (E_SCALP_BOOKING_VECTOR_VALID_INDEX,
+                                           E_SCALP_BOOKING_VECTOR_SCHEDULER_ACK);
+
+    -- Scalp Tx Side States
+    type t_scalp_tx_side_states is (E_SCALP_TX_IDLE,
+                                    E_SCALP_TX_WAIT_BOOKING_VECTOR,
+                                    E_SCALP_TX_POP_N_PUSH);
+
+    -- Scalp Rx Side States
+    type t_scalp_rx_side_states is (E_SCALP_RX_IDLE,
+                                    E_SCALP_RX_ARBITRATE,
+                                    E_SCALP_RX_WAIT_ARBITRATED,
+                                    E_SCALP_RX_POP_N_PUSH,
+                                    E_SCALP_RX_ACK);
+
+    -- Scalp Packet States
+    type t_scalp_packet_states is (E_SP_IDLE,
+                                   E_SP_WAIT,
+                                   E_SP_H0,
+                                   E_SP_H1,
+                                   E_SP_H2,
+                                   E_SP_P,
+                                   E_SP_P_LAST);
+
+    type t_scalp_netaddr is record
+        XxD : integer range 0 to C_SCALP_X_RANGE_VALUE;
+        YxD : integer range 0 to C_SCALP_Y_RANGE_VALUE;
+        ZxD : integer range 0 to C_SCALP_Z_RANGE_VALUE;
+    end record t_scalp_netaddr;
+
+    constant C_3D_MIN_SCALP_NETADDR : t_scalp_netaddr := (XxD => 0,
+                                                          YxD => 0,
+                                                          ZxD => 0);
+    constant C_3D_MAX_SCALP_NETADDR : t_scalp_netaddr := (XxD => C_SCALP_X_RANGE_VALUE,
+                                                          YxD => C_SCALP_Y_RANGE_VALUE,
+                                                          ZxD => C_SCALP_Z_RANGE_VALUE);
+    constant C_2D_MIN_SCALP_NETADDR : t_scalp_netaddr := (XxD => 0,
+                                                          YxD => 0,
+                                                          ZxD => 0);
+    constant C_2D_MAX_SCALP_NETADDR : t_scalp_netaddr := (XxD => C_SCALP_X_RANGE_VALUE,
+                                                          YxD => C_SCALP_Y_RANGE_VALUE,
+                                                          ZxD => 0);
+
+    type t_scalp_netaddr_vector is array (natural range <>) of t_scalp_netaddr;
+
+    -- Scalp QoS Vector
+    constant C_SCALP_QOS_SIZE : integer range 0 to 7 := 7;
+
+    subtype t_scalp_qos is unsigned((C_SCALP_QOS_SIZE - 1) downto 0);
+    type t_scalp_qos_vector is array (natural range <>) of t_scalp_qos;
+
+    constant C_SCALP_NO_QOS : t_scalp_qos := (others => '0');
+
+    -- Scalp Vector of Booking Vector
+    type t_scalp_booking_vector_vector is array (natural range <>) of std_ulogic_vector;
+
+    -- Scalp Vector of Scheduler Ack Vector
+    type t_scalp_scheduler_ack_vector_vector is array (natural range <>) of std_ulogic_vector;
+
+    type t_scalp_packet_header is record
+        DstAddrxD : t_scalp_netaddr;
+        SrcAddrxD : t_scalp_netaddr;
+        TypexD    : integer range 0 to C_SCALP_PACKET_TYPE_RANGE_VALUE;
+        LengthxD  : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+    end record t_scalp_packet_header;
+
+    constant C_NO_SCALP_PACKET_HEADER : t_scalp_packet_header := (DstAddrxD => C_3D_MIN_SCALP_NETADDR,
+                                                                  SrcAddrxD => C_3D_MIN_SCALP_NETADDR,
+                                                                  TypexD    => 0,
+                                                                  LengthxD  => 0);
+
+    type t_scalp_packet_header_vector is array (natural range <>) of t_scalp_packet_header;
+
+    type t_scalp_packet_word is record
+        WordxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0);
+        IdxD   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+    end record t_scalp_packet_word;
+
+    constant C_NO_SCALP_PACKET_WORD : t_scalp_packet_word := (WordxD => (others => '0'),
+                                                              IdxD   => 0);
+
+    type t_scalp_packet_payload is array (natural range <>) of t_scalp_packet_word;
+
+    type t_scalp_packet_payload_vector is array (natural range <>) of t_scalp_packet_payload;
+
+    -- constant C_NO_SCALP_PACKET_PAYLOAD : t_scalp_packet_payload := (others => C_NO_SCALP_PACKET_WORD);
+
+    type t_scalp_packet is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload;
+    end record t_scalp_packet;
+
+    type t_scalp_packet_vector is array (natural range <>) of t_scalp_packet;
+
+    -- constant C_NO_SCALP_PACKET : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER);
+
+    subtype t_scalp_packet_payload_1 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_1 - 1) downto 0);
+    subtype t_scalp_packet_payload_2 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_2 - 1) downto 0);
+    subtype t_scalp_packet_payload_4 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_4 - 1) downto 0);
+    subtype t_scalp_packet_payload_8 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_8 - 1) downto 0);
+    subtype t_scalp_packet_payload_16 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_16 - 1) downto 0);
+    subtype t_scalp_packet_payload_32 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_32 - 1) downto 0);
+    subtype t_scalp_packet_payload_64 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_64 - 1) downto 0);
+    subtype t_scalp_packet_payload_128 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_128 - 1) downto 0);
+    subtype t_scalp_packet_payload_256 is t_scalp_packet_payload((C_SCALP_PACKET_PAYLOAD_SIZE_256 - 1) downto 0);
+
+    constant C_NO_SCALP_PACKET_PAYLOAD_1   : t_scalp_packet_payload_1   := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_2   : t_scalp_packet_payload_2   := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_4   : t_scalp_packet_payload_4   := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_8   : t_scalp_packet_payload_8   := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_16  : t_scalp_packet_payload_16  := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_32  : t_scalp_packet_payload_32  := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_64  : t_scalp_packet_payload_64  := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_128 : t_scalp_packet_payload_128 := (others => C_NO_SCALP_PACKET_WORD);
+    constant C_NO_SCALP_PACKET_PAYLOAD_256 : t_scalp_packet_payload_256 := (others => C_NO_SCALP_PACKET_WORD);
+
+    type t_scalp_packet_1 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_1;
+    end record t_scalp_packet_1;
+
+    constant C_NO_SCALP_PACKET_1 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                      SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_1);
+
+    type t_scalp_packet_2 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_2;
+    end record t_scalp_packet_2;
+
+    constant C_NO_SCALP_PACKET_2 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                      SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_2);
+
+    type t_scalp_packet_4 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_4;
+    end record t_scalp_packet_4;
+
+    constant C_NO_SCALP_PACKET_4 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                      SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_4);
+
+    type t_scalp_packet_8 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_8;
+    end record t_scalp_packet_8;
+
+    constant C_NO_SCALP_PACKET_8 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                      SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_8);
+
+    type t_scalp_packet_16 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_16;
+    end record t_scalp_packet_16;
+
+    constant C_NO_SCALP_PACKET_16 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                       SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_16);
+
+    type t_scalp_packet_32 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_32;
+    end record t_scalp_packet_32;
+
+    constant C_NO_SCALP_PACKET_32 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                       SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_32);
+
+    type t_scalp_packet_64 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_64;
+    end record t_scalp_packet_64;
+
+    constant C_NO_SCALP_PACKET_64 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                       SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_64);
+
+    type t_scalp_packet_128 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_128;
+    end record t_scalp_packet_128;
+
+    constant C_NO_SCALP_PACKET_128 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                        SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_128);
+
+    type t_scalp_packet_256 is record
+        SpHeaderxD  : t_scalp_packet_header;
+        SpPayloadxD : t_scalp_packet_payload_256;
+    end record t_scalp_packet_256;
+
+    constant C_NO_SCALP_PACKET_256 : t_scalp_packet := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+                                                        SpPayloadxD => C_NO_SCALP_PACKET_PAYLOAD_256);
+
+    function scalp_is_simulation
+        return boolean;
+
+    -- Fonction pour calculer l'index des vecteurs.
+    function scalp_matrix_idx (
+        IfSrcxD : integer;
+        IfDstxD : integer;
+        NbIfxD  : integer)
+        return integer;
+
+    -- Fonction pour changer l'endianess BIG <-> LITTLE (std_ulogic_vector)
+    function change_endian_ul (
+        VecxD : std_ulogic_vector)
+        return std_ulogic_vector;
+
+    -- Fonction pour changer l'endianess BIG <-> LITTLE (std_logic_vector)
+    function change_endian(
+        VecxD : std_logic_vector)
+        return std_logic_vector;
+
+    -- Fonction pour récupérer l'adresse de destination ou de source d'un paquet SCALP_PACKET
+    function scalp_peek_addr_ul (
+        DataxD : std_ulogic_vector)
+        return t_scalp_netaddr;
+
+    -- Fonction pour récupérer l'adresse de destination ou de source d'un paquet SCALP_PACKET
+    function scalp_peek_addr (
+        DataxD : std_logic_vector)
+        return t_scalp_netaddr;
+
+    -- Fonction pour récupérer la taille du payload.
+    function scalp_peek_pld_size_ul (
+        DataxD : std_ulogic_vector)
+        return integer;
+
+    -- Fonction pour récupérer la taille du payload.
+    function scalp_peek_pld_size (
+        DataxD : std_logic_vector)
+        return integer;
+
+    -- Fonction pour récupérer le type du paquet Scalp.
+    function scalp_peek_type_ul (
+        DataxD : std_ulogic_vector)
+        return integer;
+
+    -- Fonction pour récupérer le type du paquet Scalp.
+    function scalp_peek_type (
+        DataxD : std_logic_vector)
+        return integer;
+
+    -- Fonction de conversion Scalp Packet Header H0 vers Axis (big endian).
+    function scalp_sp_header_h0_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector;
+
+    -- Fonction de conversion Scalp Packet Header H0 vers Axis (big endian).
+    function scalp_sp_header_h0_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector;
+
+    -- Fonction de conversion Scalp Packet Header H1 vers Axis (big endian).
+    function scalp_sp_header_h1_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector;
+
+    -- Fonction de conversion Scalp Packet Header H1 vers Axis (big endian).
+    function scalp_sp_header_h1_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector;
+
+    -- Fonction de conversion Scalp Packet Header H2 vers Axis (big endian).
+    function scalp_sp_header_h2_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector;
+
+    -- Fonction de conversion Scalp Packet Header H2 vers Axis (big endian).
+    function scalp_sp_header_h2_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector;
+
+    -- Function de conversion Scalp Packet Payload P vers Axis (big endian).
+    function scalp_sp_payload_p_to_axis_ul (
+        SpPayloadxD : t_scalp_packet_payload;
+        IdxxD       : integer)
+        return std_ulogic_vector;
+
+    -- Function de conversion Scalp Packet Payload P vers Axis (big endian).
+    function scalp_sp_payload_p_to_axis (
+        SpPayloadxD : t_scalp_packet_payload;
+        IdxxD       : integer)
+        return std_logic_vector;
+
+    -- Fonction de conversion Axis vers Scalp Packet Header (big endian ->
+    -- little endian)
+    function scalp_axis_to_sp_header_ul (
+        H0xD : std_ulogic_vector;
+        H1xD : std_ulogic_vector;
+        H2xD : std_ulogic_vector)
+        return t_scalp_packet_header;
+
+    -- Fonction de conversion Axis vers Scalp Packet Header (big endian ->
+    -- little endian)
+    function scalp_axis_to_sp_header (
+        H0xD : std_logic_vector;
+        H1xD : std_logic_vector;
+        H2xD : std_logic_vector)
+        return t_scalp_packet_header;
+
+    -- Fonction de conversion Axis vers Scalp Packet Word (big endian -> little
+    -- endian)
+    function scalp_axis_to_sp_word_ul (
+        WordxD : std_ulogic_vector;
+        IdxD   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE)
+        return t_scalp_packet_word;
+
+    -- Fonction de conversion Axis vers Scalp Packet Word (big endian -> little
+    -- endian)
+    function scalp_axis_to_sp_word (
+        WordxD : std_logic_vector;
+        IdxD   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE)
+        return t_scalp_packet_word;
+
+    -- Natural -> std_ulogic_vector
+    function scalp_to_sulv (
+        ValuexD : natural;
+        SizexD  : positive)
+        return std_ulogic_vector;
+
+    -- Natural -> std_logic_vector
+    function scalp_to_slv (
+        ValuexD : natural;
+        SizexD  : positive)
+        return std_logic_vector;
+
+    -- If Then Else -> Unsigned
+    function scalp_ite (
+        CondxS   : boolean;
+        Value1xD : unsigned;
+        Value2xD : unsigned)
+        return unsigned;
+
+    -- Fonction qui retourne le max entre deux entiers.
+    function scalp_imax (
+        Arg1xD : integer;
+        Arg2xD : integer)
+        return integer;
+
+    -- Fonction qui retourne le log en base 2. Toujours à l'arrondu supérieur.
+    function scalp_log2ceil (
+        ArgxD : positive)
+        return natural;
+
+    -- Fonction qui retourne le log en base 2. Toujours à l'arrondi supérieur.
+    -- La valeur de retour est >= 1.
+    function scalp_log2ceilnz(
+        ArgxD : positive)
+        return positive;
+
+    -- Fonction de conversion d'un code One-Hot vers binaire.
+    function scalp_onehot2bin(
+        OneHotxD   : std_ulogic_vector;
+        EmptyValxD : integer := -1)
+        return unsigned;
+
+end package scalp_misc;
+
+package body scalp_misc is
+
+    -- SCALP SIMULATION
+    ---------------------------------------------------------------------------
+    function scalp_is_simulation
+        return boolean is
+        variable RetxS : boolean;
+    begin  -- function scalp_is_simulation
+        RetxS := false;
+
+        if is_x('X') then
+            RetxS := true;
+        end if;
+
+        return RetxS;
+    end function scalp_is_simulation;
+
+    constant C_SCALP_SIMULATION : boolean := scalp_is_simulation;
+    ---------------------------------------------------------------------------
+
+    -- Fonction pour calculer l'index des vecteurs.
+    function scalp_matrix_idx (
+        IfSrcxD : integer;
+        IfDstxD : integer;
+        NbIfxD  : integer)
+        return integer is
+        variable ResxD : integer := 0;
+    begin
+        ResxD := (IfDstxD - (IfSrcxD + 1)) mod NbIfxD;
+        return ResxD;
+    end function scalp_matrix_idx;
+
+    -- Fonction pour changer l'endianess BIG <-> LITTLE (std_ulogic_vector)
+    function change_endian_ul(
+        VecxD : std_ulogic_vector)
+        return std_ulogic_vector is
+        variable VRetxD      : std_ulogic_vector(VecxD'range) := (others => '0');
+        constant CNumBytesxD : natural                        := (VecxD'length / C_BYTE_SIZE);
+    begin
+        for i in 0 to (CNumBytesxD - 1) loop
+            for j in (C_BYTE_SIZE - 1) downto 0 loop
+                VRetxD((C_BYTE_SIZE * i) + j) := VecxD((C_BYTE_SIZE * (CNumBytesxD - 1 - i)) + j);
+            end loop;  -- j
+        end loop;  -- i
+
+        return VRetxD;
+    end function change_endian_ul;
+
+    -- Fonction pour changer l'endianess BIG <-> LITTLE (std_logic_vector)
+    function change_endian(
+        VecxD : std_logic_vector)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(change_endian_ul(std_ulogic_vector(VecxD)));
+    end function change_endian;
+
+    -- Fonction pour récupérer l'adresse de destination ou de source d'un paquet SCALP_PACKET
+    function scalp_peek_addr_ul (
+        DataxD : std_ulogic_vector)
+        return t_scalp_netaddr is
+        variable AddrxD      : t_scalp_netaddr;
+        variable XMapRangexD : std_ulogic_vector(0 to (C_BYTE_SIZE - 1))     := (others => '0');
+        variable YMapRangexD : std_ulogic_vector(0 to (C_BYTE_SIZE - 1))     := (others => '0');
+        variable ZMapRangexD : std_ulogic_vector(0 to (C_BYTE_SIZE - 1))     := (others => '0');
+        variable XxD         : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0) := (others => '0');
+        variable YxD         : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0) := (others => '0');
+        variable ZxD         : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0) := (others => '0');
+    begin
+        XMapRangexD(0 to (C_BYTE_SIZE - 1)) := DataxD((DataxD'high - ((C_BYTE_SIZE * 1) - 1)) to DataxD'high);
+        YMapRangexD(0 to (C_BYTE_SIZE - 1)) := DataxD((DataxD'high - ((C_BYTE_SIZE * 2) - 1)) to (DataxD'high - (C_BYTE_SIZE * 1)));
+        ZMapRangexD(0 to (C_BYTE_SIZE - 1)) := DataxD((DataxD'high - ((C_BYTE_SIZE * 3) - 1)) to (DataxD'high - (C_BYTE_SIZE * 2)));
+
+        XxD := change_endian_ul(XMapRangexD);
+        YxD := change_endian_ul(YMapRangexD);
+        ZxD := change_endian_ul(ZMapRangexD);
+
+        AddrxD.XxD := to_integer(unsigned(XxD));
+        AddrxD.YxD := to_integer(unsigned(YxD));
+        AddrxD.ZxD := to_integer(unsigned(ZxD));
+
+        return AddrxD;
+    end function scalp_peek_addr_ul;
+
+    -- Fonction pour récupérer l'adresse de destination ou de source d'un paquet SCALP_PACKET
+    function scalp_peek_addr (
+        DataxD : std_logic_vector)
+        return t_scalp_netaddr is
+    begin
+        return scalp_peek_addr_ul(std_ulogic_vector(DataxD));
+    end function scalp_peek_addr;
+
+    -- Fonction pour récupérer la taille du payload.
+    function scalp_peek_pld_size_ul (
+        DataxD : std_ulogic_vector)
+        return integer is
+        variable PldSizexD       : std_ulogic_vector(((C_BYTE_SIZE * 2) - 1) downto 0) := (others => '0');
+        variable WordBigEndianxD : std_ulogic_vector(0 to ((C_BYTE_SIZE * 2) - 1))     := (others => '0');
+    begin
+        WordBigEndianxD(WordBigEndianxD'left to WordBigEndianxD'right)
+            := DataxD(DataxD'left to (DataxD'left + ((2 * C_BYTE_SIZE) - 1)));
+        PldSizexD := change_endian_ul(WordBigEndianxD);
+        return to_integer(unsigned(PldSizexD));
+    end function scalp_peek_pld_size_ul;
+
+    -- Fonction pour récupérer la taille du payload.
+    function scalp_peek_pld_size (
+        DataxD : std_logic_vector)
+        return integer is
+    begin
+        return scalp_peek_pld_size_ul(std_ulogic_vector(DataxD));
+    end function scalp_peek_pld_size;
+
+    -- Fonction pour récupérer le type du paquet Scalp.
+    function scalp_peek_type_ul (
+        DataxD : std_ulogic_vector)
+        return integer is
+        variable TypexD          : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable ByteBigEndianxD : std_ulogic_vector(0 to (C_BYTE_SIZE - 1))           := (others => '0');
+    begin  -- function scalp_peek_type_ul
+        ByteBigEndianxD(ByteBigEndianxD'left to ByteBigEndianxD'right)
+            := DataxD((DataxD'left + (C_BYTE_SIZE * 3)) to (DataxD'left + ((C_BYTE_SIZE * 4) - 1)));
+        TypexD := change_endian_ul(ByteBigEndianxD);
+        return to_integer(unsigned(TypexD));
+    end function scalp_peek_type_ul;
+
+    -- Fonction pour récupérer le type du paquet Scalp.
+    function scalp_peek_type (
+        DataxD : std_logic_vector)
+        return integer is
+    begin  -- function scalp_peek_type
+        return scalp_peek_type_ul(std_ulogic_vector(DataxD));
+    end function scalp_peek_type;
+
+    -- Fonction pour récupérer le payload.
+    function scalp_peek_pld_ul (
+        DataxD : std_ulogic_vector)
+        return std_ulogic_vector is
+        variable PldxD                 : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable DoubleWordBigEndianxD : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))     := (others => '0');
+    begin  -- function scalp_peek_pld
+        DoubleWordBigEndianxD(DoubleWordBigEndianxD'left to DoubleWordBigEndianxD'right)
+            := DataxD(DataxD'left to DataxD'right);
+        PldxD := change_endian_ul(DoubleWordBigEndianxD);
+        return PldxD;
+    end function scalp_peek_pld_ul;
+
+    -- Fonction pour récupérer le payload.
+    function scalp_peek_pld (
+        DataxD : std_logic_vector)
+        return std_logic_vector is
+    begin  -- function scalp_peek_pld
+        return std_logic_vector(scalp_peek_pld_ul(std_ulogic_vector(DataxD)));
+    end function scalp_peek_pld;
+
+    -- Fonction de conversion Scalp Packet Header H0 vers Axis (big endian).
+    function scalp_sp_header_h0_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector is
+        variable H0xD             : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))     := (others => '0');
+        variable H0LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable DstAddrXxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable DstAddrYxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable DstAddrZxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable TypexD           : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+    begin
+        DstAddrXxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.DstAddrxD.XxD, C_BYTE_SIZE));
+        DstAddrYxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.DstAddrxD.YxD, C_BYTE_SIZE));
+        DstAddrZxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.DstAddrxD.ZxD, C_BYTE_SIZE));
+        TypexD           := std_ulogic_vector(to_unsigned(SpHeaderxD.TypexD, C_BYTE_SIZE));
+        H0LittleEndianxD := DstAddrXxD & DstAddrYxD & DstAddrZxD & TypexD;
+        H0xD             := change_endian_ul(H0LittleEndianxD);
+        return H0xD;
+    end function scalp_sp_header_h0_to_axis_ul;
+
+    -- Fonction de conversion Scalp Packet Header H0 vers Axis (big endian).
+    function scalp_sp_header_h0_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(scalp_sp_header_h0_to_axis_ul(SpHeaderxD));
+    end function scalp_sp_header_h0_to_axis;
+
+    -- Fonction de conversion Scalp Packet Header H1 vers Axis (big endian).
+    function scalp_sp_header_h1_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector is
+        variable H1xD             : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))     := (others => '0');
+        variable H1LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable SrcAddrXxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable SrcAddrYxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable SrcAddrZxD       : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+        variable PadxD            : std_ulogic_vector((C_BYTE_SIZE - 1) downto 0)       := (others => '0');
+    begin
+        SrcAddrXxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.SrcAddrxD.XxD, C_BYTE_SIZE));
+        SrcAddrYxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.SrcAddrxD.YxD, C_BYTE_SIZE));
+        SrcAddrZxD       := std_ulogic_vector(to_unsigned(SpHeaderxD.SrcAddrxD.ZxD, C_BYTE_SIZE));
+        -- 31 downto 0
+        H1LittleEndianxD := SrcAddrXxD & SrcAddrYxD & SrcAddrZxD & PadxD;
+        H1xD             := change_endian_ul(H1LittleEndianxD);
+        return H1xD;
+    end function scalp_sp_header_h1_to_axis_ul;
+
+    -- Fonction de conversion Scalp Packet Header H1 vers Axis (big endian).
+    function scalp_sp_header_h1_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(scalp_sp_header_h1_to_axis_ul(SpHeaderxD));
+    end function scalp_sp_header_h1_to_axis;
+
+    -- Fonction de conversion Scalp Packet Header H2 vers Axis (big endian).
+    function scalp_sp_header_h2_to_axis_ul (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_ulogic_vector is
+        variable H2xD             : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))     := (others => '0');
+        variable H2LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable PldSizexD        : std_ulogic_vector(((C_BYTE_SIZE * 2) - 1) downto 0) := (others => '0');
+        variable PadxD            : std_ulogic_vector(((C_BYTE_SIZE * 2) - 1) downto 0) := (others => '0');
+    begin
+        PldSizexD        := std_ulogic_vector(to_unsigned(SpHeaderxD.LengthxD, (C_BYTE_SIZE * 2)));
+        H2LittleEndianxD := PldSizexD & PadxD;
+        H2xD             := change_endian_ul(H2LittleEndianxD);
+        return H2xD;
+    end function scalp_sp_header_h2_to_axis_ul;
+
+    -- Fonction de conversion Scalp Packet Header H2 vers Axis (big endian).
+    function scalp_sp_header_h2_to_axis (
+        SpHeaderxD : t_scalp_packet_header)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(scalp_sp_header_h2_to_axis_ul(SpHeaderxD));
+    end function scalp_sp_header_h2_to_axis;
+
+    -- Fonction de conversion Scalp Packet Payload P vers Axis (big endian).
+    function scalp_sp_payload_p_to_axis_ul (
+        SpPayloadxD : t_scalp_packet_payload;
+        IdxxD       : integer)
+        return std_ulogic_vector is
+        variable PxD             : std_ulogic_vector(0 to ((C_BYTE_SIZE * 4) - 1))     := (others => '0');
+        variable PLittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+    begin
+        PLittleEndianxD(PLittleEndianxD'left downto PLittleEndianxD'right) :=
+            SpPayloadxD(IdxxD).WordxD(SpPayloadxD(IdxxD).WordxD'left downto SpPayloadxD(IdxxD).WordxD'right);
+        PxD := change_endian_ul(PLittleEndianxD);
+        return PxD;
+    end function scalp_sp_payload_p_to_axis_ul;
+
+    -- Fonction de conversion Scalp Packet Payload P vers Axis (big endian).
+    function scalp_sp_payload_p_to_axis (
+        SpPayloadxD : t_scalp_packet_payload;
+        IdxxD       : integer)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(scalp_sp_payload_p_to_axis_ul(SpPayloadxD, IdxxD));
+    end function scalp_sp_payload_p_to_axis;
+
+    -- Fonction de conversion Axis vers Scalp Packet Header (big endian ->
+    -- little endian)
+    function scalp_axis_to_sp_header_ul (
+        H0xD : std_ulogic_vector;
+        H1xD : std_ulogic_vector;
+        H2xD : std_ulogic_vector)
+        return t_scalp_packet_header is
+        variable H0LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable H1LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable H2LittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable DstAddrXxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable DstAddrYxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable DstAddrZxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable SrcAddrXxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable SrcAddrYxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable SrcAddrZxD       : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable TypexD           : std_ulogic_vector(((C_BYTE_SIZE * 1) - 1) downto 0) := (others => '0');
+        variable LengthxD         : std_ulogic_vector(((C_BYTE_SIZE * 2) - 1) downto 0) := (others => '0');
+        variable SpHeaderxD       : t_scalp_packet_header                               := C_NO_SCALP_PACKET_HEADER;
+    begin  -- function scalp_axis_to_sp_header_ul
+        -- Big endian to little endian
+        H0LittleEndianxD := change_endian_ul(H0xD);
+        H1LittleEndianxD := change_endian_ul(H1xD);
+        H2LittleEndianxD := change_endian_ul(H2xD);
+
+        -- Dst Addr + Type (H0)
+        DstAddrXxD := H0LittleEndianxD(H0LittleEndianxD'high downto (H0LittleEndianxD'high - ((C_BYTE_SIZE * 1) - 1)));
+        DstAddrYxD := H0LittleEndianxD((H0LittleEndianxD'high - (C_BYTE_SIZE * 1)) downto
+                                       (H0LittleEndianxD'high - ((C_BYTE_SIZE * 2) - 1)));
+        DstAddrZxD := H0LittleEndianxD((H0LittleEndianxD'high - (C_BYTE_SIZE * 2)) downto
+                                       (H0LittleEndianxD'high - ((C_BYTE_SIZE * 3) - 1)));
+        TypexD := H0LittleEndianxD((H0LittleEndianxD'high - (C_BYTE_SIZE * 3)) downto
+                                   (H0LittleEndianxD'high - ((C_BYTE_SIZE * 4) - 1)));
+        -- Src Addr (H1)
+        SrcAddrXxD := H1LittleEndianxD(H1LittleEndianxD'high downto (H1LittleEndianxD'high - ((C_BYTE_SIZE * 1) - 1)));
+        SrcAddrYxD := H1LittleEndianxD((H1LittleEndianxD'high - (C_BYTE_SIZE * 1)) downto
+                                       (H1LittleEndianxD'high - ((C_BYTE_SIZE * 2) - 1)));
+        SrcAddrZxD := H1LittleEndianxD((H1LittleEndianxD'high - (C_BYTE_SIZE * 2)) downto
+                                       (H1LittleEndianxD'high - ((C_BYTE_SIZE * 3) - 1)));
+        -- Payload Size (H2)
+        LengthxD := H2LittleEndianxD(H2LittleEndianxD'high downto (H2LittleEndianxD'high - ((C_BYTE_SIZE * 2) - 1)));
+
+        -- Fill Scalp Packet Header
+        SpHeaderxD.DstAddrxD.XxD := to_integer(unsigned(DstAddrXxD));
+        SpHeaderxD.DstAddrxD.YxD := to_integer(unsigned(DstAddrYxD));
+        SpHeaderxD.DstAddrxD.ZxD := to_integer(unsigned(DstAddrZxD));
+        SpHeaderxD.TypexD        := to_integer(unsigned(TypexD));
+        SpHeaderxD.SrcAddrxD.XxD := to_integer(unsigned(SrcAddrXxD));
+        SpHeaderxD.SrcAddrxD.YxD := to_integer(unsigned(SrcAddrYxD));
+        SpHeaderxD.SrcAddrxD.ZxD := to_integer(unsigned(SrcAddrZxD));
+        SpHeaderxD.LengthxD      := to_integer(unsigned(LengthxD));
+
+        return SpHeaderxD;
+    end function scalp_axis_to_sp_header_ul;
+
+    -- Fonction de conversion Axis vers Scalp Packet Header (big endian ->
+    -- little endian)
+    function scalp_axis_to_sp_header (
+        H0xD : std_logic_vector;
+        H1xD : std_logic_vector;
+        H2xD : std_logic_vector)
+        return t_scalp_packet_header is
+    begin  -- function scalp_axis_to_sp_header
+        return scalp_axis_to_sp_header_ul(std_ulogic_vector(H0xD),
+                                          std_ulogic_vector(H1xD),
+                                          std_ulogic_vector(H2xD));
+    end function scalp_axis_to_sp_header;
+
+    -- Fonction de conversion Axis vers Scalp Packet Word (big endian -> little
+    -- endian)
+    function scalp_axis_to_sp_word_ul (
+        WordxD : std_ulogic_vector;
+        IdxD   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE)
+        return t_scalp_packet_word is
+        variable WordLittleEndianxD : std_ulogic_vector(((C_BYTE_SIZE * 4) - 1) downto 0) := (others => '0');
+        variable SpWordxD           : t_scalp_packet_word                                 := C_NO_SCALP_PACKET_WORD;
+    begin  -- function scalp_axis_to_sp_word_ul
+        WordLittleEndianxD := change_endian_ul(WordxD);
+        SpWordxD.WordxD    := WordLittleEndianxD;
+        SpWordxD.IdxD      := IdxD;
+        return SpWordxD;
+    end function scalp_axis_to_sp_word_ul;
+
+    -- Fonction de conversion Axis vers Scalp Packet Word (big endian -> little
+    -- endian)
+    function scalp_axis_to_sp_word (
+        WordxD : std_logic_vector;
+        IdxD   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE)
+        return t_scalp_packet_word is
+    begin  -- function scalp_axis_to_sp_word
+        return scalp_axis_to_sp_word_ul(std_ulogic_vector(WordxD), IdxD);
+    end function scalp_axis_to_sp_word;
+
+    -- Natural -> std_ulogic_vector
+    function scalp_to_sulv (
+        ValuexD : natural;
+        SizexD  : positive)
+        return std_ulogic_vector is
+        constant ResxD : std_ulogic_vector((SizexD - 1) downto 0) := std_ulogic_vector(to_unsigned(ValuexD, SizexD));
+    begin  -- function scalp_to_sulv
+        return ResxD;
+    end function scalp_to_sulv;
+
+    -- Natural -> std_logic_vector
+    function scalp_to_slv (
+        ValuexD : natural;
+        SizexD  : positive)
+        return std_logic_vector is
+        constant ResxD : std_logic_vector((SizexD - 1) downto 0) := std_logic_vector(to_unsigned(ValuexD, SizexD));
+    begin  -- function scalp_to_slv
+        return ResxD;
+    end function scalp_to_slv;
+
+    -- If Then Else -> Unsigned
+    function scalp_ite (
+        CondxS   : boolean;
+        Value1xD : unsigned;
+        Value2xD : unsigned)
+        return unsigned is
+    begin  -- function scalp_ite
+        if CondxS then
+            return Value1xD;
+        else
+            return Value2xD;
+        end if;
+    end function scalp_ite;
+
+    -- Fonction qui retourne le max entre deux entiers.
+    function scalp_imax (
+        Arg1xD : integer;
+        Arg2xD : integer)
+        return integer is
+    begin  -- function scalp_imax
+        if Arg1xD > Arg2xD then
+            return Arg1xD;
+        end if;
+
+        return Arg2xD;
+    end function scalp_imax;
+
+    -- Fonction qui retourne le log en base 2. Toujours à l'arrondu supérieur.
+    function scalp_log2ceil (
+        ArgxD : positive)
+        return natural is
+        variable TmpxD : positive;
+        variable LogxD : natural;
+    begin  -- function scalp_log2ceil
+        if ArgxD = 1 then
+            return 0;
+        end if;
+
+        TmpxD := 1;
+        LogxD := 0;
+
+        while ArgxD > TmpxD loop
+            TmpxD := TmpxD * 2;
+            LogxD := LogxD + 1;
+        end loop;
+
+        return LogxD;
+    end function scalp_log2ceil;
+
+    -- Fonction qui retourne le log en base 2. Toujours à l'arrondi supérieur.
+    -- La valeur de retour est >= 1.
+    function scalp_log2ceilnz (
+        ArgxD : positive)
+        return positive is
+    begin  -- function scalp_log2ceilnz
+        return scalp_imax(1, scalp_log2ceil(ArgxD));
+    end function scalp_log2ceilnz;
+
+    -- Fonction de conversion d'un code One-Hot vers binaire.
+    function scalp_onehot2bin(
+        OneHotxD   : std_ulogic_vector;
+        EmptyValxD : integer := -1)
+        return unsigned is
+        variable ResxD : unsigned((scalp_log2ceilnz(scalp_imax(OneHotxD'high, EmptyValxD) + 1) - 1) downto 0);
+        variable ChkxD : natural;
+    begin  -- function scalp_onehot2bin
+        if (EmptyValxD > 0) and (OneHotxD = (OneHotxD'range => '0')) then
+            ResxD := to_unsigned(EmptyValxD, ResxD'length);
+        else
+            ResxD := (others => '0');
+            ChkxD := 0;
+
+            for i in OneHotxD'range loop
+                if OneHotxD(i) = '1' then
+                    ResxD := ResxD or to_unsigned(i, ResxD'length);
+                    ChkxD := ChkxD + 1;
+                end if;
+            end loop;  -- i
+        end if;
+
+        if C_SCALP_SIMULATION and (ChkxD /= 1) and ((ChkxD > 1) or (EmptyValxD < 0)) then
+            report "Broken 1-Hot-Code with " & integer'image(ChkxD) & " bits set." severity warning;
+            ResxD := (others => 'X');
+        end if;
+        return ResxD;
+    end function scalp_onehot2bin;
+
+    ---------------------------------------------------------------------------
+    -- Fonction Random
+    ---------------------------------------------------------------------------
+    -- Random Real Value
+    -- impure function scalp_rand_real (
+    --     MinValxD : real;
+    --     MaxValxD : real)
+    --     return real is
+    --     variable RandxD : real;
+    -- begin  -- function scalp_rand_real
+    --     uniform(Seed1xD, Seed2xD, RandxD);
+    --     return RandxD * (MaxValxD - MinValxD) + MinValxD;
+    -- end function scalp_rand_real;
+
+    -- Random Integer Value
+    -- impure function scalp_rand_int (
+    --     MinValxD : integer;
+    --     MaxValxD : integer)
+    --     return integer is
+    --     variable RandxD : real;
+    -- begin  -- function scalp_rand_int
+    --     uniform(Seed1xD, Seed2xD, RandxD);
+    --     return integer(round(RandxD * real(MaxValxD - MinValxD + 1) + real(MinValxD) - 0.5));
+    -- end function scalp_rand_int;
+
+    -- Random std_ulogic_vector
+    -- impure function scalp_rand_sulv (
+    --     LenxD : integer)
+    --     return std_ulogic_vector is
+    --     variable RandxD : real;
+    --     variable SlvxD  : std_ulogic_vector((LenxD - 1) downto 0);
+    -- begin  -- function scalp_rand_slv
+    --     for i in SlvxD'range loop
+    --         uniform(Seed1xD, Seed2xD, RandxD);
+    --         SlvxD(i) := '1' when RandxD > 0.5 else '0';
+    --     end loop;  -- i
+
+    --     return SlvxD;
+    -- end function scalp_rand_sulv;
+
+    -- Random Time
+    -- impure function scalp_rand_time (
+    --     MinValxD : time;
+    --     MaxValxD : time;
+    --     UnitxD   : time := ns)
+    --     return time is
+    --     variable RandxD       : real;
+    --     variable RandScaledxD : real;
+    --     variable MinRealxD    : real;
+    --     variable MaxRealxD    : real;
+    -- begin  -- function scalp_rand_time
+    --     uniform(Seed1xD, Seed2xD, RandxD);
+    --     MinRealxD    := real(MinValxD / UnitxD);
+    --     MaxRealxD    := real(MaxValxD / UnitxD);
+    --     RandScaledxD := RandxD * (MaxRealxD - MinRealxD) + MinRealxD;
+    --     return real(RandScaledxD) * UnitxD;
+    -- end function scalp_rand_time;
+
+end package body scalp_misc;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_router.vhd b/ips/hw/scalp_router/src/hdl/scalp_router.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..9f02514ac1ea8845bbca21cd748c726624f26884
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_router.vhd
@@ -0,0 +1,226 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_router.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp Router (NoC).
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity scalp_router is
+
+    generic (
+        C_SCALP_NUMBER_OF_INTERFACE : integer range 0 to 255 := 7;
+        C_SCALP_SCHEDULER_STRATEGY  : string                 := "RR");
+
+    port (
+        -- System Clock and System nReset
+        -----------------------------------------------------------------------
+        SysClkxCI          : in  std_ulogic;
+        SysRstxRNAI        : in  std_ulogic;
+        -- Local Router Network Address
+        -----------------------------------------------------------------------
+        LocNetAddrxDI      : in  t_scalp_netaddr;
+        -- Axi4 Stream
+        -----------------------------------------------------------------------
+        -- RX Side Vector
+        RXAxism2sVectorxDI : in  t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+        RXAxiss2mVectorxDO : out t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+        -- TX Side Vector
+        TXAxism2sVectorxDO : out t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+        TXAxiss2mVectorxDI : in  t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+        -- QoS Vector
+        -----------------------------------------------------------------------
+        QoSVectorxDI       : in  t_scalp_qos_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0));
+
+end entity scalp_router;
+
+architecture rtl of scalp_router is
+
+    constant C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255 := C_SCALP_NUMBER_OF_INTERFACE;
+    constant C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255 := (C_SCALP_NUMBER_OF_INTERFACE - 1);
+    -- Multicast Only
+    constant C_SCALP_MULTICAST_ONLY            : integer range 0 to 1   := 1;
+    constant C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255 := C_SCALP_MULTICAST_ONLY;
+
+    component scalp_router_interface is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_INTERFACE_SOURCE_NUMBER   : integer range 0 to 255;
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255;
+            C_SCALP_SCHEDULER_STRATEGY        : string);
+        port (
+            -- System Clock and System nReset
+            SysClkxCI         : in  std_ulogic;
+            SysRstxRNAI       : in  std_ulogic;
+            -- Local Router Network Address
+            LocNetAddrxDI     : in  t_scalp_netaddr;
+            -- Axi4 Stream
+            -----------------------------------------------------------------------
+            -- Interface Input Side
+            RXAxi4m2sIfxDI    : in  t_axi4m2s;
+            RXAxi4s2mIfxDO    : out t_axi4s2m;
+            -- Interface Output Side
+            TXAxi4m2sIfxDO    : out t_axi4m2s;
+            TXAxi4s2mIfxDI    : in  t_axi4s2m;
+            -----------------------------------------------------------------------
+            -- Neighborhood Links Input Side
+            RXAxi4m2sLinksxDI : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            RXAxi4s2mLinksxDO : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Neighborhood Links Output Side
+            TXAxi4m2sLinksxDO : out t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            TXAxi4s2mLinksxDI : in  t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -----------------------------------------------------------------------
+            -- Booking Vector
+            -- Input Side
+            BookingVectorxDI  : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Output Side
+            BookingVectorxDO  : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Scheduler Ack Vector
+            -- Input Side
+            SchedulerAckxDI   : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Output Side
+            SchedulerAckxDO   : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- QoS Vector
+            QoSVectorxDI      : in  t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+    end component scalp_router_interface;
+
+    -- Signals
+    -- Scalp Router
+    -- Local Router Network Address
+    signal LocNetAddrxD             : t_scalp_netaddr                                                                                                               := C_3D_MIN_SCALP_NETADDR;
+    -- Axi4 Stream Interfaces
+    signal RXAxism2sVectorxD        : t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                                  := (others => C_NO_AXI4_M2S);
+    signal RXAxiss2mVectorxD        : t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                                  := (others => C_NO_AXI4_S2M);
+    signal TXAxism2sVectorxD        : t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                                  := (others => C_NO_AXI4_M2S);
+    signal TXAxiss2mVectorxD        : t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                                  := (others => C_NO_AXI4_S2M);
+    -- Scalp QoS Vectors
+    signal QoSVectorxD              : t_scalp_qos_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                                := (others => C_SCALP_NO_QOS);
+    -- Axi4 Stream Cross-Links with Neighborhood
+    signal RXAxi4m2sLinksxD         : t_axi4m2s_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)             := (others => (others => C_NO_AXI4_M2S));
+    signal RXAxi4s2mLinksxD         : t_axi4s2m_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)             := (others => (others => C_NO_AXI4_S2M));
+    signal TXAxi4m2sLinksxD         : t_axi4m2s_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)             := (others => (others => C_NO_AXI4_M2S));
+    signal TXAxi4s2mLinksxD         : t_axi4s2m_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)             := (others => (others => C_NO_AXI4_S2M));
+    ---------------------------------------------------------------------------
+    -- For Simulation With Vivado Only
+    -- Axi4 Stream Cross-Links with Neighborhood
+    -- signal RXAxi4m2sLinksxD         : t_axi4m2s_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                           := (others => C_NO_SIM_AXISM2S_VECTOR);
+    -- signal RXAxi4s2mLinksxD         : t_axi4s2m_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                           := (others => C_NO_SIM_AXISS2M_VECTOR);
+    -- signal TXAxi4m2sLinksxD         : t_axi4m2s_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                           := (others => C_NO_SIM_AXISM2S_VECTOR);
+    -- signal TXAxi4s2mLinksxD         : t_axi4s2m_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)                                                           := (others => C_NO_SIM_AXISS2M_VECTOR);
+    ---------------------------------------------------------------------------
+    -- Scalp Booking Vectors
+    signal BookingVectorsInxD       : t_scalp_booking_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)       := (others => (others => '0'));
+    signal BookingVectorsOutxD      : t_scalp_booking_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)       := (others => (others => '0'));
+    -- Scalp Scheduler Ack Vectors
+    signal SchedulerAckVectorsInxD  : t_scalp_scheduler_ack_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => (others => '0'));
+    signal SchedulerAckVectorsOutxD : t_scalp_scheduler_ack_vector_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => (others => '0'));
+
+begin  -- architecture rtl
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        LocNetAddrxAS      : LocNetAddrxD       <= LocNetAddrxDI;
+        RXAxism2sVectorxAS : RXAxism2sVectorxD  <= RXAxism2sVectorxDI;
+        RXAxiss2mVectorxAS : RXAxiss2mVectorxDO <= RXAxiss2mVectorxD;
+        TXAxism2sVectorxAS : TXAxism2sVectorxDO <= TXAxism2sVectorxD;
+        TXAxiss2mVectorxAS : TXAxiss2mVectorxD  <= TXAxiss2mVectorxDI;
+        QoSVectorxAS       : QoSVectorxD        <= QoSVectorxDI;
+    end block EntityIOxB;
+
+    ScalpRouterInterfacexG : for i in 0 to (C_SCALP_NUMBER_OF_INTERFACE - 1) generate
+        assert false report "Generate ScalpRouterInterface #" & integer'image(i) severity note;
+        CrossLinksxG : for j in (i + 1) to ((i + 1) + (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1)) generate
+            assert false report "Generate Axi4 Stream Cross-Link #" & integer'image(j mod C_SCALP_NUMBER_OF_INTERFACE) severity note;
+            assert false report integer'image(i) & "#" &
+                integer'image(scalp_matrix_idx(i, j mod C_SCALP_NUMBER_OF_INTERFACE, C_SCALP_NUMBER_OF_INTERFACE)) &
+                " => " & integer'image(j mod C_SCALP_NUMBER_OF_INTERFACE) & "#" &
+                integer'image(scalp_matrix_idx(j mod C_SCALP_NUMBER_OF_INTERFACE, i, C_SCALP_NUMBER_OF_INTERFACE))
+                severity note;
+
+            -- Axi4 Stream Cross-Links with Neighborhood
+            RXTXm2sLinksxAS : RXAxi4m2sLinksxD(j mod C_SCALP_NUMBER_OF_INTERFACE)(scalp_matrix_idx(j mod C_SCALP_NUMBER_OF_INTERFACE, i, C_SCALP_NUMBER_OF_INTERFACE))
+                <= TXAxi4m2sLinksxD(i)(scalp_matrix_idx(i, j mod C_SCALP_NUMBER_OF_INTERFACE, C_SCALP_NUMBER_OF_INTERFACE));
+            RXTXs2mLinksxAS : TXAxi4s2mLinksxD(i)(scalp_matrix_idx(i, j mod C_SCALP_NUMBER_OF_INTERFACE, C_SCALP_NUMBER_OF_INTERFACE))
+                <= RXAxi4s2mLinksxD(j mod C_SCALP_NUMBER_OF_INTERFACE)(scalp_matrix_idx(j mod C_SCALP_NUMBER_OF_INTERFACE, i, C_SCALP_NUMBER_OF_INTERFACE));
+            -- Booking Vectors Cross-Links with Neighborhood
+            BookingVectorsxAS : BookingVectorsInxD(j mod C_SCALP_NUMBER_OF_INTERFACE)(scalp_matrix_idx(j mod C_SCALP_NUMBER_OF_INTERFACE, i, C_SCALP_NUMBER_OF_INTERFACE))
+                <= BookingVectorsOutxD(i)(scalp_matrix_idx(i, j mod C_SCALP_NUMBER_OF_INTERFACE, C_SCALP_NUMBER_OF_INTERFACE));
+            -- Scalp Scheduler Ack Vectors
+            SchedulerAckVectorsxAS : SchedulerAckVectorsInxD(i)(scalp_matrix_idx(i, j mod C_SCALP_NUMBER_OF_INTERFACE, C_SCALP_NUMBER_OF_INTERFACE)) <=
+                SchedulerAckVectorsOutxD(j mod C_SCALP_NUMBER_OF_INTERFACE)(scalp_matrix_idx(j mod C_SCALP_NUMBER_OF_INTERFACE, i, C_SCALP_NUMBER_OF_INTERFACE));
+        end generate CrossLinksxG;
+
+        ScalpRouterInterfacexI : entity work.scalp_router_interface
+            generic map (
+                C_SCALP_INTERFACE_VECTOR_SIZE     => C_SCALP_INTERFACE_VECTOR_SIZE,
+                C_SCALP_INTERFACE_SOURCE_NUMBER   => i,
+                C_SCALP_NEIGHBORS_VECTOR_SIZE     => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+                C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE,
+                C_SCALP_SCHEDULER_STRATEGY        => C_SCALP_SCHEDULER_STRATEGY)
+            port map (
+                -- System Clock and System nReset
+                SysClkxCI         => SysClkxCI,
+                SysRstxRNAI       => SysRstxRNAI,
+                -- Local Router Network Address
+                LocNetAddrxDI     => LocNetAddrxD,
+                -- Axi4 Stream
+                -----------------------------------------------------------------------
+                -- Interface Input Side
+                RXAxi4m2sIfxDI    => RXAxism2sVectorxD(i),
+                RXAxi4s2mIfxDO    => RXAxiss2mVectorxD(i),
+                -- Interface Output Side
+                TXAxi4m2sIfxDO    => TXAxism2sVectorxD(i),
+                TXAxi4s2mIfxDI    => TXAxiss2mVectorxD(i),
+                -----------------------------------------------------------------------
+                -- Neighborhood Links Input Side
+                RXAxi4m2sLinksxDI => RXAxi4m2sLinksxD(i),
+                RXAxi4s2mLinksxDO => RXAxi4s2mLinksxD(i),
+                -- Neighborhood Links Output Side
+                TXAxi4m2sLinksxDO => TXAxi4m2sLinksxD(i),
+                TXAxi4s2mLinksxDI => TXAxi4s2mLinksxD(i),
+                -----------------------------------------------------------------------
+                -- Booking Vector
+                -- Input Side
+                BookingVectorxDI  => BookingVectorsInxD(i),
+                -- Output Side
+                BookingVectorxDO  => BookingVectorsOutxD(i),
+                -- Scheduler Ack Vector
+                -- Input Side
+                SchedulerAckxDI   => SchedulerAckVectorsInxD(i),
+                -- Output Side
+                SchedulerAckxDO   => SchedulerAckVectorsOutxD(i),
+                -- QoS Vector
+                QoSVectorxDI      => QoSVectorxD);
+    end generate ScalpRouterInterfacexG;
+
+end architecture rtl;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_router_core.vhd b/ips/hw/scalp_router/src/hdl/scalp_router_core.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..64c9576ae3ded63b050a88f6158908c94fbbf9b1
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_router_core.vhd
@@ -0,0 +1,121 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_router_core.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp Router Core Algorithm
+--
+-- Last update: 2020-01-21
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.scalp_misc.all;
+
+entity scalp_router_core is
+
+    generic (
+        C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255 := 7);
+
+    port (
+        -- System Clock and Reset
+        SysClkxCI             : in  std_ulogic;
+        SysRstxRNAI           : in  std_ulogic;
+        -- Local and Destination Router Network Address
+        LocRouterNetAddrxDI   : in  t_scalp_netaddr;
+        DstRouterNetAddrxDI   : in  t_scalp_netaddr;
+        RouterNetAddrValidxSI : in  std_ulogic;
+        -- Destination Interfaces Number
+        IfDstNumxDO           : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+        IfNumValidxSO         : out std_ulogic;
+        -- QoS Vector
+        QoSVectorxDI          : in  t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+
+end entity scalp_router_core;
+
+architecture behavioral_xyz of scalp_router_core is
+
+    constant C_SCALP_NORTH_NUM  : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    constant C_SCALP_EAST_NUM   : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 1;
+    constant C_SCALP_SOUTH_NUM  : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 2;
+    constant C_SCALP_WEST_NUM   : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 3;
+    constant C_SCALP_TOP_NUM    : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 4;
+    constant C_SCALP_BOTTOM_NUM : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 5;
+    constant C_SCALP_LOCAL_NUM  : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 6;
+
+    signal LocRouterNetAddrxD   : t_scalp_netaddr                                                  := C_3D_MIN_SCALP_NETADDR;
+    signal DstRouterNetAddrxD   : t_scalp_netaddr                                                  := C_3D_MIN_SCALP_NETADDR;
+    signal RouterNetAddrValidxS : std_ulogic                                                       := '0';
+    signal IfDstNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)           := 0;
+    signal IfNumValidxS         : std_ulogic                                                       := '0';
+    signal QoSVectorxD          : t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0) := (others => C_SCALP_NO_QOS);
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        LocRouterNetAddrxAS   : LocRouterNetAddrxD   <= LocRouterNetAddrxDI;
+        DstRouterNetAddrxAS   : DstRouterNetAddrxD   <= DstRouterNetAddrxDI;
+        RouterNetAddrValidxAS : RouterNetAddrValidxS <= RouterNetAddrValidxSI;
+        IfDstNumxAS           : IfDstNumxDO          <= IfDstNumxD;
+        IfNumValidxAS         : IfNumValidxSO        <= IfNumValidxS;
+        QoSVectorxAS          : QoSVectorxD          <= QoSVectorxDI;
+    end block EntityIOxB;
+
+    ScalpRouterCorexP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process ScalpRouterCorexP
+        if SysRstxRNAI = '0' then
+            IfDstNumxD   <= C_SCALP_NORTH_NUM;
+            IfNumValidxS <= '0';
+        elsif rising_edge(SysClkxCI) then
+            IfDstNumxD   <= C_SCALP_NORTH_NUM;
+            IfNumValidxS <= '0';
+
+            if RouterNetAddrValidxS = '1' then
+                IfNumValidxS <= '1';
+                -- X-axis
+                if LocRouterNetAddrxD.XxD < DstRouterNetAddrxD.XxD then
+                    IfDstNumxD <= C_SCALP_EAST_NUM;
+                elsif LocRouterNetAddrxD.XxD > DstRouterNetAddrxD.XxD then
+                    IfDstNumxD <= C_SCALP_WEST_NUM;
+                else
+                    -- Y-axis
+                    if LocRouterNetAddrxD.YxD < DstRouterNetAddrxD.YxD then
+                        IfDstNumxD <= C_SCALP_NORTH_NUM;
+                    elsif LocRouterNetAddrxD.YxD > DstRouterNetAddrxD.YxD then
+                        IfDstNumxD <= C_SCALP_SOUTH_NUM;
+                    else
+                        -- Z-axis
+                        if LocRouterNetAddrxD.ZxD < DstRouterNetAddrxD.ZxD then
+                            IfDstNumxD <= C_SCALP_TOP_NUM;
+                        elsif LocRouterNetAddrxD.ZxD > DstRouterNetAddrxD.ZxD then
+                            IfDstNumxD <= C_SCALP_BOTTOM_NUM;
+                        else
+                            IfDstNumxD <= C_SCALP_LOCAL_NUM;
+                        end if;
+                    end if;
+                end if;
+            end if;
+        end if;
+    end process ScalpRouterCorexP;
+
+end architecture behavioral_xyz;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_router_interface.vhd b/ips/hw/scalp_router/src/hdl/scalp_router_interface.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..29aad8cabbc85c7615978a3947cbd3046ab16b87
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_router_interface.vhd
@@ -0,0 +1,325 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_router_interface.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp Router Interface.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+
+entity scalp_router_interface is
+
+    generic (
+        C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255 := 7;
+        C_SCALP_INTERFACE_SOURCE_NUMBER   : integer range 0 to 255 := 0;
+        C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255 := 6;
+        C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255 := 1;
+        C_SCALP_SCHEDULER_STRATEGY        : string                 := "RR");
+
+    port (
+        -- System Clock and System nReset
+        SysClkxCI         : in  std_ulogic;
+        SysRstxRNAI       : in  std_ulogic;
+        -- Local Router Network Address
+        LocNetAddrxDI     : in  t_scalp_netaddr;
+        -- Axi4 Stream
+        -----------------------------------------------------------------------
+        -- Interface Input Side
+        RXAxi4m2sIfxDI    : in  t_axi4m2s;
+        RXAxi4s2mIfxDO    : out t_axi4s2m;
+        -- Interface Output Side
+        TXAxi4m2sIfxDO    : out t_axi4m2s;
+        TXAxi4s2mIfxDI    : in  t_axi4s2m;
+        -----------------------------------------------------------------------
+        -- Neighborhood Links Input Side
+        RXAxi4m2sLinksxDI : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        RXAxi4s2mLinksxDO : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Neighborhood Links Output Side
+        TXAxi4m2sLinksxDO : out t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        TXAxi4s2mLinksxDI : in  t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -----------------------------------------------------------------------
+        -- Booking Vector
+        -- Input Side
+        BookingVectorxDI  : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Output Side
+        BookingVectorxDO  : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Scheduler Ack Vector
+        -- Input Side
+        SchedulerAckxDI   : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Output Side
+        SchedulerAckxDO   : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- QoS Vector
+        QoSVectorxDI      : in  t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+
+end entity scalp_router_interface;
+
+architecture rtl of scalp_router_interface is
+
+    -- Scalp RX Side
+    constant C_SCALP_SCHEDULER_OUTPUT_REG : boolean                := true;
+    constant C_SCALP_DELAY_SIZE           : integer range 0 to 255 := 2;
+
+    component scalp_tx_side is
+        generic (
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            DstRouterNetAddrxDO   : out t_scalp_netaddr;
+            RouterNetAddrValidxSO : out std_ulogic;
+            BookingVectorValidxSI : in  std_ulogic;
+            -- SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+            RXAxi4M2SLinkxDI      : in  t_axi4m2s;
+            RXAxi4S2MLinkxDO      : out t_axi4s2m;
+            TXAxi4M2SLinkxDO      : out t_axi4m2s;
+            TXAxi4S2MLinkxDI      : in  t_axi4s2m);
+    end component scalp_tx_side;
+
+    component scalp_rx_side is
+        generic (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255;
+            C_SCALP_SCHEDULER_STRATEGY    : string;
+            C_SCALP_SCHEDULER_OUTPUT_REG  : boolean);
+        port (
+            SysClkxCI            : in  std_ulogic;
+            SysRstxRNAI          : in  std_ulogic;
+            SchedulerAckxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingVectorxDI     : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            TXAxi4M2SLinkxDO     : out t_axi4m2s;
+            TXAxi4S2MLinkxDI     : in  t_axi4s2m;
+            RXAxi4M2SLinkxDI     : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            RXAxi4S2MLinkxDO     : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingIndexxDO      : out integer range 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1);
+            BookingIndexValidxSO : out std_ulogic);
+    end component scalp_rx_side;
+
+    component scalp_router_core is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            LocRouterNetAddrxDI   : in  t_scalp_netaddr;
+            DstRouterNetAddrxDI   : in  t_scalp_netaddr;
+            RouterNetAddrValidxSI : in  std_ulogic;
+            IfDstNumxDO           : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfNumValidxSO         : out std_ulogic;
+            QoSVectorxDI          : in  std_ulogic_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+    end component scalp_router_core;
+
+    component scalp_scheduler_ack is
+        generic (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SchedulerAckxDI : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            SchedulerAckxDO : out std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0));
+    end component scalp_scheduler_ack;
+
+    component scalp_matrix_index is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            IfSrcNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfNumValidxSI    : in  std_ulogic;
+            IfDstIdxxDO      : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstIdxValidxSO : out std_ulogic);
+    end component scalp_matrix_index;
+
+    component scalp_booking_vector is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            IfDstIdxxDI           : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstIdxValidxSI      : in  std_ulogic;
+            SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+            BookingVectorxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingVectorValidxSO : out std_ulogic);
+    end component scalp_booking_vector;
+
+    component scalp_tx_fanout is
+        generic (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            RXAxi4M2SLinkxDI : in  t_axi4m2s;
+            RXAxi4S2MLinkxDO : out t_axi4s2m;
+            TXAxi4M2SLinkxDO : out t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            TXAxi4S2MLinkxDI : in  t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0));
+    end component scalp_tx_fanout;
+
+    -- Signals
+    -- Scalp Router Interface
+    signal RXAxi4m2sIfxD        : t_axi4m2s                                                           := C_NO_AXI4_M2S;
+    signal RXAxi4s2mIfxD        : t_axi4s2m                                                           := C_NO_AXI4_S2M;
+    signal TXAxi4m2sIfxD        : t_axi4m2s                                                           := C_NO_AXI4_M2S;
+    signal TXAxi4s2mIfxD        : t_axi4s2m                                                           := C_NO_AXI4_S2M;
+    signal RXAxi4m2sLinksxD     : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)      := (others => C_NO_AXI4_M2S);
+    signal RXAxi4s2mLinksxD     : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)      := (others => C_NO_AXI4_S2M);
+    signal TXAxi4m2sLinksxD     : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)      := (others => C_NO_AXI4_M2S);
+    signal TXAxi4s2mLinksxD     : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)      := (others => C_NO_AXI4_S2M);
+    signal BookingVectorInxD    : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal BookingVectorOutxD   : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal SchedulerAckInxD     : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal SchedulerAckOutxD    : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal QoSVectorxD          : t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0)    := (others => C_SCALP_NO_QOS);
+    -- Scalp TX Side
+    signal DstRouterNetAddrxD   : t_scalp_netaddr                                                     := C_3D_MIN_SCALP_NETADDR;
+    signal RouterNetAddrValidxS : std_ulogic                                                          := '0';
+    signal BookingVectorValidxS : std_ulogic                                                          := '0';
+    signal SchedulerAckxD       : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal TXAxi4M2SLinkxD      : t_axi4m2s                                                           := C_NO_AXI4_M2S;
+    signal TXAxi4S2MLinkxD      : t_axi4s2m                                                           := C_NO_AXI4_S2M;
+    -- Scalp RX Side
+    -- Scalp Router Core
+    signal LocRouterNetAddrxD   : t_scalp_netaddr                                                     := C_3D_MIN_SCALP_NETADDR;
+    signal IfDstNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal IfNumValidxS         : std_ulogic                                                          := '0';
+    -- Scalp Scheduler Ack
+    -- Scalp Matrix Index
+    signal IfSrcNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := C_SCALP_INTERFACE_SOURCE_NUMBER;
+    signal IfDstIdxxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal IfDstIdxValidxS      : std_ulogic                                                          := '0';
+    -- Scalp Booking Vector
+    -- Scalp TX Fanout
+    -- Scalp Axis Delay
+    signal DTXAxi4M2SLinkxD     : t_axi4m2s                                                           := C_NO_AXI4_M2S;
+    signal DTXAxi4S2MLinkxD     : t_axi4s2m                                                           := C_NO_AXI4_S2M;
+
+begin  -- architecture rtl
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        LocNetAddrxAS       : LocRouterNetAddrxD <= LocNetAddrxDI;
+        RXAxi4m2sIfxAS      : RXAxi4m2sIfxD      <= RXAxi4m2sIfxDI;
+        RXAxi4s2mIfxAS      : RXAxi4s2mIfxDO     <= RXAxi4s2mIfxD;
+        TXAxi4m2sIfxAS      : TXAxi4m2sIfxDO     <= TXAxi4m2sIfxD;
+        TXAxi4s2mIfxAS      : TXAxi4s2mIfxD      <= TXAxi4s2mIfxDI;
+        RXAxi4m2sLinksxAS   : RXAxi4m2sLinksxD   <= RXAxi4m2sLinksxDI;
+        RXAxi4s2mLinksxAS   : RXAxi4s2mLinksxDO  <= RXAxi4s2mLinksxD;
+        TXAxi4m2sLinksxAS   : TXAxi4m2sLinksxDO  <= TXAxi4m2sLinksxD;
+        TXAxi4s2mLinksxAS   : TXAxi4s2mLinksxD   <= TXAxi4s2mLinksxDI;
+        BookingVectorInxAS  : BookingVectorInxD  <= BookingVectorxDI;
+        BookingVectorOutxAS : BookingVectorxDO   <= BookingVectorOutxD;
+        SchedulerAckInxAS   : SchedulerAckInxD   <= SchedulerAckxDI;
+        SchedulerAckOutxAS  : SchedulerAckxDO    <= SchedulerAckOutxD;
+        QoSVectorxAS        : QoSVectorxD        <= QoSVectorxDI;
+    end block EntityIOxB;
+
+    ScalpTXSidexI : entity work.scalp_tx_side
+        generic map (
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE)
+        port map (
+            SysClkxCI             => SysClkxCI,
+            SysRstxRNAI           => SysRstxRNAI,
+            DstRouterNetAddrxDO   => DstRouterNetAddrxD,
+            RouterNetAddrValidxSO => RouterNetAddrValidxS,
+            BookingVectorValidxSI => BookingVectorValidxS,
+            -- SchedulerAckxDI       => SchedulerAckxD,
+            RXAxi4M2SLinkxDI      => RXAxi4m2sIfxD,
+            RXAxi4S2MLinkxDO      => RXAxi4s2mIfxD,
+            TXAxi4M2SLinkxDO      => TXAxi4M2SLinkxD,
+            TXAxi4S2MLinkxDI      => TXAxi4S2MLinkxD);
+
+    ScalpRXSidexI : entity work.scalp_rx_side
+        generic map (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_STRATEGY    => C_SCALP_SCHEDULER_STRATEGY,
+            C_SCALP_SCHEDULER_OUTPUT_REG  => C_SCALP_SCHEDULER_OUTPUT_REG)
+        port map (
+            SysClkxCI            => SysClkxCI,
+            SysRstxRNAI          => SysRstxRNAI,
+            SchedulerAckxDO      => SchedulerAckOutxD,
+            BookingVectorxDI     => BookingVectorInxD,
+            TXAxi4M2SLinkxDO     => TXAxi4m2sIfxD,
+            TXAxi4S2MLinkxDI     => TXAxi4s2mIfxD,
+            RXAxi4M2SLinkxDI     => RXAxi4m2sLinksxD,
+            RXAxi4S2MLinkxDO     => RXAxi4s2mLinksxD,
+            BookingIndexxDO      => open,
+            BookingIndexValidxSO => open);
+
+    ScalpRouterCorexI : entity work.scalp_router_core
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE => C_SCALP_INTERFACE_VECTOR_SIZE)
+        port map (
+            SysClkxCI             => SysClkxCI,
+            SysRstxRNAI           => SysRstxRNAI,
+            LocRouterNetAddrxDI   => LocRouterNetAddrxD,
+            DstRouterNetAddrxDI   => DstRouterNetAddrxD,
+            RouterNetAddrValidxSI => RouterNetAddrValidxS,
+            IfDstNumxDO           => IfDstNumxD,
+            IfNumValidxSO         => IfNumValidxS,
+            QoSVectorxDI          => QoSVectorxD);
+
+    ScalpSchedulerAckxI : entity work.scalp_scheduler_ack
+        generic map (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE)
+        port map (
+            SchedulerAckxDI => SchedulerAckInxD,
+            SchedulerAckxDO => SchedulerAckxD);
+
+    ScalpMatrixIndexxI : entity work.scalp_matrix_index
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE => C_SCALP_INTERFACE_VECTOR_SIZE)
+        port map (
+            IfSrcNumxDI      => IfSrcNumxD,
+            IfDstNumxDI      => IfDstNumxD,
+            IfNumValidxSI    => IfNumValidxS,
+            IfDstIdxxDO      => IfDstIdxxD,
+            IfDstIdxValidxSO => IfDstIdxValidxS);
+
+    ScalpBookingVectorxI : entity work.scalp_booking_vector
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE     => C_SCALP_INTERFACE_VECTOR_SIZE,
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE)
+        port map (
+            SysClkxCI             => SysClkxCI,
+            SysRstxRNAI           => SysRstxRNAI,
+            IfDstIdxxDI           => IfDstIdxxD,
+            IfDstIdxValidxSI      => IfDstIdxValidxS,
+            SchedulerAckxDI       => SchedulerAckxD,
+            BookingVectorxDO      => BookingVectorOutxD,
+            BookingVectorValidxSO => BookingVectorValidxS);
+
+    ScalpTXFanoutxI : entity work.scalp_tx_fanout
+        generic map (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE => C_SCALP_NEIGHBORS_VECTOR_SIZE)
+        port map (
+            RXAxi4M2SLinkxDI => TXAxi4M2SLinkxD,
+            RXAxi4S2MLinkxDO => TXAxi4S2MLinkxD,
+            TXAxi4M2SLinkxDO => TXAxi4m2sLinksxD,
+            TXAxi4S2MLinkxDI => TXAxi4s2mLinksxD);
+
+end architecture rtl;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_rx_side.vhd b/ips/hw/scalp_router/src/hdl/scalp_rx_side.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..b17fa25219edb849005208c5cd11aa7c1e7d06a7
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_rx_side.vhd
@@ -0,0 +1,230 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_rx_side.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp RX side state machine.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+
+entity scalp_rx_side is
+
+    generic (
+        C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255 := 6;
+        C_SCALP_SCHEDULER_STRATEGY    : string                 := "RR";
+        C_SCALP_SCHEDULER_OUTPUT_REG  : boolean                := true);
+
+    port (
+        -- System Clock and Reset
+        SysClkxCI            : in  std_ulogic;
+        SysRstxRNAI          : in  std_ulogic;
+        -- Scheduler Ack Vector
+        SchedulerAckxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Booking Vector
+        BookingVectorxDI     : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Axi4 Stream
+        -- Output Side
+        TXAxi4M2SLinkxDO     : out t_axi4m2s;
+        TXAxi4S2MLinkxDI     : in  t_axi4s2m;
+        -- Input Side
+        RXAxi4M2SLinkxDI     : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        RXAxi4S2MLinkxDO     : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        -- Debug Interface
+        BookingIndexxDO      : out integer range 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1);
+        BookingIndexValidxSO : out std_ulogic);
+
+end entity scalp_rx_side;
+
+architecture behavioral of scalp_rx_side is
+
+    component scalp_scheduler is
+        generic (
+            C_SCALP_STRATEGY   : string;
+            C_SCALP_PORTS      : positive;
+            C_SCALP_OUTPUT_REG : boolean);
+        port (
+            SysClkxCI        : in  std_ulogic;
+            SysRstxRNAI      : in  std_ulogic;
+            ArbitratexSI     : in  std_ulogic;
+            RequestVectorxDI : in  std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+            ArbitratedxSO    : out std_ulogic;
+            GrantVectorxDO   : out std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+            GrantIndexxDO    : out std_ulogic_vector((scalp_log2ceilnz(C_SCALP_PORTS) - 1) downto 0));
+    end component scalp_scheduler;
+
+    component scalp_fifo_double_register is
+        port (
+            -- System Clock and Reset
+            SysClkxCI      : in  std_ulogic;
+            SysRstxRNAI    : in  std_ulogic;
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI : in  t_axi4m2s;
+            Axiss2mLinkxDO : out t_axi4s2m;
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO : out t_axi4m2s;
+            Axiss2mLinkxDI : in  t_axi4s2m);
+    end component scalp_fifo_double_register;
+
+    -- Enity IO Signals
+    signal SchedulerAckxD   : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                   := (others => '0');
+    signal BookingVectorxDP : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                   := (others => '0');
+    signal BookingVectorxDN : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                   := (others => '0');
+    signal TXAxi4M2SLinkxD  : t_axi4m2s                                                                         := C_NO_AXI4_M2S;
+    signal TXAxi4S2MLinkxD  : t_axi4s2m                                                                         := C_NO_AXI4_S2M;
+    signal RXAxi4M2SLinkxD  : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                    := (others => C_NO_AXI4_M2S);
+    signal RXAxi4S2MLinkxD  : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                    := (others => C_NO_AXI4_S2M);
+    -- RR Scheduler Signals
+    signal ArbitratexS      : std_ulogic                                                                        := '0';
+    signal RequestVectorxDP : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                   := (others => '0');
+    signal RequestVectorxDN : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)                   := (others => '0');
+    signal ArbitratedxS     : std_ulogic                                                                        := '0';
+    -- signal GrantVectorxD    : std_ulogic_vector((C_SCALP_PORTS - 1) downto 0)                   := (others => '0');
+    signal GrantIndexxD     : std_ulogic_vector((scalp_log2ceilnz(C_SCALP_NEIGHBORS_VECTOR_SIZE) - 1) downto 0) := (others => '0');
+    -- Rx Side States    
+    signal RXSideStatexDP   : t_scalp_rx_side_states                                                            := E_SCALP_RX_IDLE;
+    signal RXSideStatexDN   : t_scalp_rx_side_states                                                            := E_SCALP_RX_IDLE;
+    -- Others    
+    signal ReadyInxD        : t_axi4s2m                                                                         := C_NO_AXI4_S2M;
+    signal Axism2sInxD      : t_axi4m2s                                                                         := C_NO_AXI4_M2S;
+    signal ReadyOutxD       : t_axi4s2m                                                                         := C_NO_AXI4_S2M;
+    signal EnPopNPushxS     : std_ulogic                                                                        := '0';
+
+begin  -- architecture behavioral
+
+    -- Asynchronous Statements
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        SchedulerAckxAS      : SchedulerAckxDO      <= SchedulerAckxD;
+        TXAxi4M2SLinkxAS     : TXAxi4M2SLinkxDO     <= TXAxi4M2SLinkxD;
+        TXAxi4S2MLinkxAS     : TXAxi4S2MLinkxD      <= TXAxi4S2MLinkxDI;
+        RXAxi4M2SLinkxAS     : RXAxi4M2SLinkxD      <= RXAxi4M2SLinkxDI;
+        RXAxi4S2MLinkxAS     : RXAxi4S2MLinkxDO     <= RXAxi4S2MLinkxD;
+        -- Debug Interface
+        BookingIndexxAS      : BookingIndexxDO      <= to_integer(unsigned(GrantIndexxD));
+        BookingIndexValidxAS : BookingIndexValidxSO <= ArbitratedxS;
+    end block EntityIOxB;
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+        ReadyInxAS : ReadyInxD <= TXAxi4S2MLinkxD when EnPopNPushxS = '1' else C_NO_AXI4_S2M;
+    end block AsyncStatementsxB;
+
+    -- Synchronous Statements
+
+    ScalpSchedulerxI : entity work.scalp_scheduler
+        generic map (
+            C_SCALP_STRATEGY   => C_SCALP_SCHEDULER_STRATEGY,
+            C_SCALP_PORTS      => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_OUTPUT_REG => C_SCALP_SCHEDULER_OUTPUT_REG)
+        port map (
+            SysClkxCI        => SysClkxCI,
+            SysRstxRNAI      => SysRstxRNAI,
+            ArbitratexSI     => ArbitratexS,
+            RequestVectorxDI => RequestVectorxDP,
+            ArbitratedxSO    => ArbitratedxS,
+            GrantVectorxDO   => open,
+            GrantIndexxDO    => GrantIndexxD);
+
+    ScalpFifoDoubleRegisterxI : entity work.scalp_fifo_double_register
+        port map (
+            -- System Clock and Reset
+            SysClkxCI      => SysClkxCI,
+            SysRstxRNAI    => SysRstxRNAI,
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI => Axism2sInxD,
+            Axiss2mLinkxDO => ReadyOutxD,
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO => TXAxi4M2SLinkxD,
+            Axiss2mLinkxDI => ReadyInxD);
+
+    UpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process UpdateRegxP
+        if SysRstxRNAI = '0' then
+            RXSideStatexDP   <= E_SCALP_RX_IDLE;
+            RequestVectorxDP <= (others => '0');
+        elsif rising_edge(SysClkxCI) then
+            RXSideStatexDP   <= RXSideStatexDN;
+            RequestVectorxDP <= RequestVectorxDN;
+        end if;
+    end process UpdateRegxP;
+
+    RxSideStateMachinexP : process (ArbitratedxS, BookingVectorxDI,
+                                    GrantIndexxD, RXAxi4M2SLinkxD,
+                                    RXSideStatexDP, ReadyOutxD,
+                                    TXAxi4M2SLinkxD.LastxS) is
+    begin  -- process RxSideStateMachinexP
+        -- Default values
+        RXSideStatexDN   <= RXSideStatexDP;
+        RequestVectorxDN <= (others => '0');
+        SchedulerAckxD   <= (others => '0');
+        ArbitratexS      <= '0';
+        EnPopNPushxS     <= '0';
+        -- All RX Ready to 0
+        RXAxi4S2MLinkxD  <= (others => C_NO_AXI4_S2M);
+        Axism2sInxD      <= C_NO_AXI4_M2S;
+
+        case RXSideStatexDP is
+            when E_SCALP_RX_IDLE =>
+                    if to_integer(unsigned(BookingVectorxDI)) /= 0 then
+                        RequestVectorxDN <= BookingVectorxDI;
+                        RXSideStatexDN   <= E_SCALP_RX_ARBITRATE;
+                    end if;
+
+            when E_SCALP_RX_ARBITRATE =>
+                    ArbitratexS    <= '1';
+                    RXSideStatexDN <= E_SCALP_RX_WAIT_ARBITRATED;
+
+            when E_SCALP_RX_WAIT_ARBITRATED =>
+                    if ArbitratedxS = '1' then
+                        RXSideStatexDN <= E_SCALP_RX_POP_N_PUSH;
+                    end if;
+
+            when E_SCALP_RX_POP_N_PUSH =>
+                    RXAxi4S2MLinkxD(to_integer(unsigned(GrantIndexxD))) <= ReadyOutxD;
+                    Axism2sInxD                                         <= RXAxi4M2SLinkxD(to_integer(unsigned(GrantIndexxD)));
+                    EnPopNPushxS                                        <= '1';
+
+                    if TXAxi4M2SLinkxD.LastxS = '1' then
+                        RXSideStatexDN <= E_SCALP_RX_ACK;
+                    end if;
+
+            when E_SCALP_RX_ACK =>
+                    SchedulerAckxD(to_integer(unsigned(GrantIndexxD))) <= '1';
+                    -- if to_integer(unsigned(BookingVectorxDI)) /= 0 then
+                    --     RXSideStatexDN <= E_SCALP_RX_ARBITRATE;
+                    -- else
+                    RXSideStatexDN                                     <= E_SCALP_RX_IDLE;
+                    -- end if;
+
+            when others => null;
+        end case;
+    end process RxSideStateMachinexP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_scheduler.vhd b/ips/hw/scalp_router/src/hdl/scalp_scheduler.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..1d9d5ff09ac1b909f6aae9975b160db63a627e02
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_scheduler.vhd
@@ -0,0 +1,129 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_scheduler.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Generic Round Robin or Random Scheduler.
+--
+-- Last update: 2020-01-17
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.scalp_misc.all;
+-- use work.scalp_utility.all;
+
+entity scalp_scheduler is
+
+    generic (
+        C_SCALP_STRATEGY   : string   := "RR";  -- RR or RAND
+        C_SCALP_PORTS      : positive := 6;
+        C_SCALP_OUTPUT_REG : boolean  := true);
+
+    port (
+        -- Sys Clock and Sys Reset
+        SysClkxCI        : in  std_ulogic;
+        SysRstxRNAI      : in  std_ulogic;
+        -- Request Side
+        ArbitratexSI     : in  std_ulogic;
+        RequestVectorxDI : in  std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+        -- Grant Side
+        ArbitratedxSO    : out std_ulogic;
+        GrantVectorxDO   : out std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+        GrantIndexxDO    : out std_ulogic_vector((scalp_log2ceilnz(C_SCALP_PORTS) - 1) downto 0));
+
+end entity scalp_scheduler;
+
+architecture behavioral of scalp_scheduler is
+
+begin  -- architecture behavioral
+    -- Assert C_SCALP_STRATEGY for known strings
+    assert ((C_SCALP_STRATEGY = "RR"))  -- or (C_SCALP_STRATEGY = "RAND"))
+        report "Unknow scheduler strategy." severity failure;
+
+    -- Round Robin Scheduler (with RR strategy)
+    RRStrategyxG : if C_SCALP_STRATEGY = "RR" generate
+        signal RequestLeftxD      : unsigned((C_SCALP_PORTS - 1) downto 0)          := (others => '0');
+        signal SelectLeftxD       : unsigned((C_SCALP_PORTS - 1) downto 0)          := (others => '0');
+        signal SelectRightxD      : unsigned((C_SCALP_PORTS - 1) downto 0)          := (others => '0');
+        signal ChannelPointerEnxS : std_ulogic                                      := '0';
+        signal ChannelPointerxDP  : std_ulogic_vector((C_SCALP_PORTS - 1) downto 0) := scalp_to_sulv(1, C_SCALP_PORTS);
+        signal ChannelPointerxDN  : std_ulogic_vector((C_SCALP_PORTS - 1) downto 0) := (others => '0');
+    begin
+
+        GlobalAsyncStatementsxB : block is
+        begin  -- block GlobalAsyncStatementsxB
+            ChannelPointerEnxAS : ChannelPointerEnxS <= ArbitratexSI;
+            RequestLeftxAS      : RequestLeftxD      <= (not ((unsigned(ChannelPointerxDP) - 1) or unsigned(ChannelPointerxDP)) and unsigned(RequestVectorxDI));
+            SelectLeftxAS       : SelectLeftxD       <= (unsigned(not RequestLeftxD) + 1) and RequestLeftxD;
+            SelectRightxAS      : SelectRightxD      <= (unsigned(not RequestVectorxDI) + 1) and unsigned(RequestVectorxDI);
+            ChannelPointerxAS   : ChannelPointerxDN  <= std_ulogic_vector(scalp_ite((RequestLeftxD = (RequestLeftxD'range => '0')), SelectRightxD, SelectLeftxD));
+        end block GlobalAsyncStatementsxB;
+
+        SchedulerxB : block is
+        begin  -- block SchedulerxB            
+            OutRegxG : if not C_SCALP_OUTPUT_REG generate  -- Without Output Register
+                AsyncStatementsxB : block is
+                begin  -- block AsyncStatementsxB
+                    ArbitratedxAS  : ArbitratedxSO  <= ArbitratexSI;
+                    GrantVectorxAS : GrantVectorxDO <= ChannelPointerxDN;
+                    GrantIndexxAS  : GrantIndexxDO  <= std_ulogic_vector(scalp_onehot2bin(ChannelPointerxDN));
+                end block AsyncStatementsxB;
+
+                UpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+                begin  -- process UpdateRegxP
+                    if SysRstxRNAI = '0' then
+                        ChannelPointerxDP <= scalp_to_sulv(1, C_SCALP_PORTS);
+                    elsif rising_edge(SysClkxCI) then
+                        if ChannelPointerEnxS = '1' then
+                            ChannelPointerxDP <= ChannelPointerxDN;
+                        end if;
+                    end if;
+                end process UpdateRegxP;
+            elsif C_SCALP_OUTPUT_REG generate  -- With Output Register
+                signal ChannelPointerBinxDP : std_ulogic_vector((scalp_log2ceilnz(C_SCALP_PORTS) - 1) downto 0) := (others => '0');
+            begin
+                AsyncStatementsxB : block is
+                begin  -- block AsyncStatementsxB
+                    ArbitratedxAS  : ArbitratedxSO  <= ArbitratexSI when rising_edge(SysClkxCI);
+                    GrantVectorxAS : GrantVectorxDO <= ChannelPointerxDP;
+                    GrantIndexxAS  : GrantIndexxDO  <= ChannelPointerBinxDP;
+                end block AsyncStatementsxB;
+
+                UpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+                begin  -- process UpdateRegxP
+                    if SysRstxRNAI = '0' then
+                        ChannelPointerxDP    <= scalp_to_sulv(1, C_SCALP_PORTS);
+                        ChannelPointerBinxDP <= (others => '0');
+                    elsif rising_edge(SysClkxCI) then
+                        if ChannelPointerEnxS = '1' then
+                            ChannelPointerxDP    <= ChannelPointerxDN;
+                            ChannelPointerBinxDP <= std_ulogic_vector(scalp_onehot2bin(ChannelPointerxDN));
+                        end if;
+                    end if;
+                end process UpdateRegxP;
+            end generate OutRegxG;
+        end block SchedulerxB;
+    end generate RRStrategyxG;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_scheduler_ack.vhd b/ips/hw/scalp_router/src/hdl/scalp_scheduler_ack.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..c74b8726a38181d9b02268abb47032c5eda5e0b2
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_scheduler_ack.vhd
@@ -0,0 +1,68 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_scheduler_ack.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp Scheduler Acknowledge.
+--
+-- Last update: 2019-11-22
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+-- use work.utility.all;
+
+entity scalp_scheduler_ack is
+
+    generic (
+        C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255 := 6;
+        C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255 := 1);
+
+    port (
+        SchedulerAckxDI : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        SchedulerAckxDO : out std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0));
+
+end entity scalp_scheduler_ack;
+
+architecture dataflow of scalp_scheduler_ack is
+
+    signal InSchedulerAckxD  : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal OutSchedulerAckxD : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+
+begin  -- architecture dataflow
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+
+        InSchedulerAckxAS  : InSchedulerAckxD <= SchedulerAckxDI;
+        OutSchedulerAckxAS : SchedulerAckxDO  <= OutSchedulerAckxD;
+
+    end block EntityIOxB;
+
+    MuxInVectorxB : block is
+    begin  -- block MuxInVectorxB
+
+        OrReduceInSchedulerAckxAS : OutSchedulerAckxD(0) <= or_reduce(InSchedulerAckxD);
+
+    end block MuxInVectorxB;
+
+end architecture dataflow;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_sim_packets.vhd b/ips/hw/scalp_router/src/hdl/scalp_sim_packets.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..74ed3bb2fa3e85374418ad0224e4e7b9ec7661aa
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_sim_packets.vhd
@@ -0,0 +1,311 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_sim_packets.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2018.2
+-- Description: Scalp Packets For Simulation
+--
+-- Last update: 2020-02-26
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.scalp_misc.all;
+
+package scalp_sim_packets is
+
+    constant C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+
+    ---------------------------------------------------------------------------
+    -- Scalp Network Address
+    ---------------------------------------------------------------------------
+    constant C_SCALP_NET_ADDR_121 : t_scalp_netaddr := (XxD => 1, YxD => 2, ZxD => 1);
+    constant C_SCALP_NET_ADDR_211 : t_scalp_netaddr := (XxD => 2, YxD => 1, ZxD => 1);
+    constant C_SCALP_NET_ADDR_101 : t_scalp_netaddr := (XxD => 1, YxD => 0, ZxD => 1);
+    constant C_SCALP_NET_ADDR_011 : t_scalp_netaddr := (XxD => 0, YxD => 1, ZxD => 1);
+    constant C_SCALP_NET_ADDR_112 : t_scalp_netaddr := (XxD => 1, YxD => 1, ZxD => 2);
+    constant C_SCALP_NET_ADDR_110 : t_scalp_netaddr := (XxD => 1, YxD => 1, ZxD => 0);
+    constant C_SCALP_NET_ADDR_111 : t_scalp_netaddr := (XxD => 1, YxD => 1, ZxD => 1);
+
+    ---------------------------------------------------------------------------
+    -- Scalp Packets
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    -- Scalp Packet Headers
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_NULL       : t_scalp_packet_header := C_NO_SCALP_PACKET_HEADER;
+    -- From North 121
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_121_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_121_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_121_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_121_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_121_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_121_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_121,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From East 211
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_211_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_211_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_211_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_211_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_211_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_211_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_211,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From South 101
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_101_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_101_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_101_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_101_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_101_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_101_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_101,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From West 011
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_011_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_011_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_011_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_011_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_011_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_011_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_011,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From Top 112
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_112_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_112_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_112_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_112_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_112_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_112_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_112,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From Bottom 110
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_110_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_110_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_110_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_110_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_110_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_110_TO_111 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_111,
+            SrcAddrxD => C_SCALP_NET_ADDR_110,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- From Local 111
+    ---------------------------------------------------------------------------
+    constant C_SP_HEADER_111_TO_121 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_121,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_111_TO_211 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_211,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_111_TO_101 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_101,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_111_TO_011 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_011,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_111_TO_112 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_112,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    constant C_SP_HEADER_111_TO_110 : t_scalp_packet_header
+        := (DstAddrxD => C_SCALP_NET_ADDR_110,
+            SrcAddrxD => C_SCALP_NET_ADDR_111,
+            TypexD    => 1,
+            LengthxD  => C_SCALP_PACKET_PAYLOAD_SIZE);
+    ---------------------------------------------------------------------------
+    -- Scalp Packet Payloads
+    ---------------------------------------------------------------------------
+    constant C_SP_PAYLOAD_NULL : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 => C_NO_SCALP_PACKET_WORD,
+            1 => C_NO_SCALP_PACKET_WORD,
+            2 => C_NO_SCALP_PACKET_WORD,
+            3 => C_NO_SCALP_PACKET_WORD,
+            4 => C_NO_SCALP_PACKET_WORD,
+            5 => C_NO_SCALP_PACKET_WORD,
+            6 => C_NO_SCALP_PACKET_WORD,
+            7 => C_NO_SCALP_PACKET_WORD);
+    constant C_SP_PAYLOAD_0 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#01223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#02334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));    
+
+end package scalp_sim_packets;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_sp_to_axis.vhd b/ips/hw/scalp_router/src/hdl/scalp_sp_to_axis.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7363468c5ae1832154db78d02592328c5454bf7a
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_sp_to_axis.vhd
@@ -0,0 +1,238 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_sp_to_axis.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp Packet to AXI Stream converter.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+-- 31      23      15      7       0
+--  0       7      15     23      31
+--     8       8       8       8
+-- ---------------------------------
+-- | x_dst | y_dst | z_dst | type  |
+-- ---------------------------------
+-- | x_src | y_srd | z_src |  pad  |
+-- ---------------------------------
+--        16              16
+-- ---------------------------------
+-- | payload_size  |     pad       |
+-- ---------------------------------
+--
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+--                .
+--                .
+--                .
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+
+-- Register map
+--
+-- 31                              0
+-- ---------------------------------
+-- |             H0                | Dst addr + Type
+-- ---------------------------------
+-- ---------------------------------
+-- |             H1                | Src addr + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |             H2                | Pld size + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |              P                | N x Payload
+-- ---------------------------------
+
+entity scalp_sp_to_axis is
+
+    generic (
+        C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8);
+
+    port (
+        -- Sys clk and sys nrst
+        SysClkxCI           : in  std_ulogic;
+        SysRstxRNAI         : in  std_ulogic;
+        -- Scalp Packet
+        ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+        ScalpPacketValidxSI : in  std_ulogic;
+        -- Axis
+        ScalpAxism2sxDO     : out t_axi4m2s;
+        ScalpAxiss2mxDI     : in  t_axi4s2m;
+        -- Ready for new packet
+        ScalpRdyxSO         : out std_ulogic);
+
+end entity scalp_sp_to_axis;
+
+architecture behavioral of scalp_sp_to_axis is
+
+    -- Signals
+    signal ScalpAxism2sxD      : t_axi4m2s                                            := C_NO_AXI4_M2S;
+    signal ScalpAxiss2mxD      : t_axi4s2m                                            := C_NO_AXI4_S2M;
+    signal ScalpPacketStatexDP : t_scalp_packet_states                                := E_SP_IDLE;
+    signal ScalpPacketStatexDN : t_scalp_packet_states                                := E_SP_IDLE;
+    signal ScalpPacketCntxDP   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 0;
+    signal ScalpPacketCntxDN   : integer range 0 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 0;
+    signal ScalpPacketValidxS  : std_ulogic                                           := '0';
+    signal ScalpPacketxD       : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)))
+        := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+            SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    -- Axis Registers
+    signal DataxDP    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    signal DataxDN    : std_ulogic_vector((C_AXI4_DATA_SIZE - 1) downto 0) := (others => '0');
+    -- Others
+    signal ScalpRdyxS : std_ulogic                                         := '0';
+
+begin  -- architecture behavioral
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        ScalpPacketxAS      : ScalpPacketxD      <= ScalpPacketxDI;
+        ScalpPacketValidxAS : ScalpPacketValidxS <= ScalpPacketValidxSI;
+        ScalpAxism2sxAS     : ScalpAxism2sxDO    <= ScalpAxism2sxD;
+        ScalpAxiss2mxAS     : ScalpAxiss2mxD     <= ScalpAxiss2mxDI;
+        ScalpRdyxAS         : ScalpRdyxSO        <= ScalpRdyxS;
+    end block EntityIOxB;
+
+    -- Mémorisation des états
+    StateMachineUpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process StateMachineUpdateRegxP
+        if SysRstxRNAI = '0' then
+            ScalpPacketStatexDP <= E_SP_IDLE;
+            ScalpPacketCntxDP   <= 0;
+            DataxDP             <= (others => '0');
+        elsif rising_edge(SysClkxCI) then
+            ScalpPacketStatexDP <= ScalpPacketStatexDN;
+            ScalpPacketCntxDP   <= ScalpPacketCntxDN;
+            DataxDP             <= DataxDN;
+        end if;
+    end process StateMachineUpdateRegxP;
+
+    -- Combinatoire des états
+    SpToAxisOutAndStatesCombinatoricxP : process (DataxDP,
+                                                  ScalpAxiss2mxD.ReadyxS,
+                                                  ScalpPacketCntxDP,
+                                                  ScalpPacketStatexDP,
+                                                  ScalpPacketValidxS,
+                                                  ScalpPacketxD.SpHeaderxD,
+                                                  ScalpPacketxD.SpHeaderxD.LengthxD,
+                                                  ScalpPacketxD.SpPayloadxD) is
+    begin  -- process SpToAxisOutAndStatesCombinatoricxP
+        -- Default values
+        -- State and counter
+        ScalpPacketStatexDN    <= ScalpPacketStatexDP;
+        ScalpPacketCntxDN      <= ScalpPacketCntxDP;
+        -- Axis
+        DataxDN                <= DataxDP;
+        ScalpAxism2sxD.DataxD  <= (others => '0');
+        ScalpAxism2sxD.KeepxD  <= (others => '1');
+        ScalpAxism2sxD.LastxS  <= '0';
+        ScalpAxism2sxD.ValidxS <= '0';
+        ScalpRdyxS             <= '0';
+
+        case ScalpPacketStatexDP is
+            when E_SP_IDLE =>
+                    ScalpRdyxS <= '1';
+
+                    if ScalpPacketValidxS = '1' then
+                        DataxDN             <= scalp_sp_header_h0_to_axis_ul(ScalpPacketxD.SpHeaderxD);
+                        ScalpRdyxS          <= '0';
+                        ScalpPacketStatexDN <= E_SP_H0;
+                    end if;
+
+            when E_SP_H0 =>
+                    -- Extract word with convert data from little endian to big endian.
+                    ScalpAxism2sxD.DataxD  <= DataxDP;
+                    ScalpAxism2sxD.ValidxS <= '1';
+
+                    if ScalpAxiss2mxD.ReadyxS = '1' then
+                        DataxDN             <= scalp_sp_header_h1_to_axis_ul(ScalpPacketxD.SpHeaderxD);
+                        ScalpPacketStatexDN <= E_SP_H1;
+                    end if;
+
+            when E_SP_H1 =>
+                    -- Extract word with convert data from little endian to big endian.
+                    ScalpAxism2sxD.DataxD  <= DataxDP;
+                    ScalpAxism2sxD.ValidxS <= '1';
+
+                    if ScalpAxiss2mxD.ReadyxS = '1' then
+                        DataxDN             <= scalp_sp_header_h2_to_axis_ul(ScalpPacketxD.SpHeaderxD);
+                        ScalpPacketStatexDN <= E_SP_H2;
+                    end if;
+
+            when E_SP_H2 =>
+                    -- Extract word with convert data from little endian to big endian.
+                    ScalpAxism2sxD.DataxD  <= DataxDP;
+                    ScalpAxism2sxD.ValidxS <= '1';
+
+                    if ScalpAxiss2mxD.ReadyxS = '1' then
+                        if ScalpPacketxD.SpHeaderxD.LengthxD <= 0 then
+                            ScalpPacketCntxDN   <= 0;
+                            ScalpPacketStatexDN <= E_SP_IDLE;
+                        else
+                            DataxDN             <= scalp_sp_payload_p_to_axis_ul(ScalpPacketxD.SpPayloadxD, ScalpPacketCntxDP);
+                            ScalpPacketCntxDN   <= ScalpPacketCntxDP + 1;
+                            ScalpPacketStatexDN <= E_SP_P;
+                        end if;
+                    end if;
+
+            when E_SP_P =>
+                    ScalpAxism2sxD.DataxD  <= DataxDP;
+                    ScalpAxism2sxD.ValidxS <= '1';
+
+                    if ScalpAxiss2mxD.ReadyxS = '1' then
+                        if ScalpPacketCntxDP >= (ScalpPacketxD.SpHeaderxD.LengthxD - 1) then
+                            DataxDN             <= scalp_sp_payload_p_to_axis_ul(ScalpPacketxD.SpPayloadxD, ScalpPacketCntxDP);
+                            ScalpPacketStatexDN <= E_SP_P_LAST;
+                        else
+                            DataxDN <= scalp_sp_payload_p_to_axis_ul(ScalpPacketxD.SpPayloadxD, ScalpPacketCntxDP);
+                        end if;
+
+                        ScalpPacketCntxDN <= ScalpPacketCntxDP + 1;
+                    end if;
+
+            when E_SP_P_LAST =>
+                    ScalpAxism2sxD.DataxD  <= DataxDP;
+                    ScalpAxism2sxD.ValidxS <= '1';
+                    ScalpAxism2sxD.LastxS  <= '1';
+
+                    if ScalpAxiss2mxD.ReadyxS = '1' then
+                        ScalpPacketCntxDN   <= 0;
+                        ScalpPacketStatexDN <= E_SP_IDLE;
+                    end if;
+
+            when others => null;
+        end case;
+
+    end process SpToAxisOutAndStatesCombinatoricxP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_tx_fanout.vhd b/ips/hw/scalp_router/src/hdl/scalp_tx_fanout.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..32875001c975282af9a5dfac33ff1f4724d54a9d
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_tx_fanout.vhd
@@ -0,0 +1,84 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_tx_fanout.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Spread of the AXI4 Stream bus.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+-- use work.utility.all;
+use work.axi4_pkg.all;
+
+entity scalp_tx_fanout is
+
+    generic (
+        C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255 := 6);
+
+    port (
+        -- RX Side
+        RXAxi4M2SLinkxDI : in  t_axi4m2s;
+        RXAxi4S2MLinkxDO : out t_axi4s2m;
+        -- TX Side
+        TXAxi4M2SLinkxDO : out t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+        TXAxi4S2MLinkxDI : in  t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0));
+
+end entity scalp_tx_fanout;
+
+architecture dataflow of scalp_tx_fanout is
+
+    signal RXAxi4M2SLinkxD : t_axi4m2s                                                      := C_NO_AXI4_M2S;
+    signal RXAxi4S2MLinkxD : t_axi4s2m                                                      := C_NO_AXI4_S2M;
+    signal TXAxi4M2SLinkxD : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => C_NO_AXI4_M2S);
+    signal TXAxi4S2MLinkxD : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => C_NO_AXI4_S2M);
+
+begin  -- architecture dataflow
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+
+        -- RX Side
+        RXAxi4M2SLinkxAS : RXAxi4M2SLinkxD  <= RXAxi4M2SLinkxDI;
+        RXAxi4S2MLinkxAS : RXAxi4S2MLinkxDO <= RXAxi4S2MLinkxD;
+        -- TX Side
+        TXAxi4M2SLinkxAS : TXAxi4M2SLinkxDO <= TXAxi4M2SLinkxD;
+        TXAxi4S2MLinkxAS : TXAxi4S2MLinkxD  <= TXAxi4S2MLinkxDI;
+
+    end block EntityIOxB;
+
+    Axi4FanoutxB : block is
+    begin  -- block Axi4FanoutxB
+
+        RXAxi4S2MLinkxAS : RXAxi4S2MLinkxD <= or_reduce_t_axi4s2m_vector(TXAxi4S2MLinkxD);
+
+        Axi4M2SFanoutxG : for i in 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) generate
+
+            TXAxi4M2SLinkxAS : TXAxi4M2SLinkxD(i) <= RXAxi4M2SLinkxD;
+
+        end generate Axi4M2SFanoutxG;
+
+    end block Axi4FanoutxB;
+
+end architecture dataflow;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_tx_side.vhd b/ips/hw/scalp_router/src/hdl/scalp_tx_side.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..18e87957c82f1a54cfefcc9436a30d27a524123c
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_tx_side.vhd
@@ -0,0 +1,179 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_tx_side.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Scalp TX side state machine.
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+
+entity scalp_tx_side is
+
+    generic (
+        C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255 := 1);
+
+    port (
+        -- System Clock and Reset
+        SysClkxCI             : in  std_ulogic;
+        SysRstxRNAI           : in  std_ulogic;
+        -- Routeur Network Address
+        DstRouterNetAddrxDO   : out t_scalp_netaddr;
+        RouterNetAddrValidxSO : out std_ulogic;
+        -- Indicates when the booking vector is valid.
+        BookingVectorValidxSI : in  std_ulogic;
+        -- Scheduler Acknowledgement Vector
+        -- SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+        -- Axi4 Stream
+        -- Input side
+        RXAxi4M2SLinkxDI      : in  t_axi4m2s;
+        RXAxi4S2MLinkxDO      : out t_axi4s2m;
+        -- Output Side
+        TXAxi4M2SLinkxDO      : out t_axi4m2s;
+        TXAxi4S2MLinkxDI      : in  t_axi4s2m);
+
+end entity scalp_tx_side;
+
+architecture behavioral of scalp_tx_side is
+
+    component scalp_fifo_double_register is
+        port (
+            -- System Clock and Reset
+            SysClkxCI      : in  std_ulogic;
+            SysRstxRNAI    : in  std_ulogic;
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI : in  t_axi4m2s;
+            Axiss2mLinkxDO : out t_axi4s2m;
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO : out t_axi4m2s;
+            Axiss2mLinkxDI : in  t_axi4s2m);
+    end component scalp_fifo_double_register;
+
+    signal DstRouterNetAddrxDP   : t_scalp_netaddr        := C_3D_MIN_SCALP_NETADDR;
+    signal DstRouterNetAddrxDN   : t_scalp_netaddr        := C_3D_MIN_SCALP_NETADDR;
+    signal RouterNetAddrValidxSP : std_ulogic             := '0';
+    signal RouterNetAddrValidxSN : std_ulogic             := '0';
+    signal BookingVectorValidxS  : std_ulogic             := '0';
+    -- signal SchedulerAckxD        : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal RXAxi4M2SLinkxD       : t_axi4m2s              := C_NO_AXI4_M2S;
+    signal RXAxi4S2MLinkxD       : t_axi4s2m              := C_NO_AXI4_S2M;
+    signal TXAxi4M2SLinkxD       : t_axi4m2s              := C_NO_AXI4_M2S;
+    signal TXAxi4S2MLinkxD       : t_axi4s2m              := C_NO_AXI4_S2M;
+    -- TX Side States
+    signal TXSideStatexDP        : t_scalp_tx_side_states := E_SCALP_TX_IDLE;
+    signal TXSideStatexDN        : t_scalp_tx_side_states := E_SCALP_TX_IDLE;
+    -- Others
+    signal ReadyInxD             : t_axi4s2m              := C_NO_AXI4_S2M;
+    signal EnPopNPushxS          : std_ulogic             := '0';
+
+begin  -- architecture behavioral
+
+    -- Asynchronous Statements
+
+    EntityIOxB : block is
+    begin  -- block EntityIOxB
+        DstRouterNetAddrxAS   : DstRouterNetAddrxDO   <= DstRouterNetAddrxDP;
+        -- SchedulerAckxAS       : SchedulerAckxD        <= SchedulerAckxDI;
+        RXAxi4M2SLinkxAS      : RXAxi4M2SLinkxD       <= RXAxi4M2SLinkxDI;
+        RXAxi4S2MLinkxAS      : RXAxi4S2MLinkxDO      <= RXAxi4S2MLinkxD;
+        TXAxi4M2SLinkxAS      : TXAxi4M2SLinkxDO      <= TXAxi4M2SLinkxD;
+        TXAxi4S2MLinkxAS      : TXAxi4S2MLinkxD       <= TXAxi4S2MLinkxDI;
+        RouterNetAddrValidxAS : RouterNetAddrValidxSO <= RouterNetAddrValidxSP;
+        BookingVectorValidxAS : BookingVectorValidxS  <= BookingVectorValidxSI;
+    end block EntityIOxB;
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+        ReadyInxAS : ReadyInxD <= TXAxi4S2MLinkxD when EnPopNPushxS = '1' else C_NO_AXI4_S2M;
+    end block AsyncStatementsxB;
+
+    -- Synchronous Statements
+
+    ScalpFifoDoubleRegisterxI : entity work.scalp_fifo_double_register
+        port map (
+            -- System Clock and Reset
+            SysClkxCI      => SysClkxCI,
+            SysRstxRNAI    => SysRstxRNAI,
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI => RXAxi4M2SLinkxD,
+            Axiss2mLinkxDO => RXAxi4S2MLinkxD,
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO => TXAxi4M2SLinkxD,
+            Axiss2mLinkxDI => ReadyInxD);
+
+    UpdateRegxP : process (SysClkxCI, SysRstxRNAI) is
+    begin  -- process UpdateRegxP
+        if SysRstxRNAI = '0' then
+            TXSideStatexDP        <= E_SCALP_TX_IDLE;
+            DstRouterNetAddrxDP   <= C_3D_MIN_SCALP_NETADDR;
+            RouterNetAddrValidxSP <= '0';
+        elsif rising_edge(SysClkxCI) then
+            TXSideStatexDP        <= TXSideStatexDN;
+            DstRouterNetAddrxDP   <= DstRouterNetAddrxDN;
+            RouterNetAddrValidxSP <= RouterNetAddrValidxSN;
+        end if;
+    end process UpdateRegxP;
+
+    TXSideStateMachinexP : process (BookingVectorValidxS, DstRouterNetAddrxDP,
+                                    RXAxi4M2SLinkxD.DataxD,
+                                    RXAxi4M2SLinkxD.ValidxS,
+                                    TXAxi4M2SLinkxD.LastxS, TXSideStatexDP) is
+    begin  -- process TXSideStateMachinexP
+        -- Default values
+        TXSideStatexDN        <= TXSideStatexDP;
+        DstRouterNetAddrxDN   <= DstRouterNetAddrxDP;
+        RouterNetAddrValidxSN <= '0';
+        EnPopNPushxS          <= '0';
+
+        case TXSideStatexDP is
+            when E_SCALP_TX_IDLE =>
+                    -- Si un paquet scalp est présent, on lit le premier mot
+                    -- pour en extraire l'adresse de destination.
+                    if RXAxi4M2SLinkxD.ValidxS = '1' then
+                        DstRouterNetAddrxDN   <= scalp_peek_addr_ul(RXAxi4M2SLinkxD.DataxD);
+                        RouterNetAddrValidxSN <= '1';
+                        TXSideStatexDN        <= E_SCALP_TX_WAIT_BOOKING_VECTOR;
+                    end if;
+
+            when E_SCALP_TX_WAIT_BOOKING_VECTOR =>
+                    if BookingVectorValidxS = '1' then
+                        EnPopNPushxS   <= '1';
+                        TXSideStatexDN <= E_SCALP_TX_POP_N_PUSH;
+                    end if;
+
+            when E_SCALP_TX_POP_N_PUSH =>
+                    EnPopNPushxS <= '1';
+
+                    if TXAxi4M2SLinkxD.LastxS = '1' then
+                        TXSideStatexDN <= E_SCALP_TX_IDLE;
+                    end if;
+
+            when others => null;
+        end case;
+    end process TXSideStateMachinexP;
+
+end architecture behavioral;
diff --git a/ips/hw/scalp_router/src/hdl/scalp_utility.vhd b/ips/hw/scalp_router/src/hdl/scalp_utility.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..b1f14989a03b3b5e0aec4dc51786c97be8bb0c22
--- /dev/null
+++ b/ips/hw/scalp_router/src/hdl/scalp_utility.vhd
@@ -0,0 +1,678 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: scalp_utility.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2018.2
+-- Description: Scalp Utility
+--
+-- Last update: 2020-02-04
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use std.textio.all;
+
+package scalp_utility is
+
+    -- prints a message to the screen
+    procedure print(text : string);
+
+    -- prints the message when active
+    -- useful for debug switches
+    procedure print(active : boolean;
+                    text   : string);
+
+    -- converts std_ulogic into a character
+    function uchr(sul : std_ulogic)
+        return character;
+
+    -- converts std_logic into a character
+    function chr(sl : std_logic)
+        return character;
+
+    -- converts std_ulogic into a string (1 to 1)
+    function ustr(sul : std_ulogic)
+        return string;
+
+    -- converts std_logic into a string (1 to 1)
+    function str(sl : std_logic)
+        return string;
+
+    -- converts std_ulogic_vector into a string (binary base)
+    function str_ul(slv : std_ulogic_vector)
+        return string;
+
+    -- converts std_logic_vector into a string (binary base)
+    function str(slv : std_logic_vector)
+        return string;
+
+    -- converts boolean into a string
+    function str(b : boolean)
+        return string;
+
+    -- converts an integer into a single character
+    -- (can also be used for hex conversion and other bases)
+    function chr(int : integer)
+        return character;
+
+    -- converts integer into string using specified base
+    function str(int  : integer;
+                 base : integer)
+        return string;
+
+    -- converts integer to string, using base 10
+    function str(int : integer)
+        return string;
+
+    -- convert std_ulogic_vector into a string in hex format
+    function hstr_ul(slv : std_ulogic_vector)
+        return string;
+
+    -- convert std_logic_vector into a string in hex format
+    function hstr(slv : std_logic_vector)
+        return string;
+
+    -- functions to manipulate strings
+    -----------------------------------
+
+    -- convert a character to upper case
+    function to_upper(c : character)
+        return character;
+
+    -- convert a character to lower case
+    function to_lower(c : character)
+        return character;
+
+    -- convert a string to upper case
+    function to_upper(s : string)
+        return string;
+
+    -- convert a string to lower case
+    function to_lower(s : string)
+        return string;
+
+    -- functions to convert strings into other formats
+    --------------------------------------------------
+
+    -- converts a character into std_ulogic
+    function to_std_ulogic(c : character)
+        return std_ulogic;
+
+    -- converts a character into std_ulogic
+    function to_std_logic(c : character)
+        return std_logic;
+
+    -- converts a string into std_ulogic_vector
+    function to_std_ulogic_vector(s : string)
+        return std_ulogic_vector;
+
+    -- converts a string into std_ulogic_vector
+    function to_std_logic_vector(s : string)
+        return std_logic_vector;
+
+    -- file I/O
+    -----------
+
+    -- read variable length string from input file
+    procedure str_read(file in_file :     text;
+                       res_string   : out string);
+
+    -- print string to a file and start new line
+    procedure print(file out_file :    text;
+                    new_string    : in string);
+
+    -- print character to a file and start new line
+    procedure print(file out_file :    text;
+                    char          : in character);
+
+    function string_fill(msg : string;
+                         len : natural)
+        return string;
+
+end package scalp_utility;
+
+package body scalp_utility is
+
+    -- prints text to the screen
+
+    procedure print(text : string) is
+        variable msg_line : line;
+    begin
+        write(msg_line, text);
+        writeline(output, msg_line);
+    end print;
+
+    -- prints text to the screen when active
+
+    procedure print(active : boolean;
+                    text   : string) is
+    begin
+        if active then
+            print(text);
+        end if;
+    end print;
+
+    -- converts std_ulogic into a character
+
+    function uchr(sul : std_ulogic)
+        return character is
+
+        variable c : character;
+    begin
+        case sul is
+            when 'U' => c := 'U';
+            when 'X' => c := 'X';
+            when '0' => c := '0';
+            when '1' => c := '1';
+            when 'Z' => c := 'Z';
+            when 'W' => c := 'W';
+            when 'L' => c := 'L';
+            when 'H' => c := 'H';
+            when '-' => c := '-';
+        end case;
+        return c;
+    end uchr;
+
+    -- converts std_logic into a character
+
+    function chr(sl : std_logic)
+        return character is
+    begin
+        return uchr(std_ulogic(sl));
+    end chr;
+
+    -- converts std_ulogic into a string (1 to 1)
+
+    function ustr(sul : std_ulogic)
+        return string is
+
+        variable s : string(1 to 1);
+    begin
+        s(1) := uchr(sul);
+        return s;
+    end ustr;
+
+    -- converts std_logic into a string (1 to 1)
+
+    function str(sl : std_logic)
+        return string is
+
+        variable s : string(1 to 1);
+    begin
+        s(1) := chr(sl);
+        return s;
+    end str;
+
+    -- converts std_ulogic_vector into a string (binary base)
+    -- (this also takes care of the fact that the range of
+    --  a string is natural while a std_ulogic_vector may
+    --  have an integer range)
+
+    function str_ul(slv : std_ulogic_vector)
+        return string is
+
+        variable result : string (1 to slv'length);
+        variable r      : integer;
+    begin
+        r := 1;
+        for i in slv'range loop
+            result(r) := chr(slv(i));
+            r         := r + 1;
+        end loop;
+        return result;
+    end str_ul;
+
+    -- converts std_logic_vector into a string (binary base)
+    -- (this also takes care of the fact that the range of
+    --  a string is natural while a std_logic_vector may
+    --  have an integer range)
+
+    function str(slv : std_logic_vector)
+        return string is
+    begin
+        return str_ul(std_ulogic_vector(slv));
+    end str;
+
+    function str(b : boolean)
+        return string is
+    begin
+        if b then
+            return "true";
+        else
+            return "false";
+        end if;
+    end str;
+
+    -- converts an integer into a character
+    -- for 0 to 9 the obvious mapping is used, higher
+    -- values are mapped to the characters A-Z
+    -- (this is usefull for systems with base > 10)
+    -- (adapted from Steve Vogwell's posting in comp.lang.vhdl)
+
+    function chr(int : integer)
+        return character is
+
+        variable c : character;
+    begin
+        case int is
+            when 0      => c := '0';
+            when 1      => c := '1';
+            when 2      => c := '2';
+            when 3      => c := '3';
+            when 4      => c := '4';
+            when 5      => c := '5';
+            when 6      => c := '6';
+            when 7      => c := '7';
+            when 8      => c := '8';
+            when 9      => c := '9';
+            when 10     => c := 'A';
+            when 11     => c := 'B';
+            when 12     => c := 'C';
+            when 13     => c := 'D';
+            when 14     => c := 'E';
+            when 15     => c := 'F';
+            when 16     => c := 'G';
+            when 17     => c := 'H';
+            when 18     => c := 'I';
+            when 19     => c := 'J';
+            when 20     => c := 'K';
+            when 21     => c := 'L';
+            when 22     => c := 'M';
+            when 23     => c := 'N';
+            when 24     => c := 'O';
+            when 25     => c := 'P';
+            when 26     => c := 'Q';
+            when 27     => c := 'R';
+            when 28     => c := 'S';
+            when 29     => c := 'T';
+            when 30     => c := 'U';
+            when 31     => c := 'V';
+            when 32     => c := 'W';
+            when 33     => c := 'X';
+            when 34     => c := 'Y';
+            when 35     => c := 'Z';
+            when others => c := '?';
+        end case;
+        return c;
+    end chr;
+
+    -- convert integer to string using specified base
+    -- (adapted from Steve Vogwell's posting in comp.lang.vhdl)
+
+    function str(int  : integer;
+                 base : integer)
+        return string is
+
+        variable temp    : string(1 to 10);
+        variable num     : integer;
+        variable abs_int : integer;
+        variable len     : integer := 1;
+        variable power   : integer := 1;
+
+    begin
+
+        -- bug fix for negative numbers
+        abs_int := abs(int);
+
+        num := abs_int;
+
+        while num >= base loop          -- Determine how many
+            len := len + 1;             -- characters required
+            num := num / base;          -- to represent the
+        end loop;  -- number.
+
+        for i in len downto 1 loop                   -- Convert the number to
+            temp(i) := chr(abs_int/power mod base);  -- a string starting
+            power   := power * base;                 -- with the right hand
+        end loop;  -- side.
+
+        -- return result and add sign if required
+        if int < 0 then
+            return '-'& temp(1 to len);
+        else
+            return temp(1 to len);
+        end if;
+
+    end str;
+
+    -- convert integer to string, using base 10
+    function str(int : integer)
+        return string is
+
+    begin
+
+        return str(int, 10);
+
+    end str;
+
+    -- converts a std_ulogic_vector into a hex string.
+    function hstr_ul(slv : std_ulogic_vector)
+        return string is
+
+        variable hexlen  : integer;
+        variable longslv : std_ulogic_vector(67 downto 0) := (others => '0');
+        variable hex     : string(1 to 16);
+        variable fourbit : std_ulogic_vector(3 downto 0);
+    begin
+        hexlen := (slv'left+1)/4;
+        if (slv'left+1) mod 4 /= 0 then
+            hexlen := hexlen + 1;
+        end if;
+        longslv(slv'left downto 0) := slv;
+        for i in (hexlen -1) downto 0 loop
+            fourbit := longslv(((i*4)+3) downto (i*4));
+            case fourbit is
+                when "0000" => hex(hexlen -I) := '0';
+                when "0001" => hex(hexlen -I) := '1';
+                when "0010" => hex(hexlen -I) := '2';
+                when "0011" => hex(hexlen -I) := '3';
+                when "0100" => hex(hexlen -I) := '4';
+                when "0101" => hex(hexlen -I) := '5';
+                when "0110" => hex(hexlen -I) := '6';
+                when "0111" => hex(hexlen -I) := '7';
+                when "1000" => hex(hexlen -I) := '8';
+                when "1001" => hex(hexlen -I) := '9';
+                when "1010" => hex(hexlen -I) := 'A';
+                when "1011" => hex(hexlen -I) := 'B';
+                when "1100" => hex(hexlen -I) := 'C';
+                when "1101" => hex(hexlen -I) := 'D';
+                when "1110" => hex(hexlen -I) := 'E';
+                when "1111" => hex(hexlen -I) := 'F';
+                when "ZZZZ" => hex(hexlen -I) := 'z';
+                when "UUUU" => hex(hexlen -I) := 'u';
+                when "XXXX" => hex(hexlen -I) := 'x';
+                when others => hex(hexlen -I) := '?';
+            end case;
+        end loop;
+        return hex(1 to hexlen);
+    end hstr_ul;
+
+    -- converts a std_logic_vector into a hex string.
+    function hstr(slv : std_logic_vector)
+        return string is
+    begin
+        return hstr_ul(std_ulogic_vector(slv));
+    end hstr;
+
+    -- functions to manipulate strings
+    -----------------------------------
+
+    -- convert a character to upper case
+
+    function to_upper(c : character)
+        return character is
+
+        variable u : character;
+
+    begin
+
+        case c is
+            when 'a'    => u := 'A';
+            when 'b'    => u := 'B';
+            when 'c'    => u := 'C';
+            when 'd'    => u := 'D';
+            when 'e'    => u := 'E';
+            when 'f'    => u := 'F';
+            when 'g'    => u := 'G';
+            when 'h'    => u := 'H';
+            when 'i'    => u := 'I';
+            when 'j'    => u := 'J';
+            when 'k'    => u := 'K';
+            when 'l'    => u := 'L';
+            when 'm'    => u := 'M';
+            when 'n'    => u := 'N';
+            when 'o'    => u := 'O';
+            when 'p'    => u := 'P';
+            when 'q'    => u := 'Q';
+            when 'r'    => u := 'R';
+            when 's'    => u := 'S';
+            when 't'    => u := 'T';
+            when 'u'    => u := 'U';
+            when 'v'    => u := 'V';
+            when 'w'    => u := 'W';
+            when 'x'    => u := 'X';
+            when 'y'    => u := 'Y';
+            when 'z'    => u := 'Z';
+            when others => u := c;
+        end case;
+
+        return u;
+
+    end to_upper;
+
+    -- convert a character to lower case
+
+    function to_lower(c : character)
+        return character is
+
+        variable l : character;
+
+    begin
+
+        case c is
+            when 'A'    => l := 'a';
+            when 'B'    => l := 'b';
+            when 'C'    => l := 'c';
+            when 'D'    => l := 'd';
+            when 'E'    => l := 'e';
+            when 'F'    => l := 'f';
+            when 'G'    => l := 'g';
+            when 'H'    => l := 'h';
+            when 'I'    => l := 'i';
+            when 'J'    => l := 'j';
+            when 'K'    => l := 'k';
+            when 'L'    => l := 'l';
+            when 'M'    => l := 'm';
+            when 'N'    => l := 'n';
+            when 'O'    => l := 'o';
+            when 'P'    => l := 'p';
+            when 'Q'    => l := 'q';
+            when 'R'    => l := 'r';
+            when 'S'    => l := 's';
+            when 'T'    => l := 't';
+            when 'U'    => l := 'u';
+            when 'V'    => l := 'v';
+            when 'W'    => l := 'w';
+            when 'X'    => l := 'x';
+            when 'Y'    => l := 'y';
+            when 'Z'    => l := 'z';
+            when others => l := c;
+        end case;
+
+        return l;
+
+    end to_lower;
+
+    -- convert a string to upper case
+
+    function to_upper(s : string)
+        return string is
+
+        variable uppercase : string (s'range);
+
+    begin
+
+        for i in s'range loop
+            uppercase(i) := to_upper(s(i));
+        end loop;
+        return uppercase;
+
+    end to_upper;
+
+    -- convert a string to lower case
+
+    function to_lower(s : string)
+        return string is
+
+        variable lowercase : string (s'range);
+
+    begin
+
+        for i in s'range loop
+            lowercase(i) := to_lower(s(i));
+        end loop;
+        return lowercase;
+
+    end to_lower;
+
+    -- functions to convert strings into other types
+
+    -- converts a character into a std_ulogic
+
+    function to_std_ulogic(c : character)
+        return std_ulogic is
+
+        variable sul : std_ulogic;
+    begin
+        case c is
+            when 'U' =>
+                    sul := 'U';
+            when 'X' =>
+                    sul := 'X';
+            when '0' =>
+                    sul := '0';
+            when '1' =>
+                    sul := '1';
+            when 'Z' =>
+                    sul := 'Z';
+            when 'W' =>
+                    sul := 'W';
+            when 'L' =>
+                    sul := 'L';
+            when 'H' =>
+                    sul := 'H';
+            when '-' =>
+                    sul := '-';
+            when others =>
+                    sul := 'X';
+        end case;
+        return sul;
+    end to_std_ulogic;
+
+    -- converts a character into a std_logic
+
+    function to_std_logic(c : character)
+        return std_logic is
+    begin
+        return std_logic(to_std_ulogic(c));
+    end to_std_logic;
+
+    -- converts a string into std_ulogic_vector
+
+    function to_std_ulogic_vector(s : string)
+        return std_ulogic_vector is
+
+        variable sulv : std_ulogic_vector(s'high-s'low downto 0);
+        variable k    : integer;
+    begin
+        k := s'high-s'low;
+        for i in s'range loop
+            sulv(k) := to_std_ulogic(s(i));
+            k       := k - 1;
+        end loop;
+        return sulv;
+    end to_std_ulogic_vector;
+
+    -- converts a string into std_logic_vector
+
+    function to_std_logic_vector(s : string)
+        return std_logic_vector is
+    begin
+        return std_logic_vector(to_std_ulogic_vector(s));
+    end to_std_logic_vector;
+
+    ----------------
+    --  file I/O  --
+    ----------------
+
+    -- read variable length string from input file
+
+    procedure str_read(file in_file :     text;
+                       res_string   : out string) is
+
+        variable l         : line;
+        variable c         : character;
+        variable is_string : boolean;
+
+    begin
+
+        readline(in_file, l);
+        -- clear the contents of the result string
+        for i in res_string'range loop
+            res_string(i) := ' ';
+        end loop;
+        -- read all characters of the line, up to the length  
+        -- of the results string
+        for i in res_string'range loop
+            read(l, c, is_string);
+            res_string(i) := c;
+            if not is_string then       -- found end of line
+                exit;
+            end if;
+        end loop;
+
+    end str_read;
+
+    -- print string to a file
+    procedure print(file out_file :    text;
+                    new_string    : in string) is
+
+        variable l : line;
+
+    begin
+
+        write(l, new_string);
+        writeline(out_file, l);
+
+    end print;
+
+    -- print character to a file and start new line
+    procedure print(file out_file :    text;
+                    char          : in character) is
+
+        variable l : line;
+
+    begin
+
+        write(l, char);
+        writeline(out_file, l);
+
+    end print;
+
+    -- appends contents of a string to a file until line feed occurs
+    -- (LF is considered to be the end of the string)
+
+    procedure str_write(file out_file :    text;
+                        new_string    : in string) is
+    begin
+
+        for i in new_string'range loop
+            print(out_file, new_string(i));
+            if new_string(i) = LF then  -- end of string
+                exit;
+            end if;
+        end loop;
+
+    end str_write;
+
+    function string_fill(msg : string;
+                         len : natural) return string is
+        variable res_v : string(1 to len);
+    begin
+        res_v                  := (others => ' ');  -- Fill with spaces to blank all for a start
+        res_v(1 to msg'length) := msg;
+        return res_v;
+    end function;
+
+end package body scalp_utility;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_booking_vector.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_booking_vector.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..187a2a51551ec4303678a3e9358aeb2912619161
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_booking_vector.vhd
@@ -0,0 +1,216 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_booking_vector.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_booking_vector
+--
+-- Last update: 2020-02-13
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.uniform;
+use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.scalp_utility.all;
+
+entity tb_scalp_booking_vector is
+
+end entity tb_scalp_booking_vector;
+
+architecture testbench of tb_scalp_booking_vector is
+
+    constant C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255                                          := 7;
+    constant C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255                                          := 6;
+    constant C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255                                          := 1;
+    constant C_CLK_PERIOD                      : time                                                            := 10 ns;
+    constant C_SCALP_BOOKING_VECTOR_EMPTY      : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+
+    component scalp_matrix_index is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            IfSrcNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfNumValidxSI    : in  std_ulogic;
+            IfDstIdxxDO      : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstIdxValidxSO : out std_ulogic);
+    end component scalp_matrix_index;
+
+    component scalp_booking_vector is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            IfDstIdxxDI           : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstIdxValidxSI      : in  std_ulogic;
+            SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+            BookingVectorxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingVectorValidxSO : out std_ulogic);
+    end component scalp_booking_vector;
+
+    signal SysClkxC             : std_ulogic                                                          := '0';
+    signal SysRstxRNA           : std_ulogic                                                          := '0';
+    -- Scalp Matrix Index
+    signal IfSrcNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal IfDstNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal IfNumValidxS         : std_ulogic                                                          := '0';
+    signal IfDstIdxxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)              := 0;
+    signal IfDstIdxValidxS      : std_ulogic                                                          := '0';
+    -- Scalp Booking Vector
+    signal SchedulerAckxD       : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal BookingVectorxD      : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)     := (others => '0');
+    signal BookingVectorValidxS : std_ulogic                                                          := '0';
+    -- Process Signals
+    signal EndScalpMatIdxxS     : std_ulogic                                                          := '0';
+    signal RandomWaitTimexD     : integer                                                             := 10;
+
+begin  -- architecture testbench
+
+    SysClkxAS : SysClkxC <= not SysClkxC after (C_CLK_PERIOD / 2);
+
+    ScalpMatrixIndexxI : entity work.scalp_matrix_index
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE => C_SCALP_INTERFACE_VECTOR_SIZE)
+        port map (
+            IfSrcNumxDI      => IfSrcNumxD,
+            IfDstNumxDI      => IfDstNumxD,
+            IfNumValidxSI    => IfNumValidxS,
+            IfDstIdxxDO      => IfDstIdxxD,
+            IfDstIdxValidxSO => IfDstIdxValidxS);
+
+    ScalpBookingVectorxI : entity work.scalp_booking_vector
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE     => C_SCALP_INTERFACE_VECTOR_SIZE,
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE)
+        port map (
+            SysClkxCI             => SysClkxC,
+            SysRstxRNAI           => SysRstxRNA,
+            IfDstIdxxDI           => IfDstIdxxD,
+            IfDstIdxValidxSI      => IfDstIdxValidxS,
+            SchedulerAckxDI       => SchedulerAckxD,
+            BookingVectorxDO      => BookingVectorxD,
+            BookingVectorValidxSO => BookingVectorValidxS);
+
+    ResetxP : process is
+    begin  -- process ResetxP
+        wait for C_CLK_PERIOD;
+        SysRstxRNA <= '1';
+        wait;
+    end process ResetxP;
+
+    RandomWaitTimexP : process is
+
+        variable Seed1xD, Seed2xD : positive;
+        variable RandxD           : real;
+        variable RangeOfRandxD    : real := 20.0;
+
+    begin  -- process RandomWaitTimexP
+
+        report "Random wait Time is started" severity note;
+
+        RVTLoopxAS : loop
+            exit RVTLoopxAS when (EndScalpMatIdxxS = '1');
+            uniform(Seed1xD, Seed2xD, RandxD);
+            RandomWaitTimexD <= integer(RandxD * RangeOfRandxD) + 10;
+            -- report "RandomWaitTimexD = " & integer'image(RandomWaitTimexD) severity note;
+            wait for C_CLK_PERIOD;
+        end loop;
+
+        report "Random wait Time is finished" severity note;
+
+        wait;
+    end process RandomWaitTimexP;
+
+    ScalpRouterValidxP : process is
+    begin  -- process ScalpRouterValidxP
+
+        report "Scalp Router Valid is started" severity note;
+
+        SRVLoopxAS : loop
+            exit SRVLoopxAS when (EndScalpMatIdxxS = '1');
+            wait for RandomWaitTimexD * C_CLK_PERIOD;
+            IfNumValidxS <= '1';
+            wait for C_CLK_PERIOD;
+            IfNumValidxS <= '0';
+        end loop;
+
+        report "Scalp Router Valid is finished" severity note;
+
+        wait;
+    end process ScalpRouterValidxP;
+
+
+    CheckScalpMatrixIndexxP : process is
+    begin  -- process CheckScalpMatrixIndexxP
+
+        wait for 2 * C_CLK_PERIOD;
+
+        report "Scalp Matrix Index checking is started" severity note;
+
+        for i in 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) loop
+            IfSrcNumxD <= i;
+            for j in 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) loop
+                IfDstNumxD <= j;
+
+                wait until IfNumValidxS = '1';
+
+                report "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" severity note;
+                report "Iteration i = " & integer'image(i) & ", j = " & integer'image(j) severity note;
+                report "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" severity note;
+
+            end loop;  -- j
+        end loop;  -- i
+
+        EndScalpMatIdxxS <= '1';
+
+        report "Scalp Matrix Index checking is finished" severity note;
+
+        wait;
+    end process CheckScalpMatrixIndexxP;
+
+    CheckScalpBookingVectorxP : process is
+    begin  -- process CheckScalpBookingVectorxP
+
+        wait for 2 * C_CLK_PERIOD;
+
+        report "Scalp Booking Vector checking is started" severity note;
+
+        CSBVxAS : loop
+            exit CSBVxAS when (EndScalpMatIdxxS = '1');
+            wait until (BookingVectorxD /= C_SCALP_BOOKING_VECTOR_EMPTY);
+            SchedulerAckxD(0) <= '1';
+            wait for 5 * C_CLK_PERIOD;
+            SchedulerAckxD(0) <= '0';
+        end loop;
+
+        report "Scalp Booking Vector checking is finished" severity note;
+
+        wait;
+    end process CheckScalpBookingVectorxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_fifo_double_register.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_fifo_double_register.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..695a1459c4f0af181ecca0d67ffb4324d78d9ce9
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_fifo_double_register.vhd
@@ -0,0 +1,218 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_fifo_double_register.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_fifo_double_register.
+--
+-- Last update: 2020-02-21
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity tb_scalp_fifo_double_register is
+
+end entity tb_scalp_fifo_double_register;
+
+architecture testbench of tb_scalp_fifo_double_register is
+
+    constant C_CLK_PERIOD : time := 10 ns;
+
+    component scalp_fifo_double_register is
+        port (
+            -- System Clock and Reset
+            SysClkxCI      : in  std_ulogic;
+            SysRstxRNAI    : in  std_ulogic;
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI : in  t_axi4m2s;
+            Axiss2mLinkxDO : out t_axi4s2m;
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO : out t_axi4m2s;
+            Axiss2mLinkxDI : in  t_axi4s2m);
+    end component scalp_fifo_double_register;
+
+    signal SysClkxC         : std_ulogic := '0';
+    signal SysRstxRNA       : std_ulogic := '0';
+    -- End of Simulation
+    signal EndSimxS         : boolean    := false;
+    -- Others
+    signal Axism2sLinkInxD  : t_axi4m2s  := C_NO_AXI4_M2S;
+    signal Axiss2mLinkOutxD : t_axi4s2m  := C_NO_AXI4_S2M;
+    signal Axism2sLinkOutxD : t_axi4m2s  := C_NO_AXI4_M2S;
+    signal Axiss2mLinkInxD  : t_axi4s2m  := C_NO_AXI4_S2M;
+    -- Counter
+    signal CounterxDP       : integer    := 0;
+    signal CounterxDN       : integer    := 0;
+
+begin  -- architecture testbench
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+        SysClkxAS : SysClkxC               <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA             <= '1'          after (C_CLK_PERIOD * 10);
+        DataxAS   : Axism2sLinkInxD.DataxD <= std_ulogic_vector(to_unsigned(CounterxDP, 32));
+    end block AsyncStatementsxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpFifoDoubleRegisterxI : entity work.scalp_fifo_double_register
+        port map (
+            -- System Clock and Reset
+            SysClkxCI      => SysClkxC,
+            SysRstxRNAI    => SysRstxRNA,
+            -- Axis Ports (Slave Side)
+            Axism2sLinkxDI => Axism2sLinkInxD,
+            Axiss2mLinkxDO => Axiss2mLinkOutxD,
+            -- Axis Ports (Master Side)
+            Axism2sLinkxDO => Axism2sLinkOutxD,
+            Axiss2mLinkxDI => Axiss2mLinkInxD);
+
+    UpdateRegxP : process (SysClkxC, SysRstxRNA) is
+    begin  -- process UpdateRegxP
+        if SysRstxRNA = '0' then
+            CounterxDP <= 0;
+        elsif rising_edge(SysClkxC) then
+            CounterxDP <= CounterxDN;
+        end if;
+    end process UpdateRegxP;
+
+    CounterxP : process (Axism2sLinkInxD.ValidxS, Axiss2mLinkOutxD.ReadyxS,
+                         CounterxDP) is
+    begin  -- process CounterxP
+        CounterxDN <= CounterxDP;
+
+        if Axiss2mLinkOutxD.ReadyxS = '1' then
+            if Axism2sLinkInxD.ValidxS = '1' then
+                CounterxDN <= CounterxDP + 1;
+            end if;
+        end if;
+    end process CounterxP;
+
+    ValidxP : process is
+    begin  -- process ValidxP
+        Axism2sLinkInxD.ValidxS <= '0';
+        wait until (SysRstxRNA = '1');
+        Axism2sLinkInxD.ValidxS <= '1';
+
+        for i in 0 to 30 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axism2sLinkInxD.ValidxS <= '0';
+
+        for i in 0 to 6 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axism2sLinkInxD.ValidxS <= '1';
+
+        for i in 0 to 14 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axism2sLinkInxD.ValidxS <= '0';
+
+        for i in 0 to 10 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axism2sLinkInxD.ValidxS <= '1';
+
+        wait;
+    end process ValidxP;
+
+    ReadyxP : process is
+    begin  -- process ReadyxP
+        Axiss2mLinkInxD.ReadyxS <= '0';
+        wait until (SysRstxRNA = '1');
+        Axiss2mLinkInxD.ReadyxS <= '1';
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 10 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axiss2mLinkInxD.ReadyxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axiss2mLinkInxD.ReadyxS <= '1';
+
+        for i in 0 to 40 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axiss2mLinkInxD.ReadyxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        for i in 0 to 20 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        Axiss2mLinkInxD.ReadyxS <= '1';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        for i in 0 to 10 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        wait;
+    end process ReadyxP;
+
+    TestbenchxP : process is
+    begin  -- process TestbenchxP
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 150 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        EndSimxS <= true;
+    end process TestbenchxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_matrix_index.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_matrix_index.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..72c4645c92e2e84123dd8e97569f2fd8c74a0983
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_matrix_index.vhd
@@ -0,0 +1,122 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_matrix_index.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_matrix_index
+--
+-- Last update: 2020-01-19
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.scalp_utility.all;
+
+entity tb_scalp_matrix_index is
+
+end entity tb_scalp_matrix_index;
+
+architecture testbench of tb_scalp_matrix_index is
+
+    constant C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255 := 7;
+    constant C_CLK_PERIOD                  : time                   := 10 ns;
+
+    component scalp_matrix_index is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            IfSrcNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstNumxDI      : in  integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfNumValidxSI    : in  std_ulogic;
+            IfDstIdxxDO      : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfDstIdxValidxSO : out std_ulogic);
+    end component scalp_matrix_index;
+
+    signal IfSrcNumxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    signal IfDstNumxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    signal IfNumValidxS    : std_ulogic                                             := '0';
+    signal IfDstIdxxD      : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+    signal IfDstIdxValidxS : std_ulogic                                             := '0';
+    signal TestResultxD    : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) := 0;
+
+begin  -- architecture testbench    
+
+    ScalpMatrixIndexxI : entity work.scalp_matrix_index
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE => C_SCALP_INTERFACE_VECTOR_SIZE)
+        port map (
+            IfSrcNumxDI      => IfSrcNumxD,
+            IfDstNumxDI      => IfDstNumxD,
+            IfNumValidxSI    => IfNumValidxS,
+            IfDstIdxxDO      => IfDstIdxxD,
+            IfDstIdxValidxSO => IfDstIdxValidxS);
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+
+        TestResultxAS : TestResultxD <= ((IfDstNumxD - (IfSrcNumxD + 1)) mod C_SCALP_INTERFACE_VECTOR_SIZE);
+
+    end block AsyncStatementsxB;
+
+    CheckScalpMatrixIndexxP : process is
+    begin  -- process CheckScalpMatrixIndexxP
+
+        report "Scalp Matrix Index checking is started" severity note;
+
+        IfNumValidxS <= '1';
+
+        for i in 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) loop
+            IfSrcNumxD <= i;
+            for j in 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1) loop
+                IfDstNumxD <= j;
+
+                wait for C_CLK_PERIOD;
+
+                report "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" severity note;
+                report "Iteration i = " & integer'image(i) & ", j = " & integer'image(j) severity note;
+                report "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" severity note;
+
+                if IfDstIdxValidxS = '0' then
+                    report "++++++++++++++++++++++++++++++++++++++++" severity note;
+                    report "IfDstIdxxD   = " & integer'image(IfDstIdxxD) severity note;
+                    report "TestResultxD = " & integer'image(TestResultxD) severity note;
+                    report "No mistake, the indefinite condition when i = j" severity note;
+                    report "++++++++++++++++++++++++++++++++++++++++" severity note;
+                else
+                    report "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" severity note;
+                    report "IfDstIdxxD   = " & integer'image(IfDstIdxxD) severity note;
+                    report "TestResultxD = " & integer'image(TestResultxD) severity note;
+                    assert IfDstIdxxD = TestResultxD report "Error : unexpected value at current iteration!" severity failure;
+                    report "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" severity note;
+                end if;
+            end loop;  -- j
+        end loop;  -- i
+
+        IfNumValidxS <= '0';
+
+        report "Scalp Matrix Index checking is finished" severity note;
+
+        wait;
+    end process CheckScalpMatrixIndexxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_router.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_router.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7cfe201e2f84a0be05a35af42ee9ef49a54932ff
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_router.vhd
@@ -0,0 +1,1743 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_router.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_router (NoC).
+--
+-- Last update: 2020-11-30
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+use work.scalp_sim_packets.all;
+
+entity tb_scalp_router is
+
+end entity tb_scalp_router;
+
+architecture testbench of tb_scalp_router is
+
+    constant C_CLK_PERIOD                : time                   := 10 ns;
+    constant C_SCALP_NUMBER_OF_INTERFACE : integer range 0 to 255 := 7;
+    constant C_SCALP_SCHEDULER_STRATEGY  : string                 := "RR";
+    -- constant C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+    constant C_SCALP_RANDOM_READY        : boolean                := false;
+    -- Interface de destination
+    -- constant C_SCALP_DST_IF_ID           : integer range 0 to 6   := C_NORTH_IF_ID;
+
+    component scalp_router is
+        generic (
+            C_SCALP_NUMBER_OF_INTERFACE : integer range 0 to 255;
+            C_SCALP_SCHEDULER_STRATEGY  : string);
+        port (
+            -- System Clock and System nReset
+            SysClkxCI          : in  std_ulogic;
+            SysRstxRNAI        : in  std_ulogic;
+            -- Local Router Network Address
+            LocNetAddrxDI      : in  t_scalp_netaddr;
+            -- Axi4 Stream
+            -- RX Side Vector
+            RXAxism2sVectorxDI : in  t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+            RXAxiss2mVectorxDO : out t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+            -- TX Side Vector
+            TXAxism2sVectorxDO : out t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+            TXAxiss2mVectorxDI : in  t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0);
+            -- QoS Vector
+            QoSVectorxDI       : in  t_scalp_qos_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0));
+    end component scalp_router;
+
+    component scalp_sp_to_axis is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSI : in  std_ulogic;
+            ScalpAxism2sxDO     : out t_axi4m2s;
+            ScalpAxiss2mxDI     : in  t_axi4s2m;
+            ScalpRdyxSO         : out std_ulogic);
+    end component scalp_sp_to_axis;
+
+    component scalp_axis_to_sp is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+            C_SCALP_RANDOM_READY        : boolean);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpAxism2sxDI     : in  t_axi4m2s;
+            ScalpAxiss2mxDO     : out t_axi4s2m;
+            ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSO : out std_ulogic);
+    end component scalp_axis_to_sp;
+
+    -- Sys Clk and Sys nRst
+    signal SysClkxC           : std_ulogic                                                     := '0';
+    signal SysRstxRNA         : std_ulogic                                                     := '0';
+    -- End of Simulation
+    signal EndSimxS           : boolean                                                        := false;
+    signal ScalpDstIfIdxD     : integer range 0 to 6                                           := C_NORTH_IF_ID;
+    signal ScalpRdyxD         : std_ulogic_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)  := (others => '0');
+    -- Scalp Router
+    signal LocNetAddrxD       : t_scalp_netaddr                                                := C_SCALP_NET_ADDR_111;
+    signal RXAxism2sVectorxD  : t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)   := (others => C_NO_AXI4_M2S);
+    signal RXAxiss2mVectorxD  : t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)   := (others => C_NO_AXI4_S2M);
+    signal TXAxism2sVectorxD  : t_axi4m2s_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)   := (others => C_NO_AXI4_M2S);
+    signal TXAxiss2mVectorxD  : t_axi4s2m_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0)   := (others => C_NO_AXI4_S2M);
+    signal QoSVectorxD        : t_scalp_qos_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0) := (others => (others => '0'));
+    -- Scalp Packet
+    -- Start
+    -- signal ScalpNorthEndCounterxD  : integer                                                        := 0;
+    -- signal ScalpEastEndCounterxD   : integer                                                        := 0;
+    -- signal ScalpSouthEndCounterxD  : integer                                                        := 0;
+    -- signal ScalpWestEndCounterxD   : integer                                                        := 0;
+    -- signal ScalpTopEndCounterxD    : integer                                                        := 0;
+    -- signal ScalpBottomEndCounterxD : integer                                                        := 0;
+    -- signal ScalpLocalEndCounterxD  : integer                                                        := 0;
+    signal ScalpNorthIfEndxS  : std_ulogic                                                     := '0';
+    signal ScalpEastIfEndxS   : std_ulogic                                                     := '0';
+    signal ScalpSouthIfEndxS  : std_ulogic                                                     := '0';
+    signal ScalpWestIfEndxS   : std_ulogic                                                     := '0';
+    signal ScalpTopIfEndxS    : std_ulogic                                                     := '0';
+    signal ScalpBottomIfEndxS : std_ulogic                                                     := '0';
+    signal ScalpLocalIfEndxS  : std_ulogic                                                     := '0';
+    -- Packet NULL
+    signal ScalpPacketNullxD  : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    -- From North 121
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketNorthxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidNorthxS  : std_ulogic := '0';
+    signal ScalpPacketSelectNorthxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 0
+    signal ScalpPacket0xD           : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid0xS : std_ulogic := '0';
+    -- Packet 1
+    signal ScalpPacket1xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid1xS : std_ulogic := '0';
+    -- Packet 2
+    signal ScalpPacket2xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid2xS : std_ulogic := '0';
+    -- Packet 3
+    signal ScalpPacket3xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid3xS : std_ulogic := '0';
+    -- Packet 4
+    signal ScalpPacket4xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid4xS : std_ulogic := '0';
+    -- Packet 5
+    signal ScalpPacket5xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_121_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid5xS : std_ulogic := '0';
+    -- From East 211
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketEastxD   : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidEastxS  : std_ulogic := '0';
+    signal ScalpPacketSelectEastxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 6
+    signal ScalpPacket6xD          : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid6xS : std_ulogic := '0';
+    -- Packet 7
+    signal ScalpPacket7xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid7xS : std_ulogic := '0';
+    -- Packet 8
+    signal ScalpPacket8xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid8xS : std_ulogic := '0';
+    -- Packet 9
+    signal ScalpPacket9xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid9xS : std_ulogic := '0';
+    -- Packet 10
+    signal ScalpPacket10xD     : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid10xS : std_ulogic := '0';
+    -- Packet 11
+    signal ScalpPacket11xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_211_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid11xS : std_ulogic := '0';
+    -- From South 101
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketSouthxD   : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidSouthxS  : std_ulogic := '0';
+    signal ScalpPacketSelectSouthxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 12
+    signal ScalpPacket12xD          : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid12xS : std_ulogic := '0';
+    -- Packet 13
+    signal ScalpPacket13xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid13xS : std_ulogic := '0';
+    -- Packet 14
+    signal ScalpPacket14xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid14xS : std_ulogic := '0';
+    -- Packet 15
+    signal ScalpPacket15xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid15xS : std_ulogic := '0';
+    -- Packet 16
+    signal ScalpPacket16xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid16xS : std_ulogic := '0';
+    -- Packet 17
+    signal ScalpPacket17xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_101_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid17xS : std_ulogic := '0';
+    -- From West 011
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketWestxD    : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidWestxS  : std_ulogic := '0';
+    signal ScalpPacketSelectWestxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 18
+    signal ScalpPacket18xD         : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid18xS : std_ulogic := '0';
+    -- Packet 19
+    signal ScalpPacket19xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid19xS : std_ulogic := '0';
+    -- Packet 20
+    signal ScalpPacket20xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid20xS : std_ulogic := '0';
+    -- Packet 21
+    signal ScalpPacket21xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid21xS : std_ulogic := '0';
+    -- Packet 22
+    signal ScalpPacket22xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid22xS : std_ulogic := '0';
+    -- Packet 23
+    signal ScalpPacket23xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_011_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid23xS : std_ulogic := '0';
+    -- From Top 112
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketTopxD     : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidTopxS  : std_ulogic := '0';
+    signal ScalpPacketSelectTopxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 24
+    signal ScalpPacket24xD        : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid24xS : std_ulogic := '0';
+    -- Packet 25
+    signal ScalpPacket25xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid25xS : std_ulogic := '0';
+    -- Packet 26
+    signal ScalpPacket26xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid26xS : std_ulogic := '0';
+    -- Packet 27
+    signal ScalpPacket27xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid27xS : std_ulogic := '0';
+    -- Packet 28
+    signal ScalpPacket28xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid28xS : std_ulogic := '0';
+    -- Packet 29
+    signal ScalpPacket29xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_112_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid29xS : std_ulogic := '0';
+    -- From Bottom 110
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketBottomxD  : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidBottomxS  : std_ulogic := '0';
+    signal ScalpPacketSelectBottomxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 30
+    signal ScalpPacket30xD           : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid30xS : std_ulogic := '0';
+    -- Packet 31
+    signal ScalpPacket31xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid31xS : std_ulogic := '0';
+    -- Packet 32
+    signal ScalpPacket32xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid32xS : std_ulogic := '0';
+    -- Packet 33
+    signal ScalpPacket33xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid33xS : std_ulogic := '0';
+    -- Packet 34
+    signal ScalpPacket34xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid34xS : std_ulogic := '0';
+    -- Packet 35
+    signal ScalpPacket35xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_110_TO_111,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid35xS : std_ulogic := '0';
+    -- From Local 111
+    ---------------------------------------------------------------------------
+    ---------------------------------------------------------------------------
+    signal ScalpPacketLocalxD   : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_NULL,
+         SpPayloadxD => C_SP_PAYLOAD_NULL);
+    signal ScalpPacketValidLocalxS  : std_ulogic := '0';
+    signal ScalpPacketSelectLocalxD : integer    := 0;
+    ---------------------------------------------------------------------------
+    -- Packet 36
+    signal ScalpPacket36xD          : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_121,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid36xS : std_ulogic := '0';
+    -- Packet 37
+    signal ScalpPacket37xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_211,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid37xS : std_ulogic := '0';
+    -- Packet 38
+    signal ScalpPacket38xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_101,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid38xS : std_ulogic := '0';
+    -- Packet 39
+    signal ScalpPacket39xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_011,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid39xS : std_ulogic := '0';
+    -- Packet 40
+    signal ScalpPacket40xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_112,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid40xS : std_ulogic := '0';
+    -- Packet 41
+    signal ScalpPacket41xD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_111_TO_110,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValid41xS  : std_ulogic := '0';
+    -- End Packet
+    ---------------------------------------------------------------------------
+    signal ScalpPacketEndNorthxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndEastxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndSouthxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndWestxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndTopxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndBottomxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEndLocalxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketValidEndxD : std_ulogic_vector((C_SCALP_NUMBER_OF_INTERFACE - 1) downto 0) := (others => '0');
+
+    ---------------------------------------------------------------------------
+    -- Variables
+    ---------------------------------------------------------------------------
+    shared variable ScalpNorthEndCounterxD  : integer := 0;
+    shared variable ScalpEastEndCounterxD   : integer := 0;
+    shared variable ScalpSouthEndCounterxD  : integer := 0;
+    shared variable ScalpWestEndCounterxD   : integer := 0;
+    shared variable ScalpTopEndCounterxD    : integer := 0;
+    shared variable ScalpBottomEndCounterxD : integer := 0;
+    shared variable ScalpLocalEndCounterxD  : integer := 0;
+
+begin  -- architecture testbench
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+
+    end block AsyncStatementsxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpSpToAxisNorthxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketNorthxD,
+            ScalpPacketValidxSI => ScalpPacketValidNorthxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_NORTH_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_NORTH_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_NORTH_IF_ID));
+
+    ScalpSpToAxisEastxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketEastxD,
+            ScalpPacketValidxSI => ScalpPacketValidEastxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_EAST_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_EAST_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_EAST_IF_ID));
+
+    ScalpSpToAxisSouthxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketSouthxD,
+            ScalpPacketValidxSI => ScalpPacketValidSouthxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_SOUTH_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_SOUTH_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_SOUTH_IF_ID));
+
+    ScalpSpToAxisWestxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketWestxD,
+            ScalpPacketValidxSI => ScalpPacketValidWestxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_WEST_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_WEST_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_WEST_IF_ID));
+
+    ScalpSpToAxisTopxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketTopxD,
+            ScalpPacketValidxSI => ScalpPacketValidTopxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_TOP_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_TOP_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_TOP_IF_ID));
+
+    ScalpSpToAxisBottomxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketBottomxD,
+            ScalpPacketValidxSI => ScalpPacketValidBottomxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_BOTTOM_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_BOTTOM_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_BOTTOM_IF_ID));
+
+    ScalpSpToAxisLocalxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketLocalxD,
+            ScalpPacketValidxSI => ScalpPacketValidLocalxS,
+            ScalpAxism2sxDO     => RXAxism2sVectorxD(C_LOCAL_IF_ID),
+            ScalpAxiss2mxDI     => RXAxiss2mVectorxD(C_LOCAL_IF_ID),
+            ScalpRdyxSO         => ScalpRdyxD(C_LOCAL_IF_ID));
+
+    ---------------------------------------------------------------------------
+    -- ---------    ---------
+    -- | 1 3 0 |    | 2 3 0 |
+    -- ---------    ---------
+    --                  S
+    --                  N
+    -- ---------    ---------
+    -- | 1 2 0 |    | 2 2 0 |
+    -- ---------    ---------
+    --                  S
+    --                  N
+    -- ---------    ---------
+    -- | 1 1 0 |E  W| 2 1 0 |  <---
+    -- ---------    ---------
+
+    ScalpRouterxI : entity work.scalp_router
+        generic map (
+            C_SCALP_NUMBER_OF_INTERFACE => C_SCALP_NUMBER_OF_INTERFACE,
+            C_SCALP_SCHEDULER_STRATEGY  => C_SCALP_SCHEDULER_STRATEGY)
+        port map (
+            -- System Clock and System nReset
+            SysClkxCI          => SysClkxC,
+            SysRstxRNAI        => SysRstxRNA,
+            -- Local Router Network Address
+            LocNetAddrxDI      => LocNetAddrxD,
+            -- Axi4 Stream
+            -- RX Side Vector
+            RXAxism2sVectorxDI => RXAxism2sVectorxD,
+            RXAxiss2mVectorxDO => RXAxiss2mVectorxD,
+            -- TX Side Vector
+            TXAxism2sVectorxDO => TXAxism2sVectorxD,
+            TXAxiss2mVectorxDI => TXAxiss2mVectorxD,
+            -- QoS Vector
+            QoSVectorxDI       => QoSVectorxD);
+
+    ScalpAxisToSpNorthxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_NORTH_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_NORTH_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndNorthxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_NORTH_IF_ID));
+
+    ScalpAxisToSpEastxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_EAST_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_EAST_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndEastxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_EAST_IF_ID));
+
+    ScalpAxisToSpSouthxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_SOUTH_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_SOUTH_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndSouthxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_SOUTH_IF_ID));
+
+    ScalpAxisToSpWestxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_WEST_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_WEST_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndWestxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_WEST_IF_ID));
+
+    ScalpAxisToSpTopxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_TOP_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_TOP_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndTopxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_TOP_IF_ID));
+
+    ScalpAxisToSpBottomxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_BOTTOM_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_BOTTOM_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndBottomxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_BOTTOM_IF_ID));
+
+    ScalpAxisToSpLocalxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxism2sVectorxD(C_LOCAL_IF_ID),
+            ScalpAxiss2mxDO     => TXAxiss2mVectorxD(C_LOCAL_IF_ID),
+            ScalpPacketxDO      => ScalpPacketEndLocalxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(C_LOCAL_IF_ID));
+
+    ---------------------------------------------------------------------------
+    -- North
+    ---------------------------------------------------------------------------
+    NorthxB : block is
+    begin  -- block NorthxB
+        ScalpPacketNorthSelectxAS : ScalpPacketNorthxD <= ScalpPacket0xD when ScalpPacketSelectNorthxD = 0 else
+                                                          ScalpPacket1xD when ScalpPacketSelectNorthxD = 1 else
+                                                          ScalpPacket2xD when ScalpPacketSelectNorthxD = 2 else
+                                                          ScalpPacket3xD when ScalpPacketSelectNorthxD = 3 else
+                                                          ScalpPacket4xD when ScalpPacketSelectNorthxD = 4 else
+                                                          ScalpPacket5xD when ScalpPacketSelectNorthxD = 5;
+        ScalpPacketValidNorthSelectxAS : ScalpPacketValidNorthxS <= ScalpPacketValid0xS when ScalpPacketSelectNorthxD = 0 else
+                                                                    ScalpPacketValid1xS when ScalpPacketSelectNorthxD = 1 else
+                                                                    ScalpPacketValid2xS when ScalpPacketSelectNorthxD = 2 else
+                                                                    ScalpPacketValid3xS when ScalpPacketSelectNorthxD = 3 else
+                                                                    ScalpPacketValid4xS when ScalpPacketSelectNorthxD = 4 else
+                                                                    ScalpPacketValid5xS when ScalpPacketSelectNorthxD = 5;
+
+        ScalpPacketSendFromNorthxP : process is
+        begin  -- process ScalpPacketSendFromNorthxP
+            ScalpPacketSelectNorthxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            ScalpPacketValid0xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid0xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectNorthxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid1xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid1xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectNorthxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid2xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid2xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectNorthxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid3xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid3xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectNorthxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid4xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid4xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectNorthxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid5xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid5xS <= '0';
+
+            wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromNorthxP;
+
+    end block NorthxB;
+
+    ---------------------------------------------------------------------------
+    -- East
+    ---------------------------------------------------------------------------
+    EastxB : block is
+    begin  -- block EastxB
+        ScalpPacketEastSelectxAS : ScalpPacketEastxD <= ScalpPacket6xD when ScalpPacketSelectEastxD = 0 else
+                                                        ScalpPacket7xD  when ScalpPacketSelectEastxD = 1 else
+                                                        ScalpPacket8xD  when ScalpPacketSelectEastxD = 2 else
+                                                        ScalpPacket9xD  when ScalpPacketSelectEastxD = 3 else
+                                                        ScalpPacket10xD when ScalpPacketSelectEastxD = 4 else
+                                                        ScalpPacket11xD when ScalpPacketSelectEastxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidEastxS <= ScalpPacketValid6xS when ScalpPacketSelectEastxD = 0 else
+                                                                  ScalpPacketValid7xS  when ScalpPacketSelectEastxD = 1 else
+                                                                  ScalpPacketValid8xS  when ScalpPacketSelectEastxD = 2 else
+                                                                  ScalpPacketValid9xS  when ScalpPacketSelectEastxD = 3 else
+                                                                  ScalpPacketValid10xS when ScalpPacketSelectEastxD = 4 else
+                                                                  ScalpPacketValid11xS when ScalpPacketSelectEastxD = 5;
+
+        ScalpPacketSendFromEastxP : process is
+        begin  -- process ScalpPacketSendFromEastxP
+            ScalpPacketSelectEastxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD(C_NORTH_IF_ID) = '1';
+
+            ScalpPacketValid6xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid6xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectEastxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid7xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid7xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectEastxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid8xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid8xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectEastxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid9xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid9xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectEastxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid10xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid10xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectEastxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid11xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid11xS <= '0';
+
+            wait until ScalpRdyxD(C_EAST_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromEastxP;
+
+    end block EastxB;
+
+    -- ---------------------------------------------------------------------------
+    -- -- South
+    -- ---------------------------------------------------------------------------
+    SouthxB : block is
+    begin  -- block SouthxB
+        ScalpPacketEastSelectxAS : ScalpPacketSouthxD <= ScalpPacket12xD when ScalpPacketSelectSouthxD = 0 else
+                                                         ScalpPacket13xD when ScalpPacketSelectSouthxD = 1 else
+                                                         ScalpPacket14xD when ScalpPacketSelectSouthxD = 2 else
+                                                         ScalpPacket15xD when ScalpPacketSelectSouthxD = 3 else
+                                                         ScalpPacket16xD when ScalpPacketSelectSouthxD = 4 else
+                                                         ScalpPacket17xD when ScalpPacketSelectSouthxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidSouthxS <= ScalpPacketValid12xS when ScalpPacketSelectSouthxD = 0 else
+                                                                   ScalpPacketValid13xS when ScalpPacketSelectSouthxD = 1 else
+                                                                   ScalpPacketValid14xS when ScalpPacketSelectSouthxD = 2 else
+                                                                   ScalpPacketValid15xS when ScalpPacketSelectSouthxD = 3 else
+                                                                   ScalpPacketValid16xS when ScalpPacketSelectSouthxD = 4 else
+                                                                   ScalpPacketValid17xS when ScalpPacketSelectSouthxD = 5;
+
+        ScalpPacketSendFromSouthxP : process is
+        begin  -- process ScalpPacketSendFromSouthxP
+            ScalpPacketSelectSouthxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD() = '1';
+
+            ScalpPacketValid12xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid12xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectSouthxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid13xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid13xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectSouthxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid14xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid14xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectSouthxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid15xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid15xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectSouthxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid16xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid16xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectSouthxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid17xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid17xS <= '0';
+
+            wait until ScalpRdyxD(C_SOUTH_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromSouthxP;
+
+    end block SouthxB;
+
+    -- ---------------------------------------------------------------------------
+    -- -- West
+    -- ---------------------------------------------------------------------------
+    WestxB : block is
+    begin  -- block WestxB
+        ScalpPacketEastSelectxAS : ScalpPacketWestxD <= ScalpPacket18xD when ScalpPacketSelectWestxD = 0 else
+                                                        ScalpPacket19xD when ScalpPacketSelectWestxD = 1 else
+                                                        ScalpPacket20xD when ScalpPacketSelectWestxD = 2 else
+                                                        ScalpPacket21xD when ScalpPacketSelectWestxD = 3 else
+                                                        ScalpPacket22xD when ScalpPacketSelectWestxD = 4 else
+                                                        ScalpPacket23xD when ScalpPacketSelectWestxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidWestxS <= ScalpPacketValid18xS when ScalpPacketSelectWestxD = 0 else
+                                                                  ScalpPacketValid19xS when ScalpPacketSelectWestxD = 1 else
+                                                                  ScalpPacketValid20xS when ScalpPacketSelectWestxD = 2 else
+                                                                  ScalpPacketValid21xS when ScalpPacketSelectWestxD = 3 else
+                                                                  ScalpPacketValid22xS when ScalpPacketSelectWestxD = 4 else
+                                                                  ScalpPacketValid23xS when ScalpPacketSelectWestxD = 5;
+
+        ScalpPacketSendFromWestxP : process is
+        begin  -- process ScalpPacketSendFromWestxP
+            ScalpPacketSelectWestxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD() = '1';
+
+            ScalpPacketValid18xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid18xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectWestxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid19xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid19xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectWestxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid20xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid20xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectWestxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid21xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid21xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectWestxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid22xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid22xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectWestxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid23xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid23xS <= '0';
+
+            wait until ScalpRdyxD(C_WEST_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromWestxP;
+
+    end block WestxB;
+
+    -- ---------------------------------------------------------------------------
+    -- -- Top
+    -- ---------------------------------------------------------------------------
+    TopxB : block is
+    begin  -- block TopxB
+        ScalpPacketEastSelectxAS : ScalpPacketTopxD <= ScalpPacket24xD when ScalpPacketSelectTopxD = 0 else
+                                                       ScalpPacket25xD when ScalpPacketSelectTopxD = 1 else
+                                                       ScalpPacket26xD when ScalpPacketSelectTopxD = 2 else
+                                                       ScalpPacket27xD when ScalpPacketSelectTopxD = 3 else
+                                                       ScalpPacket28xD when ScalpPacketSelectTopxD = 4 else
+                                                       ScalpPacket29xD when ScalpPacketSelectTopxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidTopxS <= ScalpPacketValid24xS when ScalpPacketSelectTopxD = 0 else
+                                                                 ScalpPacketValid25xS when ScalpPacketSelectTopxD = 1 else
+                                                                 ScalpPacketValid26xS when ScalpPacketSelectTopxD = 2 else
+                                                                 ScalpPacketValid27xS when ScalpPacketSelectTopxD = 3 else
+                                                                 ScalpPacketValid28xS when ScalpPacketSelectTopxD = 4 else
+                                                                 ScalpPacketValid29xS when ScalpPacketSelectTopxD = 5;
+
+        ScalpPacketSendFromTopxP : process is
+        begin  -- process ScalpPacketSendFromTopxP
+            ScalpPacketSelectTopxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD() = '1';
+
+            ScalpPacketValid24xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid24xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectTopxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid25xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid25xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectTopxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid26xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid26xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectTopxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid27xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid27xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectTopxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid28xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid28xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectTopxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid29xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid29xS <= '0';
+
+            wait until ScalpRdyxD(C_TOP_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromTopxP;
+
+    end block TopxB;
+
+    -- ---------------------------------------------------------------------------
+    -- -- Bottom
+    -- ---------------------------------------------------------------------------
+    BottomxB : block is
+    begin  -- block BottomxB
+        ScalpPacketEastSelectxAS : ScalpPacketBottomxD <= ScalpPacket30xD when ScalpPacketSelectBottomxD = 0 else
+                                                          ScalpPacket31xD when ScalpPacketSelectBottomxD = 1 else
+                                                          ScalpPacket32xD when ScalpPacketSelectBottomxD = 2 else
+                                                          ScalpPacket33xD when ScalpPacketSelectBottomxD = 3 else
+                                                          ScalpPacket34xD when ScalpPacketSelectBottomxD = 4 else
+                                                          ScalpPacket35xD when ScalpPacketSelectBottomxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidBottomxS <= ScalpPacketValid30xS when ScalpPacketSelectBottomxD = 0 else
+                                                                    ScalpPacketValid31xS when ScalpPacketSelectBottomxD = 1 else
+                                                                    ScalpPacketValid32xS when ScalpPacketSelectBottomxD = 2 else
+                                                                    ScalpPacketValid33xS when ScalpPacketSelectBottomxD = 3 else
+                                                                    ScalpPacketValid34xS when ScalpPacketSelectBottomxD = 4 else
+                                                                    ScalpPacketValid35xS when ScalpPacketSelectBottomxD = 5;
+
+        ScalpPacketSendFromBottomxP : process is
+        begin  -- process ScalpPacketSendFromBottomxP
+            ScalpPacketSelectBottomxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD() = '1';
+
+            ScalpPacketValid30xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid30xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectBottomxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid31xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid31xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectBottomxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid32xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid32xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectBottomxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid33xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid33xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectBottomxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid34xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid34xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectBottomxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid35xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid35xS <= '0';
+
+            wait until ScalpRdyxD(C_BOTTOM_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromBottomxP;
+
+    end block BottomxB;
+
+    -- ---------------------------------------------------------------------------
+    -- -- Local
+    -- ---------------------------------------------------------------------------
+    LocalxB : block is
+    begin  -- block LocalxB
+        ScalpPacketEastSelectxAS : ScalpPacketLocalxD <= ScalpPacket36xD when ScalpPacketSelectLocalxD = 0 else
+                                                         ScalpPacket37xD when ScalpPacketSelectLocalxD = 1 else
+                                                         ScalpPacket38xD when ScalpPacketSelectLocalxD = 2 else
+                                                         ScalpPacket39xD when ScalpPacketSelectLocalxD = 3 else
+                                                         ScalpPacket40xD when ScalpPacketSelectLocalxD = 4 else
+                                                         ScalpPacket41xD when ScalpPacketSelectLocalxD = 5;
+        ScalpPacketValidEastSelectxAS : ScalpPacketValidLocalxS <= ScalpPacketValid36xS when ScalpPacketSelectLocalxD = 0 else
+                                                                   ScalpPacketValid37xS when ScalpPacketSelectLocalxD = 1 else
+                                                                   ScalpPacketValid38xS when ScalpPacketSelectLocalxD = 2 else
+                                                                   ScalpPacketValid39xS when ScalpPacketSelectLocalxD = 3 else
+                                                                   ScalpPacketValid40xS when ScalpPacketSelectLocalxD = 4 else
+                                                                   ScalpPacketValid41xS when ScalpPacketSelectLocalxD = 5;
+
+        ScalpPacketSendFromLocalxP : process is
+        begin  -- process ScalpPacketSendFromLocalxP
+            ScalpPacketSelectLocalxD <= 0;
+
+            wait until (SysRstxRNA = '1');
+            wait until rising_edge(SysClkxC);
+            wait until rising_edge(SysClkxC);
+
+            -- wait until ScalpRdyxD() = '1';
+
+            ScalpPacketValid36xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid36xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectLocalxD <= 1;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid37xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid37xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectLocalxD <= 2;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid38xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid38xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectLocalxD <= 3;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid39xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid39xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectLocalxD <= 4;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid40xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid40xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            -------------------------------------------------------------------
+
+            ScalpPacketSelectLocalxD <= 5;
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid41xS <= '1';
+
+            for i in 0 to 0 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ScalpPacketValid41xS <= '0';
+
+            wait until ScalpRdyxD(C_LOCAL_IF_ID) = '1';
+
+            wait;
+        end process ScalpPacketSendFromLocalxP;
+
+    end block LocalxB;
+
+    ScalpNorthEndxP : process is
+    begin  -- process ScalpNorthEndxP
+        ScalpNorthEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_NORTH_IF_ID) = '1';
+            ScalpNorthEndCounterxD := ScalpNorthEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpNorthEndxP;
+
+    ScalpEastEndxP : process is
+    begin  -- process ScalpEastEndxP
+        ScalpEastEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_EAST_IF_ID) = '1';
+            ScalpEastEndCounterxD := ScalpEastEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpEastEndxP;
+
+    ScalpSouthEndxP : process is
+    begin  -- process ScalpSouthEndxP
+        ScalpSouthEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_SOUTH_IF_ID) = '1';
+            ScalpSouthEndCounterxD := ScalpSouthEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpSouthEndxP;
+
+    ScalpWestEndxP : process is
+    begin  -- process ScalpWestEndxP
+        ScalpWestEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_WEST_IF_ID) = '1';
+            ScalpWestEndCounterxD := ScalpWestEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpWestEndxP;
+
+    ScalpTopEndxP : process is
+    begin  -- process ScalpTopEndxP
+        ScalpTopEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_TOP_IF_ID) = '1';
+            ScalpTopEndCounterxD := ScalpTopEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpTopEndxP;
+
+    ScalpBottomEndxP : process is
+    begin  -- process ScalpBottomEndxP
+        ScalpBottomEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_BOTTOM_IF_ID) = '1';
+            ScalpBottomEndCounterxD := ScalpBottomEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpBottomEndxP;
+
+    ScalpLocalEndxP : process is
+    begin  -- process ScalpLocalEndxP
+        ScalpLocalEndCounterxD := 0;
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 5 loop
+            wait until ScalpPacketValidEndxD(C_LOCAL_IF_ID) = '1';
+            ScalpLocalEndCounterxD := ScalpLocalEndCounterxD + 1;
+        end loop;  -- i
+
+        wait;
+    end process ScalpLocalEndxP;
+
+    TestbenchxP : process is
+    begin  -- process TestbenchxP
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        L0xL : loop
+            wait until rising_edge(SysClkxC);
+
+            -- North
+            -- exit L0xL when (ScalpEastEndCounterxD = 1 and
+            --                 ScalpSouthEndCounterxD = 1 and
+            --                 ScalpWestEndCounterxD = 1 and
+            --                 ScalpTopEndCounterxD = 1 and
+            --                 ScalpBottomEndCounterxD = 1 and
+            --                 ScalpLocalEndCounterxD = 1);
+
+            exit L0xL when (ScalpNorthEndCounterxD = 6 and
+                            ScalpEastEndCounterxD = 6 and
+                            ScalpSouthEndCounterxD = 6 and
+                            ScalpWestEndCounterxD = 6 and
+                            ScalpTopEndCounterxD = 6 and
+                            ScalpBottomEndCounterxD = 6 and
+                            ScalpLocalEndCounterxD = 6);
+        end loop L0xL;
+
+        for i in 0 to 99 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        EndSimxS <= true;
+    end process TestbenchxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_router_core.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_router_core.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f4fa6bf50d42b2c8fbc159e418d3d2d269b64232
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_router_core.vhd
@@ -0,0 +1,160 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_router_core.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_router_core.
+--
+-- Last update: 2020-01-21
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+-- use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity tb_scalp_router_core is
+
+end entity tb_scalp_router_core;
+
+architecture testbench of tb_scalp_router_core is
+
+    constant C_CLK_PERIOD                  : time                   := 10 ns;
+    -- Scalp Router Core
+    constant C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255 := 7;
+    -- Router Net Address
+    constant C_SCALP_LOC_ROUTER_NET_ADDR_0 : t_scalp_netaddr        := (XxD => 0, YxD => 0, ZxD => 0);
+    constant C_SCALP_LOC_ROUTER_NET_ADDR_1 : t_scalp_netaddr        := (XxD => 1, YxD => 0, ZxD => 0);
+    constant C_SCALP_LOC_ROUTER_NET_ADDR_2 : t_scalp_netaddr        := (XxD => 0, YxD => 1, ZxD => 0);
+    constant C_SCALP_LOC_ROUTER_NET_ADDR_3 : t_scalp_netaddr        := (XxD => 1, YxD => 1, ZxD => 0);
+    constant C_SCALP_DST_ROUTER_NET_ADDR_0 : t_scalp_netaddr        := (XxD => 1, YxD => 1, ZxD => 1);
+
+    component scalp_router_core is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            -- System Clock and Reset
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            LocRouterNetAddrxDI   : in  t_scalp_netaddr;
+            DstRouterNetAddrxDI   : in  t_scalp_netaddr;
+            RouterNetAddrValidxSI : in  std_ulogic;
+            IfDstNumxDO           : out integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1);
+            IfNumValidxSO         : out std_ulogic;
+            QoSVectorxDI          : in  t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+    end component scalp_router_core;
+
+    -- Sys Clk and Sys nRst
+    signal SysClkxC             : std_ulogic                                                       := '0';
+    signal SysRstxRNA           : std_ulogic                                                       := '0';
+    -- End of Simulation
+    signal EndSimxS             : boolean                                                          := false;
+    -- Scalp Router Core Signals
+    signal LocRouterNetAddrxD   : t_scalp_netaddr                                                  := C_3D_MIN_SCALP_NETADDR;
+    signal DstRouterNetAddrxD   : t_scalp_netaddr                                                  := C_3D_MIN_SCALP_NETADDR;
+    signal RouterNetAddrValidxS : std_ulogic                                                       := '0';
+    signal IfDstNumxD           : integer range 0 to (C_SCALP_INTERFACE_VECTOR_SIZE - 1)           := 0;
+    signal IfNumValidxS         : std_ulogic                                                       := '0';
+    signal QoSVectorxD          : t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0) := (others => C_SCALP_NO_QOS);
+
+begin  -- architecture testbench
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+
+    end block AsyncStatementsxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpRouterCorexI : entity work.scalp_router_core
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE => C_SCALP_INTERFACE_VECTOR_SIZE)
+        port map (
+            -- System Clock and Reset
+            SysClkxCI             => SysClkxC,
+            SysRstxRNAI           => SysRstxRNA,
+            -- Local and Destination Router Network Address
+            LocRouterNetAddrxDI   => LocRouterNetAddrxD,
+            DstRouterNetAddrxDI   => DstRouterNetAddrxD,
+            RouterNetAddrValidxSI => RouterNetAddrValidxS,
+            -- Destination Interfaces Number
+            IfDstNumxDO           => IfDstNumxD,
+            IfNumValidxSO         => IfNumValidxS,
+            -- QoS Vector
+            QoSVectorxDI          => QoSVectorxD);
+
+    RouterNetAddrValidxP : process is
+    begin  -- process RouterNetAddrValidxP
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for i in 0 to 1 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        RouterNetAddrValidxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        RouterNetAddrValidxS <= '0';
+
+        wait;
+
+    end process RouterNetAddrValidxP;
+
+    ScalpRouterCorexP : process is
+    begin  -- process ScalpRouterCorexP
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        LocRouterNetAddrxD <= C_SCALP_LOC_ROUTER_NET_ADDR_3;
+        DstRouterNetAddrxD <= C_SCALP_DST_ROUTER_NET_ADDR_0;
+
+        wait until IfNumValidxS = '1';
+        wait until IfNumValidxS = '0';
+
+        EndSimxS <= true;
+
+    end process ScalpRouterCorexP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_router_interface.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_router_interface.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..8350e7229caaf1c12ad4899515bbfc98fa595064
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_router_interface.vhd
@@ -0,0 +1,364 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_router_interface.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_router_interface.
+--
+-- Last update: 2020-02-13
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity tb_scalp_router_interface is
+
+end entity tb_scalp_router_interface;
+
+architecture testbench of tb_scalp_router_interface is
+
+    constant C_CLK_PERIOD                      : time                                                 := 10 ns;
+    -- Scalp Router Interface
+    constant C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255                               := 7;
+    constant C_SCALP_INTERFACE_SOURCE_NUMBER   : integer range 0 to 255                               := 0;
+    constant C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255                               := 6;
+    constant C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255                               := 1;
+    constant C_SCALP_LOCAL_ROUTER_NET_ADDR     : t_scalp_netaddr                                      := C_3D_MIN_SCALP_NETADDR;
+    constant C_SCALP_SCHEDULER_STRATEGY        : string                                               := "RR";
+    -- scalp_sp_to_axis
+    constant C_SCALP_PACKET_PAYLOAD_SIZE       : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+    constant C_SCALP_RANDOM_READY              : boolean                                              := false;
+
+    -- Scalp Packet Headers
+    constant C_SP_HEADER_0 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 1,
+             YxD     => 1,
+             ZxD     => 0),
+            SrcAddrxD =>
+            (XxD     => 0,
+             YxD     => 0,
+             ZxD     => 0),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- Scalp Packet Payloads
+    constant C_SP_PAYLOAD_0 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#01223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#02334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    component scalp_router_interface is
+        generic (
+            C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_INTERFACE_SOURCE_NUMBER   : integer range 0 to 255;
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255;
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255;
+            C_SCALP_SCHEDULER_STRATEGY        : string);
+        port (
+            SysClkxCI         : in  std_ulogic;
+            SysRstxRNAI       : in  std_ulogic;
+            LocNetAddrxDI     : in  t_scalp_netaddr;
+            RXAxi4m2sIfxDI    : in  t_axi4m2s;
+            RXAxi4s2mIfxDO    : out t_axi4s2m;
+            TXAxi4m2sIfxDO    : out t_axi4m2s;
+            TXAxi4s2mIfxDI    : in  t_axi4s2m;
+            RXAxi4m2sLinksxDI : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            RXAxi4s2mLinksxDO : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            TXAxi4m2sLinksxDO : out t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            TXAxi4s2mLinksxDI : in  t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingVectorxDI  : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            BookingVectorxDO  : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            SchedulerAckxDI   : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            SchedulerAckxDO   : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            QoSVectorxDI      : in  t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0));
+    end component scalp_router_interface;
+
+    component scalp_sp_to_axis is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSI : in  std_ulogic;
+            ScalpAxism2sxDO     : out t_axi4m2s;
+            ScalpAxiss2mxDI     : in  t_axi4s2m);
+    end component scalp_sp_to_axis;
+
+    component scalp_axis_to_sp is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+            C_SCALP_RANDOM_READY        : boolean);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpAxism2sxDI     : in  t_axi4m2s;
+            ScalpAxiss2mxDO     : out t_axi4s2m;
+            ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSO : out std_ulogic);
+    end component scalp_axis_to_sp;
+
+    -- Sys Clk and Sys nRst
+    signal SysClkxC           : std_ulogic := '0';
+    signal SysRstxRNA         : std_ulogic := '0';
+    -- End of Simulation
+    signal EndSimxS           : boolean    := false;
+    -- scalp_sp_to_axis
+    signal ScalpPacketValidxS : std_ulogic := '0';
+    signal ScalpPacketxD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_0,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValidEndxD : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal ScalpPacketEnd0xD     : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEnd1xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEnd2xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEnd3xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEnd4xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketEnd5xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    -- Scalp Router Interface
+    signal LocNetAddrxD       : t_scalp_netaddr                                                  := C_3D_MIN_SCALP_NETADDR;
+    signal RXAxi4m2sIfxD      : t_axi4m2s                                                        := C_NO_AXI4_M2S;
+    signal RXAxi4s2mIfxD      : t_axi4s2m                                                        := C_NO_AXI4_S2M;
+    signal TXAxi4m2sIfxD      : t_axi4m2s                                                        := C_NO_AXI4_M2S;
+    signal TXAxi4s2mIfxD      : t_axi4s2m                                                        := C_NO_AXI4_S2M;
+    signal RXAxi4m2sLinksxD   : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)   := (others => C_NO_AXI4_M2S);
+    signal RXAxi4s2mLinksxD   : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)   := (others => C_NO_AXI4_S2M);
+    signal TXAxi4m2sLinksxD   : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)   := (others => C_NO_AXI4_M2S);
+    signal TXAxi4s2mLinksxD   : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)   := (others => C_NO_AXI4_S2M);
+    signal BookingVectorInxD  : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => '0');
+    signal BookingVectorOutxD : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => '0');
+    signal SchedulerAckInxD   : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => '0');
+    signal SchedulerAckOutxD  : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => '0');
+    signal QoSVectorxD        : t_scalp_qos_vector((C_SCALP_INTERFACE_VECTOR_SIZE - 1) downto 0) := (others => C_SCALP_NO_QOS);
+
+begin  -- architecture testbench
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+
+    end block AsyncStatementsxB;
+
+    ScalpRouterInterfacexI : entity work.scalp_router_interface
+        generic map (
+            C_SCALP_INTERFACE_VECTOR_SIZE     => C_SCALP_INTERFACE_VECTOR_SIZE,
+            C_SCALP_INTERFACE_SOURCE_NUMBER   => C_SCALP_INTERFACE_SOURCE_NUMBER,
+            C_SCALP_NEIGHBORS_VECTOR_SIZE     => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_STRATEGY        => C_SCALP_SCHEDULER_STRATEGY)
+        port map (
+            SysClkxCI         => SysClkxC,
+            SysRstxRNAI       => SysRstxRNA,
+            LocNetAddrxDI     => LocNetAddrxD,
+            RXAxi4m2sIfxDI    => RXAxi4m2sIfxD,
+            RXAxi4s2mIfxDO    => RXAxi4s2mIfxD,
+            TXAxi4m2sIfxDO    => TXAxi4m2sIfxD,
+            TXAxi4s2mIfxDI    => TXAxi4s2mIfxD,
+            RXAxi4m2sLinksxDI => RXAxi4m2sLinksxD,
+            RXAxi4s2mLinksxDO => RXAxi4s2mLinksxD,
+            TXAxi4m2sLinksxDO => TXAxi4m2sLinksxD,
+            TXAxi4s2mLinksxDI => TXAxi4s2mLinksxD,
+            BookingVectorxDI  => BookingVectorInxD,
+            BookingVectorxDO  => BookingVectorOutxD,
+            SchedulerAckxDI   => SchedulerAckInxD,
+            SchedulerAckxDO   => SchedulerAckOutxD,
+            QoSVectorxDI      => QoSVectorxD);
+
+    ScalpSpToAxisxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketxD,
+            ScalpPacketValidxSI => ScalpPacketValidxS,
+            ScalpAxism2sxDO     => RXAxi4m2sIfxD,
+            ScalpAxiss2mxDI     => RXAxi4s2mIfxD);
+
+    ScalpAxisToSp0xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(0),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(0),
+            ScalpPacketxDO      => ScalpPacketEnd0xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(0));
+
+    ScalpAxisToSp1xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(1),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(1),
+            ScalpPacketxDO      => ScalpPacketEnd1xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(1));
+
+    ScalpAxisToSp2xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(2),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(2),
+            ScalpPacketxDO      => ScalpPacketEnd2xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(2));
+
+    ScalpAxisToSp3xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(3),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(3),
+            ScalpPacketxDO      => ScalpPacketEnd3xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(3));
+
+    ScalpAxisToSp4xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(4),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(4),
+            ScalpPacketxDO      => ScalpPacketEnd4xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(4));
+
+    ScalpAxisToSp5xI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4m2sLinksxD(5),
+            ScalpAxiss2mxDO     => TXAxi4s2mLinksxD(5),
+            ScalpPacketxDO      => ScalpPacketEnd5xD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD(5));
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    BookingVectorxP : process is
+    begin  -- process BookingVectorxP
+
+        wait until (BookingVectorOutxD(0) = '1' or
+                    BookingVectorOutxD(1) = '1' or
+                    BookingVectorOutxD(2) = '1' or
+                    BookingVectorOutxD(3) = '1' or
+                    BookingVectorOutxD(4) = '1' or
+                    BookingVectorOutxD(5) = '1');
+        wait;
+    end process BookingVectorxP;
+
+    ScalpRouterInterfacexP : process is
+    begin  -- process ScalpRouterInterfacexP
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        ScalpPacketValidxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '0';
+
+        wait until (ScalpPacketValidEndxD(0) = '1' and
+                    ScalpPacketValidEndxD(1) = '1' and
+                    ScalpPacketValidEndxD(2) = '1' and
+                    ScalpPacketValidEndxD(3) = '1' and
+                    ScalpPacketValidEndxD(4) = '1' and
+                    ScalpPacketValidEndxD(5) = '1');
+
+        EndSimxS <= true;
+
+    end process ScalpRouterInterfacexP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_rx_side.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_rx_side.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..f049ce7a6830939206dbf25ce749810275e0ec03
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_rx_side.vhd
@@ -0,0 +1,575 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_rx_side.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_rx_side.
+--
+-- Last update: 2020-02-13
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity tb_scalp_rx_side is
+
+end entity tb_scalp_rx_side;
+
+architecture testbench of tb_scalp_rx_side is
+
+    constant C_CLK_PERIOD                  : time                                                            := 10 ns;
+    constant C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255                                          := 6;
+    constant C_SCALP_SCHEDULER_STRATEGY    : string                                                          := "RR";
+    constant C_SCALP_SCHEDULER_OUTPUT_REG  : boolean                                                         := true;
+    -- scalp_sp_to_axis
+    constant C_SCALP_PACKET_PAYLOAD_SIZE   : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE            := 8;
+    constant C_SCALP_RANDOM_READY          : boolean                                                         := true;
+    constant C_SCALP_DELAY_SIZE_0          : integer range 0 to 255                                          := 5;
+    constant C_SCALP_DELAY_SIZE_1          : integer range 0 to 255                                          := 10;
+    constant C_SCALP_DELAY_SIZE_2          : integer range 0 to 255                                          := 15;
+    constant C_SCALP_DELAY_SIZE_3          : integer range 0 to 255                                          := 20;
+    constant C_SCALP_DELAY_SIZE_4          : integer range 0 to 255                                          := 25;
+    constant C_SCALP_DELAY_SIZE_5          : integer range 0 to 255                                          := 30;
+    constant C_SCALP_BOOKING_VECTOR        : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := "001010";
+
+    -- Scalp Packet Headers
+    constant C_SP_HEADER_0 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 1,
+             YxD     => 2,
+             ZxD     => 3),
+            SrcAddrxD =>
+            (XxD     => 4,
+             YxD     => 5,
+             ZxD     => 6),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+
+    constant C_SP_HEADER_1 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 7,
+             YxD     => 8,
+             ZxD     => 9),
+            SrcAddrxD =>
+            (XxD     => 10,
+             YxD     => 11,
+             ZxD     => 12),
+            TypexD   => 0,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+
+    constant C_SP_HEADER_2 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 13,
+             YxD     => 14,
+             ZxD     => 15),
+            SrcAddrxD =>
+            (XxD     => 16,
+             YxD     => 17,
+             ZxD     => 18),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+
+    constant C_SP_HEADER_3 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 19,
+             YxD     => 20,
+             ZxD     => 21),
+            SrcAddrxD =>
+            (XxD     => 22,
+             YxD     => 23,
+             ZxD     => 24),
+            TypexD   => 0,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+
+    constant C_SP_HEADER_4 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 25,
+             YxD     => 26,
+             ZxD     => 27),
+            SrcAddrxD =>
+            (XxD     => 28,
+             YxD     => 29,
+             ZxD     => 30),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+
+    constant C_SP_HEADER_5 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 31,
+             YxD     => 32,
+             ZxD     => 33),
+            SrcAddrxD =>
+            (XxD     => 34,
+             YxD     => 35,
+             ZxD     => 36),
+            TypexD   => 0,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- Scalp Packet Payloads
+    constant C_SP_PAYLOAD_0 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#01223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#02334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    constant C_SP_PAYLOAD_1 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#1f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#11223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#12334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    constant C_SP_PAYLOAD_2 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#2f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#21223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#22334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    constant C_SP_PAYLOAD_3 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#3f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#31223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#32334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    constant C_SP_PAYLOAD_4 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#4f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#41223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#42334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    constant C_SP_PAYLOAD_5 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#5f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#51223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#52334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    component scalp_sp_to_axis is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSI : in  std_ulogic;
+            ScalpAxism2sxDO     : out t_axi4m2s;
+            ScalpAxiss2mxDI     : in  t_axi4s2m);
+    end component scalp_sp_to_axis;
+
+    component scalp_axis_to_sp is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+            C_SCALP_RANDOM_READY        : boolean);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpAxism2sxDI     : in  t_axi4m2s;
+            ScalpAxiss2mxDO     : out t_axi4s2m;
+            ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSO : out std_ulogic);
+    end component scalp_axis_to_sp;
+
+    component scalp_rx_side is
+        generic (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE : integer range 0 to 255;
+            C_SCALP_SCHEDULER_STRATEGY    : string;
+            C_SCALP_SCHEDULER_OUTPUT_REG  : boolean);
+        port (
+            -- System Clock and Reset
+            SysClkxCI            : in  std_ulogic;
+            SysRstxRNAI          : in  std_ulogic;
+            -- Scheduler Ack Vector
+            SchedulerAckxDO      : out std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Booking Vector
+            BookingVectorxDI     : in  std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Axi Stream
+            -- Output Side
+            TXAxi4M2SLinkxDO     : out t_axi4m2s;
+            TXAxi4S2MLinkxDI     : in  t_axi4s2m;
+            -- Input Side
+            RXAxi4M2SLinkxDI     : in  t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            RXAxi4S2MLinkxDO     : out t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0);
+            -- Debug Interface
+            BookingIndexxDO      : out integer range 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1);
+            BookingIndexValidxSO : out std_ulogic);
+    end component scalp_rx_side;
+
+    -- Sys Clk and Sys nRst
+    signal SysClkxC              : std_ulogic                                                      := '0';
+    signal SysRstxRNA            : std_ulogic                                                      := '0';
+    -- End of Simulation
+    signal EndSimxS              : boolean                                                         := false;
+    signal SchedAckxS            : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal SPValidEndxS          : std_ulogic                                                      := '0';
+    -- scalp_rx_side
+    signal SchedulerAckxD        : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal BookingVectorxD       : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal NewBookingVectorxD    : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal TXAxi4M2SLinkxD       : t_axi4m2s                                                       := C_NO_AXI4_M2S;
+    signal TXAxi4S2MLinkxD       : t_axi4s2m                                                       := C_NO_AXI4_S2M;
+    signal RXAxi4M2SLinkxD       : t_axi4m2s_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => C_NO_AXI4_M2S);
+    signal RXAxi4S2MLinkxD       : t_axi4s2m_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0)  := (others => C_NO_AXI4_S2M);
+    signal BookingIndexxD        : integer range 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1)          := 0;
+    signal BookingIndexValidxS   : std_ulogic                                                      := '0';
+    -- Scalp Packets
+    signal ScalpPacketValidxD    : std_ulogic_vector((C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal ScalpPacketValidEndxD : std_ulogic                                                      := '0';
+
+    -- Packet 0
+    signal ScalpPacket0xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_0,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    -- Packet 1
+    signal ScalpPacket1xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_1,
+         SpPayloadxD => C_SP_PAYLOAD_1);
+    -- Packet 2
+    signal ScalpPacket2xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_2,
+         SpPayloadxD => C_SP_PAYLOAD_2);
+    -- Packet 3
+    signal ScalpPacket3xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_3,
+         SpPayloadxD => C_SP_PAYLOAD_3);
+    -- Packet 4
+    signal ScalpPacket4xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_4,
+         SpPayloadxD => C_SP_PAYLOAD_4);
+    -- Packet 5
+    signal ScalpPacket5xD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_5,
+         SpPayloadxD => C_SP_PAYLOAD_5);
+    -- Packet TX Side
+    signal ScalpPacketEndxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+
+begin  -- architecture testbench
+
+    ScalpSpToAxis0xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket0xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(0),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(0),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(0));
+
+    ScalpSpToAxis1xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket1xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(1),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(1),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(1));
+
+    ScalpSpToAxis2xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket2xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(2),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(2),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(2));
+
+    ScalpSpToAxis3xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket3xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(3),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(3),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(3));
+
+    ScalpSpToAxis4xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket4xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(4),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(4),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(4));
+
+    ScalpSpToAxis5xI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacket5xD,
+            ScalpPacketValidxSI => ScalpPacketValidxD(5),
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD(5),
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD(5));
+
+    ScalpRXSidexI : entity work.scalp_rx_side
+        generic map (
+            C_SCALP_NEIGHBORS_VECTOR_SIZE => C_SCALP_NEIGHBORS_VECTOR_SIZE,
+            C_SCALP_SCHEDULER_STRATEGY    => C_SCALP_SCHEDULER_STRATEGY,
+            C_SCALP_SCHEDULER_OUTPUT_REG  => C_SCALP_SCHEDULER_OUTPUT_REG)
+        port map (
+            -- System Clock and Reset
+            SysClkxCI            => SysClkxC,
+            SysRstxRNAI          => SysRstxRNA,
+            -- Scheduler Ack Vector
+            SchedulerAckxDO      => SchedulerAckxD,
+            -- Booking Vector
+            BookingVectorxDI     => BookingVectorxD,
+            -- Axi Stream
+            -- Output Side
+            TXAxi4M2SLinkxDO     => TXAxi4M2SLinkxD,
+            TXAxi4S2MLinkxDI     => TXAxi4S2MLinkxD,
+            -- Input Side
+            RXAxi4M2SLinkxDI     => RXAxi4M2SLinkxD,
+            RXAxi4S2MLinkxDO     => RXAxi4S2MLinkxD,
+            -- Debug Interface
+            BookingIndexxDO      => BookingIndexxD,
+            BookingIndexValidxSO => BookingIndexValidxS);
+
+    ScalpAxisToSpxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4M2SLinkxD,
+            ScalpAxiss2mxDO     => TXAxi4S2MLinkxD,
+            ScalpPacketxDO      => ScalpPacketEndxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxD);
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+    end block AsyncStatementsxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    WaitSchedulerAckxG : for i in 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) generate
+        WaitSchedulerAckxP : process is
+        begin  -- process WaitSchedulerAckxP
+            wait until SchedulerAckxD(i) = '1';
+            wait until SchedulerAckxD(i) = '0';
+
+            SchedAckxS(i) <= '1';
+            wait;
+        end process WaitSchedulerAckxP;
+    end generate WaitSchedulerAckxG;
+
+    WaitScalpPacketValidEndxP : process is
+    begin  -- process WaitScalpPacketValidEndxP
+        for i in 0 to (C_SCALP_NEIGHBORS_VECTOR_SIZE - 1) loop
+            wait until ScalpPacketValidEndxD = '1';
+            wait until ScalpPacketValidEndxD = '0';
+        end loop;  -- i
+
+        SPValidEndxS <= '1';
+        wait;
+    end process WaitScalpPacketValidEndxP;
+
+    ScalpRXSidexP : process is
+    begin  -- process ScalpRXSidexP
+
+        -- TXAxi4S2MLinkxD.ReadyxS <= '0';
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        ScalpPacketValidxD <= (others => '0');
+        BookingVectorxD    <= (others => '0');
+
+        -- TXAxi4S2MLinkxD.ReadyxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxD <= "111111";
+        BookingVectorxD    <= "111111";
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxD <= (others => '0');
+
+        wait until
+            ((SchedAckxS(0) = '1') and
+             (SchedAckxS(1) = '1') and
+             (SchedAckxS(2) = '1') and
+             (SchedAckxS(3) = '1') and
+             (SchedAckxS(4) = '1') and
+             (SchedAckxS(5) = '1') and
+             SPValidEndxS = '1');
+
+        for i in 0 to 9 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        EndSimxS <= true;
+
+    end process ScalpRXSidexP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_scheduler.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_scheduler.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..bf0ad588e9e46aca8c8e454bc1f5bfece4ff476e
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_scheduler.vhd
@@ -0,0 +1,164 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_rr_scheduler.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_rr_scheduler.
+--
+-- Last update: 2020-01-17
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.scalp_misc.all;
+-- use work.scalp_utility.all;
+
+entity tb_scalp_scheduler is
+
+end entity tb_scalp_scheduler;
+
+architecture testbench of tb_scalp_scheduler is
+
+    constant C_SCALP_STRATEGY   : string   := "RR";
+    constant C_SCALP_PORTS      : positive := 6;
+    constant C_SCALP_OUTPUT_REG : boolean  := false;
+    constant C_CLK_PERIOD       : time     := 10 ns;
+
+    component scalp_scheduler is
+        generic (
+            C_SCALP_STRATEGY   : string;
+            C_SCALP_PORTS      : positive;
+            C_SCALP_OUTPUT_REG : boolean);
+        port (
+            SysClkxCI        : in  std_ulogic;
+            SysRstxRNAI      : in  std_ulogic;
+            ArbitratexSI     : in  std_ulogic;
+            RequestVectorxDI : in  std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+            ArbitratedxSO    : out std_ulogic;
+            GrantVectorxDO   : out std_ulogic_vector((C_SCALP_PORTS - 1) downto 0);
+            GrantIndexxDO    : out std_ulogic_vector((scalp_log2ceilnz(C_SCALP_PORTS) - 1) downto 0));
+    end component scalp_scheduler;
+
+    -- Entity signals
+    signal SysClkxC        : std_ulogic                                                        := '0';
+    signal SysRstxRNA      : std_ulogic                                                        := '0';
+    signal ArbitratexS     : std_ulogic                                                        := '0';
+    signal RequestVectorxD : std_ulogic_vector((C_SCALP_PORTS - 1) downto 0)                   := (others => '0');
+    signal ArbitratedxS    : std_ulogic                                                        := '0';
+    signal GrantVectorxD   : std_ulogic_vector((C_SCALP_PORTS - 1) downto 0)                   := (others => '0');
+    signal GrantIndexxD    : std_ulogic_vector((scalp_log2ceilnz(C_SCALP_PORTS) - 1) downto 0) := (others => '0');
+    -- Simulation signals
+    signal EndSimxS        : boolean                                                           := false;
+
+begin  -- architecture testbench
+
+    AsnycStatementsxB : block is
+    begin  -- block AsnycStatementsxB
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+    end block AsnycStatementsxB;
+
+    ScalpSchedulerxI : entity work.scalp_scheduler
+        generic map (
+            C_SCALP_STRATEGY   => C_SCALP_STRATEGY,
+            C_SCALP_PORTS      => C_SCALP_PORTS,
+            C_SCALP_OUTPUT_REG => C_SCALP_OUTPUT_REG)
+        port map (
+            SysClkxCI        => SysClkxC,
+            SysRstxRNAI      => SysRstxRNA,
+            ArbitratexSI     => ArbitratexS,
+            RequestVectorxDI => RequestVectorxD,
+            ArbitratedxSO    => ArbitratedxS,
+            GrantVectorxDO   => GrantVectorxD,
+            GrantIndexxDO    => GrantIndexxD);
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpSchedulerRequestxP : process is
+    begin  -- process ScalpSchedulerRequestxP
+        ArbitratexS     <= '0';
+        RequestVectorxD <= (others => '0');
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        for j in 0 to 3 loop
+            ArbitratexS     <= '1';
+            RequestVectorxD <= "100001";
+            for i in 0 to 8 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+            RequestVectorxD <= "101101";
+            for i in 0 to 3 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+            RequestVectorxD <= "000000";
+            for i in 0 to 2 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+            RequestVectorxD <= "111111";
+            for i in 0 to 9 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+            ArbitratexS     <= '0';
+            RequestVectorxD <= "000000";
+            for i in 0 to 3 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+        end loop;  -- j
+
+        for i in 0 to 15 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+
+        for j in 0 to 1 loop
+            ArbitratexS <= '1';
+            RequestVectorxD <= "111111";
+            for i in 0 to 9 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+            ArbitratexS <= '0';
+            for i in 0 to 1 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+            ArbitratexS <= '1';
+            for i in 0 to 9 loop
+                wait until rising_edge(SysClkxC);
+            end loop;  -- i
+        end loop;  -- j
+
+        EndSimxS <= true;
+    end process ScalpSchedulerRequestxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_sp_to_axis.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_sp_to_axis.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..182d7308d99559fc104e3271877fa3937abd6efd
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_sp_to_axis.vhd
@@ -0,0 +1,336 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_sp_to_axis.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_sp_to_axis module.
+--
+-- Last update: 2020-02-26
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+-- 31      23      15      7       0
+--     8       8       8       8
+-- ---------------------------------
+-- | x_dst | y_dst | z_dst | type  |
+-- ---------------------------------
+-- | x_src | y_srd | z_src |  pad  |
+-- ---------------------------------
+--        16              16
+-- ---------------------------------
+-- | payload_size  |     pad       |
+-- ---------------------------------
+--
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+--                .
+--                .
+--                .
+-- ---------------------------------
+-- |           payload             |
+-- ---------------------------------
+
+-- Register map
+--
+-- 31                              0
+-- ---------------------------------
+-- |             H0                | Dst addr + Type
+-- ---------------------------------
+-- ---------------------------------
+-- |             H1                | Src addr + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |             H2                | Pld size + Pad
+-- ---------------------------------
+-- ---------------------------------
+-- |              P                | N x Payload
+-- ---------------------------------
+
+entity tb_scalp_sp_to_axis is
+
+end entity tb_scalp_sp_to_axis;
+
+architecture testbench of tb_scalp_sp_to_axis is
+
+    constant C_CLK_PERIOD                : time                                                 := 10 ns;
+    constant C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+    constant C_SCALP_RANDOM_READY        : boolean                                              := true;
+    constant C_SCALP_DELAY_SIZE          : integer range 0 to 255                               := 10;
+
+    component scalp_sp_to_axis is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSI : in  std_ulogic;
+            ScalpAxism2sxDO     : out t_axi4m2s;
+            ScalpAxiss2mxDI     : in  t_axi4s2m;
+            ScalpRdyxSO         : out std_ulogic);
+    end component scalp_sp_to_axis;
+
+    component scalp_axis_to_sp is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+            C_SCALP_RANDOM_READY        : boolean);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpAxism2sxDI     : in  t_axi4m2s;
+            ScalpAxiss2mxDO     : out t_axi4s2m;
+            ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSO : out std_ulogic);
+    end component scalp_axis_to_sp;
+
+    -- Signals
+    signal SysClkxC           : std_ulogic := '0';
+    signal SysRstxRNA         : std_ulogic := '0';
+    signal ScalpPacketValidxS : std_ulogic := '0';
+    signal ScalpAxism2sxD     : t_axi4m2s  := C_NO_AXI4_M2S;
+    signal ScalpAxiss2mxD     : t_axi4s2m  := C_NO_AXI4_S2M;
+    signal EndSimxS           : boolean    := false;
+    signal ScalpPacketOutxD   : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)))
+        := (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+            SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+    signal ScalpPacketValidOutxS : std_ulogic := '0';
+    signal ScalpRdyxS            : std_ulogic := '0';
+
+    -- Scalp Packets Header
+    constant C_SP_HEADER_0 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 1,
+             YxD     => 2,
+             ZxD     => 3),
+            SrcAddrxD =>
+            (XxD     => 4,
+             YxD     => 5,
+             ZxD     => 6),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- Scalp Packets Payload
+    constant C_SP_PAYLOAD_0 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#01223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#02334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+    -- Scalp Packets
+    signal ScalpPacketxD : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)))
+        := (SpHeaderxD  => C_SP_HEADER_0,
+            SpPayloadxD => C_SP_PAYLOAD_0);
+
+begin  -- architecture testbench
+
+    SimCtrlxB : block is
+    begin  -- block SimCtrlxB
+        SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+    end block SimCtrlxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpSpToAxisxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketxD,
+            ScalpPacketValidxSI => ScalpPacketValidxS,
+            ScalpAxism2sxDO     => ScalpAxism2sxD,
+            ScalpAxiss2mxDI     => ScalpAxiss2mxD,
+            ScalpRdyxSO         => ScalpRdyxS);
+
+    ScalpAxisToSpxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => ScalpAxism2sxD,
+            ScalpAxiss2mxDO     => ScalpAxiss2mxD,
+            ScalpPacketxDO      => ScalpPacketOutxD,
+            ScalpPacketValidxSO => ScalpPacketValidOutxS);
+
+    ScalpPacketReqxP : process is
+    begin  -- process ScalpPacketReqxP
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        ScalpPacketValidxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '0';
+
+        wait until (ScalpPacketValidOutxS = '1');
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        -- Dst Addr
+        assert ScalpPacketxD.SpHeaderxD.DstAddrxD.XxD = ScalpPacketOutxD.SpHeaderxD.DstAddrxD.XxD
+            report "Error : DstAddr XxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.XxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.XxD) severity failure;
+        report "Valid : DstAddr XxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.XxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.XxD) severity note;
+
+        assert ScalpPacketxD.SpHeaderxD.DstAddrxD.YxD = ScalpPacketOutxD.SpHeaderxD.DstAddrxD.YxD
+            report "Error : DstAddr YxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.YxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.YxD) severity failure;
+        report "Valid : DstAddr YxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.YxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.YxD) severity note;
+
+        assert ScalpPacketxD.SpHeaderxD.DstAddrxD.ZxD = ScalpPacketOutxD.SpHeaderxD.DstAddrxD.ZxD
+            report "Error : DstAddr ZxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.ZxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.ZxD) severity failure;
+        report "Valid : DstAddr ZxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.DstAddrxD.ZxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.DstAddrxD.ZxD) severity note;
+
+        -- Src Addr
+        assert ScalpPacketxD.SpHeaderxD.SrcAddrxD.XxD = ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.XxD
+            report "Error : SrcAddr XxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.XxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.XxD) severity failure;
+        report "Valid : SrcAddr XxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.XxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.XxD) severity note;
+
+        assert ScalpPacketxD.SpHeaderxD.SrcAddrxD.YxD = ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.YxD
+            report "Error : SrcAddr YxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.YxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.YxD) severity failure;
+        report "Valid : SrcAddr YxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.YxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.YxD) severity note;
+
+        assert ScalpPacketxD.SpHeaderxD.SrcAddrxD.ZxD = ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.ZxD
+            report "Error : SrcAddr ZxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.ZxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.ZxD) severity failure;
+        report "Valid : SrcAddr ZxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.SrcAddrxD.ZxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.SrcAddrxD.ZxD) severity note;
+
+        -- Type
+        assert ScalpPacketxD.SpHeaderxD.TypexD = ScalpPacketOutxD.SpHeaderxD.TypexD
+            report "Error : TypexD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.TypexD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.TypexD) severity failure;
+        report "Valid : TypexD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.TypexD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.TypexD) severity note;
+
+        -- Length
+        assert ScalpPacketxD.SpHeaderxD.LengthxD = ScalpPacketOutxD.SpHeaderxD.LengthxD
+            report "Error : LengthxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.LengthxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.LengthxD) severity failure;
+        report "Valid : LengthxD " &
+            integer'image(ScalpPacketxD.SpHeaderxD.LengthxD) &
+            " /= " &
+            integer'image(ScalpPacketOutxD.SpHeaderxD.LengthxD) severity note;
+
+        for i in 0 to (ScalpPacketxD.SpHeaderxD.LengthxD - 1) loop
+            -- Length
+            assert ScalpPacketxD.SpPayloadxD(i).WordxD = ScalpPacketOutxD.SpPayloadxD(i).WordxD
+                report "Error : Payload(" & integer'image(i) & ") " &
+                str_ul(ScalpPacketxD.SpPayloadxD(i).WordxD) &
+                " /= " &
+                str_ul(ScalpPacketOutxD.SpPayloadxD(i).WordxD) severity failure;
+            report "Valid : Payload(" & integer'image(i) & ") " &
+                str_ul(ScalpPacketxD.SpPayloadxD(i).WordxD) &
+                " /= " &
+                str_ul(ScalpPacketOutxD.SpPayloadxD(i).WordxD) severity note;
+        end loop;  -- i
+
+        EndSimxS <= true;
+    end process ScalpPacketReqxP;
+
+end architecture testbench;
diff --git a/ips/hw/scalp_router/src/sim/tb_scalp_tx_side.vhd b/ips/hw/scalp_router/src/sim/tb_scalp_tx_side.vhd
new file mode 100644
index 0000000000000000000000000000000000000000..7c2c79b32824e2fb01de0c869ba0090e9ef8a96c
--- /dev/null
+++ b/ips/hw/scalp_router/src/sim/tb_scalp_tx_side.vhd
@@ -0,0 +1,283 @@
+----------------------------------------------------------------------------------
+--                                 _             _
+--                                | |_  ___ _ __(_)__ _
+--                                | ' \/ -_) '_ \ / _` |
+--                                |_||_\___| .__/_\__,_|
+--                                         |_|
+--
+----------------------------------------------------------------------------------
+--
+-- Company: hepia
+-- Author: Joachim Schmidt <joachim.schmidt@hesge.ch>
+--
+-- Module Name: tb_scalp_tx_side.vhd
+-- Target Device: SCALP xc7z015clg485-2
+-- Tool version: 2019.1
+-- Description: Testbench for scalp_tx_side.
+--
+-- Last update: 2020-02-12
+--
+---------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use ieee.math_real.all;
+-- use ieee.math_real.uniform;
+-- use ieee.math_real.floor;
+
+--use ieee.std_logic_unsigned.all;
+--use ieee.std_logic_arith.all;
+--use ieee.std_logic_misc.all;
+
+--library UNISIM;
+--use UNISIM.VCOMPONENTS.all;
+
+library work;
+use work.aurora_axi4_pkg.all;
+use work.scalp_misc.all;
+use work.scalp_utility.all;
+
+entity tb_scalp_tx_side is
+
+end entity tb_scalp_tx_side;
+
+architecture testbench of tb_scalp_tx_side is
+
+    constant C_CLK_PERIOD                      : time                                                 := 10 ns;
+    -- scalp_tx_side
+    constant C_SCALP_INTERFACE_VECTOR_SIZE     : integer range 0 to 255                               := 7;
+    constant C_SCALP_NEIGHBORS_VECTOR_SIZE     : integer range 0 to 255                               := 6;
+    constant C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255                               := 1;
+    constant C_SCALP_LOCAL_IF_ID               : integer range 0 to 255                               := C_NORTH_IF_ID;
+    -- scalp_sp_to_axis
+    constant C_SCALP_PACKET_PAYLOAD_SIZE       : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE := 8;
+    constant C_SCALP_RANDOM_READY              : boolean                                              := false;
+    constant C_SCALP_DELAY_SIZE                : integer range 0 to 255                               := 10;
+
+    -- Scalp Packet Headers
+    constant C_SP_HEADER_0 : t_scalp_packet_header
+        := (DstAddrxD =>
+            (XxD     => 1,
+             YxD     => 2,
+             ZxD     => 3),
+            SrcAddrxD =>
+            (XxD     => 4,
+             YxD     => 5,
+             ZxD     => 6),
+            TypexD   => 1,
+            LengthxD => C_SCALP_PACKET_PAYLOAD_SIZE);
+    -- Scalp Packet Payloads
+    constant C_SP_PAYLOAD_0 : t_scalp_packet_payload(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))
+        := (0 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0abbccdd#, (C_BYTE_SIZE * 4))),
+             IdxD   => 0),
+            1 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0bccddee#, (C_BYTE_SIZE * 4))),
+             IdxD   => 1),
+            2 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0cddeeff#, (C_BYTE_SIZE * 4))),
+             IdxD   => 2),
+            3 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0deeff11#, (C_BYTE_SIZE * 4))),
+             IdxD   => 3),
+            4 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0eff1122#, (C_BYTE_SIZE * 4))),
+             IdxD   => 4),
+            5 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#0f112233#, (C_BYTE_SIZE * 4))),
+             IdxD   => 5),
+            6 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#01223344#, (C_BYTE_SIZE * 4))),
+             IdxD   => 6),
+            7 =>
+            (WordxD => std_ulogic_vector(to_unsigned(16#02334455#, (C_BYTE_SIZE * 4))),
+             IdxD   => 7));
+
+    component scalp_sp_to_axis is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpPacketxDI      : in  t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSI : in  std_ulogic;
+            ScalpAxism2sxDO     : out t_axi4m2s;
+            ScalpAxiss2mxDI     : in  t_axi4s2m);
+    end component scalp_sp_to_axis;
+
+    component scalp_axis_to_sp is
+        generic (
+            C_SCALP_PACKET_PAYLOAD_SIZE : integer range 1 to C_SCALP_PACKET_LENGTH_RANGE_VALUE;
+            C_SCALP_RANDOM_READY        : boolean);
+        port (
+            SysClkxCI           : in  std_ulogic;
+            SysRstxRNAI         : in  std_ulogic;
+            ScalpAxism2sxDI     : in  t_axi4m2s;
+            ScalpAxiss2mxDO     : out t_axi4s2m;
+            ScalpPacketxDO      : out t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1)));
+            ScalpPacketValidxSO : out std_ulogic);
+    end component scalp_axis_to_sp;
+
+    component scalp_tx_side is
+        generic (
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE : integer range 0 to 255);
+        port (
+            SysClkxCI             : in  std_ulogic;
+            SysRstxRNAI           : in  std_ulogic;
+            DstRouterNetAddrxDO   : out t_scalp_netaddr;
+            RouterNetAddrValidxSO : out std_ulogic;
+            BookingVectorValidxSI : in  std_ulogic;
+            -- SchedulerAckxDI       : in  std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0);
+            RXAxi4M2SLinkxDI      : in  t_axi4m2s;
+            RXAxi4S2MLinkxDO      : out t_axi4s2m;
+            TXAxi4M2SLinkxDO      : out t_axi4m2s;
+            TXAxi4S2MLinkxDI      : in  t_axi4s2m);
+    end component scalp_tx_side;
+
+    -- Sys Clk and Sys nRst
+    signal SysClkxC             : std_ulogic      := '0';
+    signal SysRstxRNA           : std_ulogic      := '0';
+    -- End of Simulation
+    signal EndSimxS             : boolean         := false;
+    -- scalp_tx_side
+    signal DstRouterNetAddrxD   : t_scalp_netaddr := C_3D_MIN_SCALP_NETADDR;
+    signal RouterNetAddrValidxS : std_ulogic      := '0';
+    signal BookingVectorValidxS : std_ulogic      := '0';
+    -- signal SchedulerAckxD       : std_ulogic_vector((C_SCALP_SCHEDULER_ACK_VECTOR_SIZE - 1) downto 0) := (others => '0');
+    signal RXAxi4M2SLinkxD      : t_axi4m2s       := C_NO_AXI4_M2S;
+    signal RXAxi4S2MLinkxD      : t_axi4s2m       := C_NO_AXI4_S2M;
+    signal TXAxi4M2SLinkxD      : t_axi4m2s       := C_NO_AXI4_M2S;
+    signal TXAxi4S2MLinkxD      : t_axi4s2m       := C_NO_AXI4_S2M;
+    -- scalp_sp_to_axis
+    signal ScalpPacketValidxS   : std_ulogic      := '0';
+    signal ScalpPacketxD        : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_SP_HEADER_0,
+         SpPayloadxD => C_SP_PAYLOAD_0);
+    signal ScalpPacketValidEndxS : std_ulogic := '0';
+    signal ScalpPacketEndxD      : t_scalp_packet(SpPayloadxD(0 to (C_SCALP_PACKET_PAYLOAD_SIZE - 1))) :=
+        (SpHeaderxD  => C_NO_SCALP_PACKET_HEADER,
+         SpPayloadxD => (others => C_NO_SCALP_PACKET_WORD));
+
+begin  -- architecture testbench
+
+    ScalpSpToAxisxI : entity work.scalp_sp_to_axis
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpPacketxDI      => ScalpPacketxD,
+            ScalpPacketValidxSI => ScalpPacketValidxS,
+            ScalpAxism2sxDO     => RXAxi4M2SLinkxD,
+            ScalpAxiss2mxDI     => RXAxi4S2MLinkxD);
+
+    ScalpTXSidexI : entity work.scalp_tx_side
+        generic map (
+            C_SCALP_SCHEDULER_ACK_VECTOR_SIZE => C_SCALP_SCHEDULER_ACK_VECTOR_SIZE)
+        port map (
+            SysClkxCI             => SysClkxC,
+            SysRstxRNAI           => SysRstxRNA,
+            DstRouterNetAddrxDO   => DstRouterNetAddrxD,
+            RouterNetAddrValidxSO => RouterNetAddrValidxS,
+            BookingVectorValidxSI => BookingVectorValidxS,
+            -- SchedulerAckxDI       => SchedulerAckxD,
+            RXAxi4M2SLinkxDI      => RXAxi4M2SLinkxD,
+            RXAxi4S2MLinkxDO      => RXAxi4S2MLinkxD,
+            TXAxi4M2SLinkxDO      => TXAxi4M2SLinkxD,
+            TXAxi4S2MLinkxDI      => TXAxi4S2MLinkxD);
+
+    ScalpAxisToSpxI : entity work.scalp_axis_to_sp
+        generic map (
+            C_SCALP_PACKET_PAYLOAD_SIZE => C_SCALP_PACKET_PAYLOAD_SIZE,
+            C_SCALP_RANDOM_READY        => C_SCALP_RANDOM_READY)
+        port map (
+            SysClkxCI           => SysClkxC,
+            SysRstxRNAI         => SysRstxRNA,
+            ScalpAxism2sxDI     => TXAxi4M2SLinkxD,
+            ScalpAxiss2mxDO     => TXAxi4S2MLinkxD,
+            ScalpPacketxDO      => ScalpPacketEndxD,
+            ScalpPacketValidxSO => ScalpPacketValidEndxS);
+
+    AsyncStatementsxB : block is
+    begin  -- block AsyncStatementsxB
+
+        SysClkxAS : SysClkxC   <= not SysClkxC after (C_CLK_PERIOD / 2);
+        SysRstxAS : SysRstxRNA <= '1'          after (C_CLK_PERIOD * 10);
+
+    end block AsyncStatementsxB;
+
+    EndSimxP : process is
+    begin  -- process EndSimxP
+        if EndSimxS = true then
+            assert false report "End of simulation!" severity failure;
+        end if;
+
+        wait until rising_edge(SysClkxC);
+    end process EndSimxP;
+
+    ScalpTXSideGenxP : process is
+    begin  -- process ScalpTXSideGenxP
+
+        -- TXAxi4S2MLinkxD.ReadyxS <= '1';
+
+        wait until (SysRstxRNA = '1');
+        wait until rising_edge(SysClkxC);
+        wait until rising_edge(SysClkxC);
+
+        ScalpPacketValidxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        ScalpPacketValidxS <= '0';
+
+        for i in 0 to 5 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        BookingVectorValidxS <= '1';
+
+        for i in 0 to 0 loop
+            wait until rising_edge(SysClkxC);
+        end loop;  -- i
+
+        BookingVectorValidxS <= '0';
+
+        -- for i in 0 to 3 loop
+        --     wait until rising_edge(SysClkxC);
+        -- end loop;  -- i
+
+        -- TXAxi4S2MLinkxD.ReadyxS <= '0';
+
+        -- for i in 0 to 3 loop
+        --     wait until rising_edge(SysClkxC);
+        -- end loop;  -- i
+
+        -- TXAxi4S2MLinkxD.ReadyxS <= '1';
+
+        wait until (ScalpPacketValidEndxS = '1');
+
+        -- for i in 0 to 15 loop
+        --     wait until rising_edge(SysClkxC);
+        -- end loop;  -- i
+
+        -- SchedulerAckxD(0) <= '1';
+
+        -- wait until (RXAxi4S2MLinkxD.ReadyxS = '1');
+
+        -- for i in 0 to 0 loop
+        --     wait until rising_edge(SysClkxC);
+        -- end loop;  -- i
+
+        EndSimxS <= true;
+
+    end process ScalpTXSideGenxP;
+
+end architecture testbench;
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/.prompt_colors.tcl b/ips/vivado/scalp_router/2019.2/lin64/.scripts/.prompt_colors.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..767df68e83e0d70c340cb5ba74ef357b823cfe25
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/.prompt_colors.tcl
@@ -0,0 +1,37 @@
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: Console color print utility
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+# Text attributes
+set RESET [exec tput sgr0]
+set BOLD [exec tput bold]
+set ITALIC [exec tput sitm]
+set BLINK [exec tput blink]
+set HIGHL [exec tput smso]
+
+# Text colors
+set RED [exec tput setaf 1]
+set GREEN [exec tput setaf 2]
+set YELLOW [exec tput setaf 3]
+set BLUE [exec tput setaf 4]
+set MAGENTA [exec tput setaf 5]
+set CYAN [exec tput setaf 6]
+set WHITE [exec tput setaf 7]
+
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/clean_prj_scalp_router.sh b/ips/vivado/scalp_router/2019.2/lin64/.scripts/clean_prj_scalp_router.sh
new file mode 100755
index 0000000000000000000000000000000000000000..e407363af2c5765de1ce97a92ae099256d6c64a4
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/clean_prj_scalp_router.sh
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: Cleanup project directory
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+echo "> Cleanup project directory..."
+
+PRJ_DIR=..
+
+# Clean current directory
+rm -rf ${PRJ_DIR}/.Xil/ 2> /dev/null
+
+# Remove generated project directory
+rm -rf ${PRJ_DIR}/scalp_router/ 2> /dev/null
+
+# Clean app directory
+rm ${PRJ_DIR}/app/*.h 2> /dev/null
+rm ${PRJ_DIR}/app/*.c 2> /dev/null
+rm ${PRJ_DIR}/app/*.html 2> /dev/null
+
+echo "> Done"
+
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.sh b/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.sh
new file mode 100755
index 0000000000000000000000000000000000000000..123e6cdcc1bae124f8555bd0fe7c2f20f41fdc0f
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: Create Vivado project
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+echo "> Create Vivado project..."
+vivado -nojournal -nolog -mode tcl -source create_prj_scalp_router.tcl -notrace
+echo "> Done"
+
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.tcl b/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..9cea07da1378864e12b96608cd29e4146ed609dc
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/create_prj_scalp_router.tcl
@@ -0,0 +1,168 @@
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: TCL script for re-creating Vivado project 'scalp_router'
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+# Include files
+source utils.tcl
+
+set PRJ_DIR ".."
+set prj_name "scalp_router"
+set PKG_DIR "${PRJ_DIR}/../../../../../packages"
+set SOC_DIR "${PRJ_DIR}/../../../../../soc/"
+
+# Set project type
+set PRJ_TYPE "COMP_PRJ_TYPE"
+
+# Create a variable to store the start time
+set start_time [clock format [clock seconds] -format {%b. %d, %Y %I:%M:%S %p}]
+
+# Set the original project directory path for adding/importing sources in the new project
+set src_dir "${PRJ_DIR}/../src"
+set ip_dir "${PRJ_DIR}/../../../../../ips/hw"
+set comp_dir "${ip_dir}/$prj_name"
+set comp_src_dir "${comp_dir}/src"
+set pkg_src_dir "${PKG_DIR}/hw"
+set soc_src_dir "${SOC_DIR}/hw"
+print_status "Set directory paths" "OK"
+
+# Create the project
+create_project $prj_name ${PRJ_DIR}/$prj_name -part xc7z015clg485-2
+#set_property board_part SCALP [current_project]
+set_property target_language VHDL [current_project]
+print_status "Create project" "OK"
+
+# Map the IP Repository so that custom IP is included
+set_property ip_repo_paths $ip_dir [current_fileset]
+update_ip_catalog
+
+#----------------------------------------------------------------
+# Add project sources
+#----------------------------------------------------------------
+
+if {$PRJ_TYPE == "DESIGN_PRJ_TYPE"} {
+	# add HDL sources
+	set vhdl_src_file_list [findFiles $src_dir/hdl *.vhd]
+	set verilog_src_file_list [findFiles $src_dir/hdl *.v]
+	set hdl_src_file_list [list {*}$vhdl_src_file_list {*}$verilog_src_file_list]
+	add_files -norecurse $hdl_src_file_list    
+	# add the constraints file (XDC)
+	add_files -fileset constrs_1 -norecurse  $src_dir/constrs/${prj_name}.xdc
+	set_property is_enabled true [get_files $src_dir/constrs/${prj_name}.xdc]
+
+	# add IPs source file
+
+	#read_ip $src_dir/custom_ip/ip_0/ip_0.xci
+} elseif {$PRJ_TYPE == "COMP_PRJ_TYPE"} {
+	# components sources are stored in an external directory
+	# add the project component
+	set vhdl_src_file_list [findFiles $comp_src_dir/hdl *.vhd]
+	set verilog_src_file_list [findFiles $comp_src_dir/hdl *.v]
+	set hdl_src_file_list [list {*}$vhdl_src_file_list {*}$verilog_src_file_list]
+	add_files -norecurse $hdl_src_file_list
+	# add IPs source file
+	#read_ip $comp_src_dir/ip_core/ip_0/ip_0.xci
+
+	# add IP-XACT source file
+	#add_files -norecurse $comp_dir/component.xml
+}
+print_status "Add project sources" "OK"
+
+foreach j $vhdl_src_file_list {
+    set_property file_type {VHDL 2008} [get_files  $j]
+    print_status "VHDL 2008 mode configured for the file $j" "OK"
+}
+print_status "VHDL 2008 mode configured for project sources" "OK"
+
+#----------------------------------------------------------------
+# Add constraints files
+#----------------------------------------------------------------
+
+
+# Set packages libraries if any
+#set_property library library_name [get_files  $src_dir/hdl/package_name.vhd]
+#update_compile_order -fileset sources_1
+
+# Create the IP Integrator portion of the design
+#create_bd_design "axi_design"
+#update_compile_order -fileset sources_1
+
+# launch the TCL script to generate the IPI design
+source $src_dir/ipi_tcl/${prj_name}_ipi.tcl
+print_status "Add IPI design" "OK"
+
+# Set the top level design
+set_property top $prj_name [current_fileset]
+update_compile_order -fileset sources_1
+
+# Add testbench sources
+if {$PRJ_TYPE == "DESIGN_PRJ_TYPE"} {
+	set vhdl_sim_file_list [findFiles $src_dir/sim *.vhd]
+	set verilog_sim_file_list [findFiles $src_dir/sim *.v]
+} elseif {$PRJ_TYPE == "COMP_PRJ_TYPE"} {
+	set vhdl_sim_file_list [findFiles $comp_src_dir/sim *.vhd]
+	set verilog_sim_file_list [findFiles $comp_src_dir/sim *.v]
+}
+set hdl_sim_file_list [list {*}$vhdl_sim_file_list {*}$verilog_sim_file_list]
+add_files -fileset sim_1 -norecurse $hdl_sim_file_list
+update_compile_order -fileset sim_1
+print_status "Add testbench sources" "OK"
+
+foreach j $vhdl_sim_file_list {
+    set_property file_type {VHDL 2008} [get_files  $j]
+    print_status "VHDL 2008 mode configured for the file $j" "OK"
+}
+print_status "VHDL 2008 mode configured for testbench sources" "OK"
+
+# Add packages sources
+	set vhdl_pkg_file_list [findFiles ${PRJ_DIR}/../../../../../packages/hw/aurora_drp_pkg/src/hdl *.vhd]
+	add_files -norecurse $vhdl_pkg_file_list
+	foreach j $vhdl_pkg_file_list {
+		set_property file_type {VHDL 2008} [get_files  $j]
+		print_status "VHDL 2008 mode configured for the file $j" "OK"
+		set_property is_enabled false [get_files $j]
+	}
+	set vhdl_pkg_file_list [findFiles ${PRJ_DIR}/../../../../../packages/hw/aurora_status_pkg/src/hdl *.vhd]
+	add_files -norecurse $vhdl_pkg_file_list
+	foreach j $vhdl_pkg_file_list {
+		set_property file_type {VHDL 2008} [get_files  $j]
+		print_status "VHDL 2008 mode configured for the file $j" "OK"
+		set_property is_enabled true [get_files $j]
+	}
+	set vhdl_pkg_file_list [findFiles ${PRJ_DIR}/../../../../../packages/hw/axi4_pkg/src/hdl *.vhd]
+	add_files -norecurse $vhdl_pkg_file_list
+	foreach j $vhdl_pkg_file_list {
+		set_property file_type {VHDL 2008} [get_files  $j]
+		print_status "VHDL 2008 mode configured for the file $j" "OK"
+		set_property is_enabled true [get_files $j]
+	}
+print_status "Add packages sources" "OK"
+print_status "VHDL 2008 mode configured for packages sources" "OK"
+
+# Add SoC wrapper sources files
+
+
+# Set the completion time
+set end_time [clock format [clock seconds] -format {%b. %d, %Y %I:%M:%S %p}]
+
+# Display the start and end time to the screen
+puts $start_time
+puts $end_time
+
+exit
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/open_prj_scalp_router.sh b/ips/vivado/scalp_router/2019.2/lin64/.scripts/open_prj_scalp_router.sh
new file mode 100755
index 0000000000000000000000000000000000000000..deac5a22d4b8941add3391832b1bc534e1971ffd
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/open_prj_scalp_router.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: Create Vivado project
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+echo "> Open Vivado GUI..."
+vivado -nojournal -nolog -notrace ../scalp_router/scalp_router.xpr
diff --git a/ips/vivado/scalp_router/2019.2/lin64/.scripts/utils.tcl b/ips/vivado/scalp_router/2019.2/lin64/.scripts/utils.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..2d6ab4266e7d9ae32d032b9b67ff6428bf2a55cc
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/.scripts/utils.tcl
@@ -0,0 +1,62 @@
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: Project management utilities
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+# findFiles
+# basedir - the directory to start looking in
+# pattern - A pattern, as defined by the glob command, that the files must match
+proc findFiles { basedir pattern } {
+
+    # Fix the directory name, this ensures the directory name is in the
+    # native format for the platform and contains a final directory seperator
+    set basedir [string trimright [file join [file normalize $basedir] { }]]
+    set fileList {}
+
+    # Look in the current directory for matching files, -type {f r}
+    # means ony readable normal files are looked at, -nocomplain stops
+    # an error being thrown if the returned list is empty
+    foreach fileName [glob -nocomplain -type {f r} -path $basedir $pattern] {
+        lappend fileList $fileName
+    }
+
+    # Now look for any sub direcories in the current directory
+    foreach dirName [glob -nocomplain -type {d  r} -path $basedir *] {
+        # Recusively call the routine on the sub directory and append any
+        # new files to the results
+        set subDirList [findFiles $dirName $pattern]
+        if { [llength $subDirList] > 0 } {
+            foreach subDirFile $subDirList {
+                lappend fileList $subDirFile
+            }
+        }
+    }
+    return $fileList
+}
+
+
+# Print a progress status
+# str The string describing the current status
+# status The status as a string (eg. "OK", "FAILED")
+proc print_status {str status} {
+    set MAX_STR_LENGTH 70
+    source .prompt_colors.tcl
+    puts "${CYAN}>${YELLOW} $str [string repeat " " [expr {$MAX_STR_LENGTH - [string length $str]}]]\[${GREEN}${status}${YELLOW}\]${RESET}"
+}
+
diff --git a/ips/vivado/scalp_router/2019.2/lin64/setup.sh b/ips/vivado/scalp_router/2019.2/lin64/setup.sh
new file mode 100755
index 0000000000000000000000000000000000000000..fd872bf2978bbefd2854458ecda37d53e01f0c89
--- /dev/null
+++ b/ips/vivado/scalp_router/2019.2/lin64/setup.sh
@@ -0,0 +1,30 @@
+##################################################################################
+#                                 _             _
+#                                | |_  ___ _ __(_)__ _
+#                                | ' \/ -_) '_ \ / _` |
+#                                |_||_\___| .__/_\__,_|
+#                                         |_|
+#
+##################################################################################
+#
+# Company: hepia
+# Author: Joachim Schmidt <joachim.schmidt@hesge.ch
+#
+# Project Name: scalp_router
+# Target Device: SCALP xc7z015clg485-2
+# Tool version: 2019.2
+# Description: TCL script creating aliases for Vivado project management scripts
+#
+# Last update: 2020-11-30 08:31:15
+#
+##################################################################################
+
+# Create aliases
+alias create_project='cd .scripts && ./create_prj_scalp_router.sh && cd ..'
+alias clean_project='cd .scripts && ./clean_prj_scalp_router.sh && cd ..'
+alias export_hw='cd .scripts && ./export_hw_scalp_router.sh && cd ..'
+alias gen_bitstream='cd .scripts && ./gen_bitstream_scalp_router.sh && cd ..'
+alias load_bitstream='cd .scripts && ./load_bitstream_scalp_router.sh && cd ..'
+alias gen_sw_apps='cd .scripts && ./gen_sw_apps_scalp_router.sh && cd ..'
+alias load_sw_app='cd .scripts && ./load_sw_app_scalp_router.sh && cd ..'
+alias open_gui='cd .scripts && ./open_prj_scalp_router.sh && cd ..'
diff --git a/ips/vivado/scalp_router/2019.2/src/ipi_tcl/scalp_router_ipi.tcl b/ips/vivado/scalp_router/2019.2/src/ipi_tcl/scalp_router_ipi.tcl
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tools/config/scalp_router.json b/tools/config/scalp_router.json
new file mode 100644
index 0000000000000000000000000000000000000000..03301dd856de0ebff0bf73cb0972535118ea7d01
--- /dev/null
+++ b/tools/config/scalp_router.json
@@ -0,0 +1,27 @@
+{
+    "author" : {
+        "name"  : "Joachim Schmidt",
+        "email" : "<joachim.schmidt@hesge.ch"
+    },
+    "project" : {
+        "name"            : "scalp_router",
+        "type"            : "COMP_PRJ_TYPE",
+        "category"        : "IPS",
+        "vivado_version"  : "2019.2",
+        "target_language" : "VHDL",
+        "vhdl_version"    : "VHDL 2008"
+    },
+    "hardware" : {
+        "part_name"  : "xc7z015clg485-2",
+        "board_name" : "SCALP"
+    },
+    "components" : {
+        "packages" : {
+            "aurora_drp_pkg"    : "disable",
+            "aurora_status_pkg" : "enable",
+            "axi4_pkg"          : "enable"
+        },
+        "ips" : {
+        }        
+    }
+}