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" : { + } + } +}