From cf073173a3d20f2a93d5df20701ef80863455b8c Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 10 Jun 2024 22:27:56 -0700 Subject: [PATCH 01/43] Create SaciAxiLiteMaster module --- protocols/saci/rtl/SaciAxiLiteMaster.vhd | 111 +++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 protocols/saci/rtl/SaciAxiLiteMaster.vhd diff --git a/protocols/saci/rtl/SaciAxiLiteMaster.vhd b/protocols/saci/rtl/SaciAxiLiteMaster.vhd new file mode 100644 index 0000000000..2ee688c5ee --- /dev/null +++ b/protocols/saci/rtl/SaciAxiLiteMaster.vhd @@ -0,0 +1,111 @@ +------------------------------------------------------------------------------- +-- Title : SACI Protocol: https://confluence.slac.stanford.edu/x/YYcRDQ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: New and improved version of the AxiLiteSaciMaster. +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; +use surf.SaciMasterPkg.all; + +entity AxiLiteSaciMaster is + generic ( + TPD_G : time := 1 ns); + port ( + -- SACI Slave interface + saciClk : in sl; + saciCmd : in sl; + saciSelL : in sl; + saciRsp : out sl; + -- AXI-Lite Register Interface + axilClk : in sl; + axilRst : in sl; + axilReadMaster : in AxiLiteReadMasterType; + axilReadSlave : out AxiLiteReadSlaveType; + axilWriteMaster : in AxiLiteWriteMasterType; + axilWriteSlave : out AxiLiteWriteSlaveType); +end AxiLiteSaciMaster; + +architecture rtl of AxiLiteSaciMaster is + + -- AXI-Lite Master Interface + signal axilReq : AxiLiteReqType; + signal axilAck : AxiLiteAckType; + + -- SACI Slave parallel interface + signal exec : sl; + signal ack : sl; + signal readL : sl; + signal cmd : slv(6 downto 0); + signal addr : slv(11 downto 0); + signal wrData : slv(31 downto 0); + signal rdData : slv(31 downto 0); + + + -- attribute dont_touch : string; + -- attribute dont_touch of r : signal is "true"; + +begin + + U_SaciSlave_1 : entity surf.SaciSlave + generic map ( + TPD_G => TPD_G) + port map ( + rstL => rstL, -- [in] + saciClk => saciClk, -- [in] + saciSelL => saciSelL, -- [in] + saciCmd => saciCmd, -- [in] + saciRsp => saciRsp, -- [out] + rstOutL => rstOutL, -- [out] + rstInL => rstInL, -- [in] + exec => exec, -- [out] + ack => ack, -- [in] + readL => readL, -- [out] + cmd => cmd, -- [out] + addr => addr, -- [out] + wrData => wrData, -- [out] + rdData => rdData); -- [in] + + axilReq.request <= exec; + axilReq.rnw <= not readL; + axilReq.address(1 downto 0) <= "00"; + axilReq.address(13 downto 2) <= addr; + axilReq.address(20 downto 14) <= cmd; + axilReq.wrData <= wrData; + + ack <= axilAck.done; + rdData <= axilAck.rdData; + + U_AxiLiteMaster_1 : entity surf.AxiLiteMaster + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => true) + port map ( + axilClk => axilClk, -- [in] + axilRst => axilRst, -- [in] + req => axilReq, -- [in] + ack => axilAck, -- [out] + axilWriteMaster => axilWriteMaster, -- [out] + axilWriteSlave => axilWriteSlave, -- [in] + axilReadMaster => axilReadMaster, -- [out] + axilReadSlave => axilReadSlave); -- [in] + + +end rtl; From 9c6aee9d9c0a240ffdc0726d7dc13350faafbb8a Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Jul 2024 17:41:52 -0700 Subject: [PATCH 02/43] depreciating VLAN support in ethernet/EthMacCore because never tested and never used --- ethernet/EthMacCore/rtl/EthMacFlowCtrl.vhd | 25 +- ethernet/EthMacCore/rtl/EthMacRx.vhd | 76 ++---- ethernet/EthMacCore/rtl/EthMacRxCsum.vhd | 170 ++++-------- ethernet/EthMacCore/rtl/EthMacRxFifo.vhd | 96 ++----- ethernet/EthMacCore/rtl/EthMacRxPause.vhd | 111 ++------ ethernet/EthMacCore/rtl/EthMacTop.vhd | 198 +++++--------- ethernet/EthMacCore/rtl/EthMacTx.vhd | 73 +----- ethernet/EthMacCore/rtl/EthMacTxCsum.vhd | 286 ++++++--------------- ethernet/EthMacCore/rtl/EthMacTxFifo.vhd | 83 +----- ethernet/EthMacCore/rtl/EthMacTxPause.vhd | 76 +----- 10 files changed, 314 insertions(+), 880 deletions(-) mode change 100755 => 100644 ethernet/EthMacCore/rtl/EthMacRxCsum.vhd diff --git a/ethernet/EthMacCore/rtl/EthMacFlowCtrl.vhd b/ethernet/EthMacCore/rtl/EthMacFlowCtrl.vhd index c6d3de548e..ced8f0353d 100644 --- a/ethernet/EthMacCore/rtl/EthMacFlowCtrl.vhd +++ b/ethernet/EthMacCore/rtl/EthMacFlowCtrl.vhd @@ -17,17 +17,14 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; entity EthMacFlowCtrl is generic ( - TPD_G : time := 1 ns; - BYP_EN_G : boolean := false; - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1); + TPD_G : time := 1 ns; + BYP_EN_G : boolean := false); port ( -- Clock and Reset ethClk : in sl; @@ -35,7 +32,6 @@ entity EthMacFlowCtrl is -- Inputs primCtrl : in AxiStreamCtrlType; bypCtrl : in AxiStreamCtrlType; - vlanCtrl : in AxiStreamCtrlArray(VLAN_SIZE_G-1 downto 0); -- Output flowCtrl : out AxiStreamCtrlType); end EthMacFlowCtrl; @@ -56,7 +52,7 @@ architecture rtl of EthMacFlowCtrl is begin - comb : process (bypCtrl, ethRst, primCtrl, r, vlanCtrl) is + comb : process (bypCtrl, ethRst, primCtrl, r) is variable v : RegType; variable i : natural; begin @@ -80,21 +76,6 @@ begin end if; end if; - -- Check if VLAN interface is enabled - if (VLAN_EN_G) then - -- Loop through the channels - for i in (VLAN_SIZE_G-1) downto 0 loop - -- Sample the VLAN pause - if (vlanCtrl(i).pause = '1') then - v.flowCtrl.pause := '1'; - end if; - -- Sample the VLAN overflow - if (vlanCtrl(i).overflow = '1') then - v.flowCtrl.overflow := '1'; - end if; - end loop; - end if; - -- Reset if (ethRst = '1') then v := REG_INIT_C; diff --git a/ethernet/EthMacCore/rtl/EthMacRx.vhd b/ethernet/EthMacCore/rtl/EthMacRx.vhd index d4d799cf95..f1f5485903 100644 --- a/ethernet/EthMacCore/rtl/EthMacRx.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRx.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.AxiStreamPkg.all; use surf.StdRtlPkg.all; @@ -26,21 +25,17 @@ use surf.EthMacPkg.all; entity EthMacRx is generic ( -- Simulation Generics - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; -- MAC Configurations - PAUSE_EN_G : boolean := true; - PHY_TYPE_G : string := "XGMII"; - JUMBO_G : boolean := true; - -- Non-VLAN Configurations - FILT_EN_G : boolean := false; - BYP_EN_G : boolean := false; - BYP_ETH_TYPE_G : slv(15 downto 0) := x"0000"; - -- VLAN Configurations - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1; - VLAN_VID_G : Slv12Array := (0 => x"001"); - -- Internal RAM sythesis mode - SYNTH_MODE_G : string := "inferred"); + PAUSE_EN_G : boolean := true; + PHY_TYPE_G : string := "XGMII"; + JUMBO_G : boolean := true; + -- Misc. Configurations + FILT_EN_G : boolean := false; + BYP_EN_G : boolean := false; + BYP_ETH_TYPE_G : slv(15 downto 0) := x"0000"; + -- Internal RAM synthesis mode + SYNTH_MODE_G : string := "inferred"); port ( -- Clock and Reset ethClkEn : in sl; @@ -52,9 +47,6 @@ entity EthMacRx is -- Bypass Interface mBypMaster : out AxiStreamMasterType; mBypCtrl : in AxiStreamCtrlType; - -- VLAN Interfaces - mVlanMasters : out AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - mVlanCtrl : in AxiStreamCtrlArray(VLAN_SIZE_G-1 downto 0); -- XLGMII PHY Interface xlgmiiRxd : in slv(127 downto 0); xlgmiiRxc : in slv(15 downto 0); @@ -79,7 +71,6 @@ architecture mapping of EthMacRx is signal macIbMaster : AxiStreamMasterType; signal pauseMaster : AxiStreamMasterType; - signal pauseMasters : AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); signal csumMaster : AxiStreamMasterType; signal bypassMaster : AxiStreamMasterType; @@ -120,11 +111,8 @@ begin ------------------ U_Pause : entity surf.EthMacRxPause generic map ( - TPD_G => TPD_G, - PAUSE_EN_G => PAUSE_EN_G, - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G, - VLAN_VID_G => VLAN_VID_G) + TPD_G => TPD_G, + PAUSE_EN_G => PAUSE_EN_G) port map ( -- Clock and Reset ethClk => ethClk, @@ -133,19 +121,17 @@ begin sAxisMaster => macIbMaster, -- Outgoing data mAxisMaster => pauseMaster, - mAxisMasters => pauseMasters, -- Pause Values rxPauseReq => rxPauseReq, rxPauseValue => rxPauseValue); - ------------------------------ - -- RX Non-VLAN Checksum Module - ------------------------------ + --------------------- + -- RX Checksum Module + --------------------- U_Csum : entity surf.EthMacRxCsum generic map ( TPD_G => TPD_G, - JUMBO_G => JUMBO_G, - VLAN_G => false) + JUMBO_G => JUMBO_G) port map ( -- Clock and Reset ethClk => ethClk, @@ -158,36 +144,6 @@ begin sAxisMaster => pauseMaster, mAxisMaster => csumMaster); - -------------------------- - -- RX VLAN Checksum Module - -------------------------- - GEN_VLAN : if (VLAN_EN_G = true) generate - GEN_VEC : - for i in (VLAN_SIZE_G-1) downto 0 generate - U_Csum : entity surf.EthMacRxCsum - generic map ( - TPD_G => TPD_G, - JUMBO_G => JUMBO_G, - VLAN_G => true) - port map ( - -- Clock and Reset - ethClk => ethClk, - ethRst => ethRst, - -- Configurations - ipCsumEn => '1', - tcpCsumEn => '1', - udpCsumEn => '1', - -- Outbound data to MAC - sAxisMaster => pauseMasters(i), - mAxisMaster => mVlanMasters(i)); - end generate GEN_VEC; - end generate; - - BYPASS_VLAN : if (VLAN_EN_G = false) generate - -- Terminate Unused buses - mVlanMasters <= (others => AXI_STREAM_MASTER_INIT_C); - end generate; - ------------------- -- RX Bypass Module ------------------- diff --git a/ethernet/EthMacCore/rtl/EthMacRxCsum.vhd b/ethernet/EthMacCore/rtl/EthMacRxCsum.vhd old mode 100755 new mode 100644 index e9e1c0e124..c4374cd0b9 --- a/ethernet/EthMacCore/rtl/EthMacRxCsum.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRxCsum.vhd @@ -18,7 +18,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -27,8 +26,7 @@ use surf.EthMacPkg.all; entity EthMacRxCsum is generic ( TPD_G : time := 1 ns; - JUMBO_G : boolean := true; - VLAN_G : boolean := false); + JUMBO_G : boolean := true); port ( -- Clock and Reset ethClk : in sl; @@ -193,19 +191,16 @@ begin v.mAxisMaster := sAxisMaster; -- Check for no EOF if (sAxisMaster.tLast = '0') then - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Check for EtherType = IPV4 = 0x0800 - if (sAxisMaster.tData(111 downto 96) = IPV4_TYPE_C) then - -- Set the flag - v.ipv4Det(0) := '1'; - end if; - -- Fill in the IPv4 header checksum - v.ipv4Hdr(0) := sAxisMaster.tData(119 downto 112); -- IPVersion + Header length - v.ipv4Hdr(1) := sAxisMaster.tData(127 downto 120); -- DSCP and ECN + -- Check for EtherType = IPV4 = 0x0800 + if (sAxisMaster.tData(111 downto 96) = IPV4_TYPE_C) then + -- Set the flag + v.ipv4Det(0) := '1'; end if; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(0) := sAxisMaster.tData(119 downto 112); -- IPVersion + Header length + v.ipv4Hdr(1) := sAxisMaster.tData(127 downto 120); -- DSCP and ECN -- Next state - v.state := IPV4_HDR0_S; + v.state := IPV4_HDR0_S; end if; end if; ---------------------------------------------------------------------- @@ -221,53 +216,27 @@ begin -- Next state v.state := IDLE_S; else - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Fill in the IPv4 header checksum - v.ipv4Hdr(2) := sAxisMaster.tData(7 downto 0); -- IPV4_Length(15 downto 8) - v.ipv4Hdr(3) := sAxisMaster.tData(15 downto 8); -- IPV4_Length(7 downto 0) - v.ipv4Hdr(4) := sAxisMaster.tData(23 downto 16); -- IPV4_ID(15 downto 8) - v.ipv4Hdr(5) := sAxisMaster.tData(31 downto 24); -- IPV4_ID(7 downto 0) - v.ipv4Hdr(6) := sAxisMaster.tData(39 downto 32); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) - v.ipv4Hdr(7) := sAxisMaster.tData(47 downto 40); -- Fragment Offsets(7 downto 0) - v.ipv4Hdr(8) := sAxisMaster.tData(55 downto 48); -- Time-To-Live - v.ipv4Hdr(9) := sAxisMaster.tData(63 downto 56); -- Protocol - v.ipv4Hdr(10) := sAxisMaster.tData(71 downto 64); -- IPV4_Checksum(15 downto 8) - v.ipv4Hdr(11) := sAxisMaster.tData(79 downto 72); -- IPV4_Checksum(7 downto 0) - v.ipv4Hdr(12) := sAxisMaster.tData(87 downto 80); -- Source IP Address - v.ipv4Hdr(13) := sAxisMaster.tData(95 downto 88); -- Source IP Address - v.ipv4Hdr(14) := sAxisMaster.tData(103 downto 96); -- Source IP Address - v.ipv4Hdr(15) := sAxisMaster.tData(111 downto 104); -- Source IP Address - v.ipv4Hdr(16) := sAxisMaster.tData(119 downto 112); -- Destination IP Address - v.ipv4Hdr(17) := sAxisMaster.tData(127 downto 120); -- Destination IP Address - -- Fill in the TCP/UDP checksum - v.tData(63 downto 0) := sAxisMaster.tData(127 downto 80) & sAxisMaster.tData(63 downto 56) & x"00"; - v.tKeep(7 downto 0) := (others => '1'); - else - -- Check for EtherType = IPV4 = 0x0800 - if (sAxisMaster.tData(15 downto 0) = IPV4_TYPE_C) then - -- Set the flag - v.ipv4Det(0) := '1'; - end if; - -- Fill in the IPv4 header checksum - v.ipv4Hdr(0) := sAxisMaster.tData(23 downto 16); -- IPVersion + Header length - v.ipv4Hdr(1) := sAxisMaster.tData(31 downto 24); -- DSCP and ECN - v.ipv4Hdr(2) := sAxisMaster.tData(39 downto 32); -- IPV4_Length(15 downto 8) - v.ipv4Hdr(3) := sAxisMaster.tData(47 downto 40); -- IPV4_Length(7 downto 0) - v.ipv4Hdr(4) := sAxisMaster.tData(55 downto 48); -- IPV4_ID(15 downto 8) - v.ipv4Hdr(5) := sAxisMaster.tData(63 downto 56); -- IPV4_ID(7 downto 0) - v.ipv4Hdr(6) := sAxisMaster.tData(71 downto 64); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) - v.ipv4Hdr(7) := sAxisMaster.tData(79 downto 72); -- Fragment Offsets(7 downto 0) - v.ipv4Hdr(8) := sAxisMaster.tData(87 downto 80); -- Time-To-Live - v.ipv4Hdr(9) := sAxisMaster.tData(95 downto 88); -- Protocol - v.ipv4Hdr(10) := sAxisMaster.tData(103 downto 96); -- IPV4_Checksum(15 downto 8) - v.ipv4Hdr(11) := sAxisMaster.tData(111 downto 104); -- IPV4_Checksum(7 downto 0) - v.ipv4Hdr(12) := sAxisMaster.tData(119 downto 112); -- Source IP Address - v.ipv4Hdr(13) := sAxisMaster.tData(127 downto 120); -- Source IP Address - -- Fill in the TCP/UDP checksum - v.tData(31 downto 0) := sAxisMaster.tData(127 downto 112) & sAxisMaster.tData(95 downto 88) & x"00"; - v.tKeep(3 downto 0) := (others => '1'); - end if; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(2) := sAxisMaster.tData(7 downto 0); -- IPV4_Length(15 downto 8) + v.ipv4Hdr(3) := sAxisMaster.tData(15 downto 8); -- IPV4_Length(7 downto 0) + v.ipv4Hdr(4) := sAxisMaster.tData(23 downto 16); -- IPV4_ID(15 downto 8) + v.ipv4Hdr(5) := sAxisMaster.tData(31 downto 24); -- IPV4_ID(7 downto 0) + v.ipv4Hdr(6) := sAxisMaster.tData(39 downto 32); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) + v.ipv4Hdr(7) := sAxisMaster.tData(47 downto 40); -- Fragment Offsets(7 downto 0) + v.ipv4Hdr(8) := sAxisMaster.tData(55 downto 48); -- Time-To-Live + v.ipv4Hdr(9) := sAxisMaster.tData(63 downto 56); -- Protocol + v.ipv4Hdr(10) := sAxisMaster.tData(71 downto 64); -- IPV4_Checksum(15 downto 8) + v.ipv4Hdr(11) := sAxisMaster.tData(79 downto 72); -- IPV4_Checksum(7 downto 0) + v.ipv4Hdr(12) := sAxisMaster.tData(87 downto 80); -- Source IP Address + v.ipv4Hdr(13) := sAxisMaster.tData(95 downto 88); -- Source IP Address + v.ipv4Hdr(14) := sAxisMaster.tData(103 downto 96); -- Source IP Address + v.ipv4Hdr(15) := sAxisMaster.tData(111 downto 104); -- Source IP Address + v.ipv4Hdr(16) := sAxisMaster.tData(119 downto 112); -- Destination IP Address + v.ipv4Hdr(17) := sAxisMaster.tData(127 downto 120); -- Destination IP Address + -- Fill in the TCP/UDP checksum + v.tData(63 downto 0) := sAxisMaster.tData(127 downto 80) & sAxisMaster.tData(63 downto 56) & x"00"; + v.tKeep(7 downto 0) := (others => '1'); + -- Latch the IPv4 length value v.ipv4Len(0)(15 downto 8) := v.ipv4Hdr(2); v.ipv4Len(0)(7 downto 0) := v.ipv4Hdr(3); @@ -297,46 +266,22 @@ begin -- Fill in the TCP/UDP checksum v.tKeep := sAxisMaster.tKeep(15 downto 0); v.tData := sAxisMaster.tData(127 downto 0); - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Fill in the IPv4 header checksum - v.ipv4Hdr(18) := sAxisMaster.tData(7 downto 0); -- Destination IP Address - v.ipv4Hdr(19) := sAxisMaster.tData(15 downto 8); -- Destination IP Address - -- Check for UDP data with inbound checksum - if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then - -- Mask off inbound UDP checksum - v.tData := sAxisMaster.tData(127 downto 80) & x"0000" & sAxisMaster.tData(63 downto 0); - -- Latch the inbound UDP checksum - v.protCsum(0)(15 downto 8) := sAxisMaster.tData(71 downto 64); - v.protCsum(0)(7 downto 0) := sAxisMaster.tData(79 downto 72); - -- Latch the inbound UDP length - v.protLen(0)(15 downto 8) := sAxisMaster.tData(55 downto 48); - v.protLen(0)(7 downto 0) := sAxisMaster.tData(63 downto 56); - end if; - -- Track the number of bytes (include IPv4 header offset from previous state) - v.byteCnt := getTKeep(sAxisMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) + 18; - else - -- Fill in the IPv4 header checksum - v.ipv4Hdr(14) := sAxisMaster.tData(7 downto 0); -- Source IP Address - v.ipv4Hdr(15) := sAxisMaster.tData(15 downto 8); -- Source IP Address - v.ipv4Hdr(16) := sAxisMaster.tData(23 downto 16); -- Destination IP Address - v.ipv4Hdr(17) := sAxisMaster.tData(31 downto 24); -- Destination IP Address - v.ipv4Hdr(18) := sAxisMaster.tData(39 downto 32); -- Destination IP Address - v.ipv4Hdr(19) := sAxisMaster.tData(47 downto 40); -- Destination IP Address - -- Check for UDP data with inbound checksum - if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then - -- Mask off inbound UDP checksum - v.tData := sAxisMaster.tData(127 downto 112) & x"0000" & sAxisMaster.tData(95 downto 0); - -- Latch the inbound UDP checksum - v.protCsum(0)(15 downto 8) := sAxisMaster.tData(103 downto 96); - v.protCsum(0)(7 downto 0) := sAxisMaster.tData(111 downto 104); - -- Latch the inbound UDP length - v.protLen(0)(15 downto 8) := sAxisMaster.tData(87 downto 80); - v.protLen(0)(7 downto 0) := sAxisMaster.tData(95 downto 88); - end if; - -- Track the number of bytes (include IPv4 header offset from previous state) - v.byteCnt := getTKeep(sAxisMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) + 14; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(18) := sAxisMaster.tData(7 downto 0); -- Destination IP Address + v.ipv4Hdr(19) := sAxisMaster.tData(15 downto 8); -- Destination IP Address + -- Check for UDP data with inbound checksum + if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then + -- Mask off inbound UDP checksum + v.tData := sAxisMaster.tData(127 downto 80) & x"0000" & sAxisMaster.tData(63 downto 0); + -- Latch the inbound UDP checksum + v.protCsum(0)(15 downto 8) := sAxisMaster.tData(71 downto 64); + v.protCsum(0)(7 downto 0) := sAxisMaster.tData(79 downto 72); + -- Latch the inbound UDP length + v.protLen(0)(15 downto 8) := sAxisMaster.tData(55 downto 48); + v.protLen(0)(7 downto 0) := sAxisMaster.tData(63 downto 56); end if; + -- Track the number of bytes (include IPv4 header offset from previous state) + v.byteCnt := getTKeep(sAxisMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) + 18; -- Check for EOF if (sAxisMaster.tLast = '1') then -- Next state @@ -358,23 +303,14 @@ begin -- Check for TCP data with inbound checksum if (r.ipv4Det(0) = '1') and (r.tcpDet(0) = '1') and (r.tcpFlag = '0') then -- Set the flag - v.tcpFlag := '1'; + v.tcpFlag := '1'; -- Calculate TCP length from IPv4 length - v.protLen(0) := r.ipv4Len(0) - 20; - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Mask off inbound TCP checksum - v.tData := sAxisMaster.tData(127 downto 32) & x"0000" & sAxisMaster.tData(15 downto 0); - -- Latch the inbound TCP checksum - v.protCsum(0)(15 downto 8) := sAxisMaster.tData(23 downto 16); - v.protCsum(0)(7 downto 0) := sAxisMaster.tData(31 downto 24); - else - -- Mask off inbound TCP checksum - v.tData := sAxisMaster.tData(127 downto 64) & x"0000" & sAxisMaster.tData(47 downto 0); - -- Latch the inbound TCP checksum - v.protCsum(0)(15 downto 8) := sAxisMaster.tData(55 downto 48); - v.protCsum(0)(7 downto 0) := sAxisMaster.tData(63 downto 56); - end if; + v.protLen(0) := r.ipv4Len(0) - 20; + -- Mask off inbound TCP checksum + v.tData := sAxisMaster.tData(127 downto 32) & x"0000" & sAxisMaster.tData(15 downto 0); + -- Latch the inbound TCP checksum + v.protCsum(0)(15 downto 8) := sAxisMaster.tData(23 downto 16); + v.protCsum(0)(7 downto 0) := sAxisMaster.tData(31 downto 24); end if; -- Track the number of bytes v.byteCnt := r.byteCnt + getTKeep(sAxisMaster.tKeep, INT_EMAC_AXIS_CONFIG_C); @@ -390,7 +326,7 @@ begin v.state := BLOWOFF_S; else -- Next state - v.state := IDLE_S; + v.state := IDLE_S; -- Flush the AXIS pipeline v.pipeFlush := '1'; end if; diff --git a/ethernet/EthMacCore/rtl/EthMacRxFifo.vhd b/ethernet/EthMacCore/rtl/EthMacRxFifo.vhd index 2137135184..5fae072ff2 100644 --- a/ethernet/EthMacCore/rtl/EthMacRxFifo.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRxFifo.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -36,40 +35,29 @@ entity EthMacRxFifo is PRIM_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C; BYP_EN_G : boolean := false; BYP_COMMON_CLK_G : boolean := false; - BYP_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C; - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive := 1; - VLAN_COMMON_CLK_G : boolean := false; - VLAN_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C); + BYP_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C); port ( -- Clock and Reset - sClk : in sl; - sRst : in sl; + sClk : in sl; + sRst : in sl; -- Status/Config (sClk domain) - phyReady : in sl; - rxFifoDrop : out sl; - pauseThresh : in slv(15 downto 0); + phyReady : in sl; + rxFifoDrop : out sl; + pauseThresh : in slv(15 downto 0); -- Primary Interface - mPrimClk : in sl; - mPrimRst : in sl; - sPrimMaster : in AxiStreamMasterType; - sPrimCtrl : out AxiStreamCtrlType; - mPrimMaster : out AxiStreamMasterType; - mPrimSlave : in AxiStreamSlaveType; + mPrimClk : in sl; + mPrimRst : in sl; + sPrimMaster : in AxiStreamMasterType; + sPrimCtrl : out AxiStreamCtrlType; + mPrimMaster : out AxiStreamMasterType; + mPrimSlave : in AxiStreamSlaveType; -- Bypass interface - mBypClk : in sl; - mBypRst : in sl; - sBypMaster : in AxiStreamMasterType; - sBypCtrl : out AxiStreamCtrlType; - mBypMaster : out AxiStreamMasterType; - mBypSlave : in AxiStreamSlaveType; - -- VLAN Interfaces - mVlanClk : in sl; - mVlanRst : in sl; - sVlanMasters : in AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - sVlanCtrl : out AxiStreamCtrlArray(VLAN_SIZE_G-1 downto 0); - mVlanMasters : out AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - mVlanSlaves : in AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0)); + mBypClk : in sl; + mBypRst : in sl; + sBypMaster : in AxiStreamMasterType; + sBypCtrl : out AxiStreamCtrlType; + mBypMaster : out AxiStreamMasterType; + mBypSlave : in AxiStreamSlaveType); end EthMacRxFifo; architecture rtl of EthMacRxFifo is @@ -89,9 +77,8 @@ architecture rtl of EthMacRxFifo is signal r : RegType := REG_INIT_C; signal rin : RegType; - signal primDrop : sl := '0'; - signal bypDrop : sl := '0'; - signal vlanDrops : slv(VLAN_SIZE_G-1 downto 0) := (others => '0'); + signal primDrop : sl := '0'; + signal bypDrop : sl := '0'; -- attribute dont_touch : string; -- attribute dont_touch of r : signal is "TRUE"; @@ -163,46 +150,7 @@ begin mAxisSlave => mBypSlave); end generate; - VLAN_DISABLED : if (VLAN_EN_G = false) generate - sVlanCtrl <= (others => AXI_STREAM_CTRL_UNUSED_C); - mVlanMasters <= (others => AXI_STREAM_MASTER_INIT_C); - end generate; - - VLAN_ENABLED : if (VLAN_EN_G = true) generate - GEN_VEC : for i in (VLAN_SIZE_G-1) downto 0 generate - U_Fifo : entity surf.SsiFifo - generic map ( - -- General Configurations - TPD_G => TPD_G, - INT_PIPE_STAGES_G => INT_PIPE_STAGES_G, - PIPE_STAGES_G => PIPE_STAGES_G, - SLAVE_READY_EN_G => false, - VALID_THOLD_G => VALID_THOLD_C, - -- FIFO configurations - SYNTH_MODE_G => SYNTH_MODE_G, - MEMORY_TYPE_G => MEMORY_TYPE_G, - GEN_SYNC_FIFO_G => PRIM_COMMON_CLK_G, - FIFO_ADDR_WIDTH_G => FIFO_ADDR_WIDTH_G, - FIFO_FIXED_THRESH_G => false, - -- AXI Stream Port Configurations - SLAVE_AXI_CONFIG_G => INT_EMAC_AXIS_CONFIG_C, - MASTER_AXI_CONFIG_G => VLAN_CONFIG_G) - port map ( - sAxisClk => sClk, - sAxisRst => sRst, - sAxisMaster => sVlanMasters(i), - sAxisCtrl => sVlanCtrl(i), - sAxisDropFrame => vlanDrops(i), - fifoPauseThresh => r.fifoPauseThresh, - mAxisClk => mVlanClk, - mAxisRst => mVlanRst, - mAxisMaster => mVlanMasters(i), - mAxisSlave => mVlanSlaves(i)); - end generate GEN_VEC; - end generate; - - comb : process (bypDrop, pauseThresh, phyReady, primDrop, r, sRst, - vlanDrops) is + comb : process (bypDrop, pauseThresh, phyReady, primDrop, r, sRst) is variable v : RegType; variable drop : sl; begin @@ -210,7 +158,7 @@ begin v := r; -- OR-ing drop flags together - v.rxFifoDrop := primDrop or bypDrop or uOr(vlanDrops); + v.rxFifoDrop := primDrop or bypDrop; -- Check the programmable threshold if pauseThresh >= (2**FIFO_ADDR_WIDTH_G)-1 then diff --git a/ethernet/EthMacCore/rtl/EthMacRxPause.vhd b/ethernet/EthMacCore/rtl/EthMacRxPause.vhd index 640dec6920..7262e1965c 100644 --- a/ethernet/EthMacCore/rtl/EthMacRxPause.vhd +++ b/ethernet/EthMacCore/rtl/EthMacRxPause.vhd @@ -19,7 +19,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.AxiStreamPkg.all; use surf.StdRtlPkg.all; @@ -27,11 +26,8 @@ use surf.EthMacPkg.all; entity EthMacRxPause is generic ( - TPD_G : time := 1 ns; - PAUSE_EN_G : boolean := true; - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1; - VLAN_VID_G : Slv12Array := (0 => x"001")); + TPD_G : time := 1 ns; + PAUSE_EN_G : boolean := true); port ( -- Clock and Reset ethClk : in sl; @@ -40,7 +36,6 @@ entity EthMacRxPause is sAxisMaster : in AxiStreamMasterType; -- Outgoing data mAxisMaster : out AxiStreamMasterType; - mAxisMasters : out AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); -- Pause Values rxPauseReq : out sl; rxPauseValue : out slv(15 downto 0)); @@ -52,25 +47,20 @@ architecture rtl of EthMacRxPause is IDLE_S, PAUSE_S, DUMP_S, - PASS_S, - VLAN_S); + PASS_S); type RegType is record - idx : natural range 0 to VLAN_SIZE_G-1; - pauseEn : sl; - pauseValue : slv(15 downto 0); - mAxisMaster : AxiStreamMasterType; - mAxisMasters : AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - state : StateType; + pauseEn : sl; + pauseValue : slv(15 downto 0); + mAxisMaster : AxiStreamMasterType; + state : StateType; end record RegType; constant REG_INIT_C : RegType := ( - idx => 0, - pauseEn => '0', - pauseValue => (others => '0'), - mAxisMaster => AXI_STREAM_MASTER_INIT_C, - mAxisMasters => (others => AXI_STREAM_MASTER_INIT_C), - state => IDLE_S); + pauseEn => '0', + pauseValue => (others => '0'), + mAxisMaster => AXI_STREAM_MASTER_INIT_C, + state => IDLE_S); signal r : RegType := REG_INIT_C; signal rin : RegType; @@ -80,13 +70,11 @@ architecture rtl of EthMacRxPause is begin - U_RxPauseGen : if ((PAUSE_EN_G = true) or (VLAN_EN_G = true)) generate + U_RxPauseGen : if (PAUSE_EN_G = true) generate comb : process (ethRst, r, sAxisMaster) is - variable v : RegType; - variable i : natural; - variable vidDet : boolean; - variable vid : slv(11 downto 0); + variable v : RegType; + variable i : natural; begin -- Latch the current value v := r; @@ -94,14 +82,6 @@ begin -- Reset flags v.pauseEn := '0'; v.mAxisMaster.tValid := '0'; - for i in (VLAN_SIZE_G-1) downto 0 loop - v.mAxisMasters(i).tValid := '0'; - end loop; - - -- Update the variable - vidDet := false; - vid(11 downto 8) := sAxisMaster.tData(115 downto 112); - vid(7 downto 0) := sAxisMaster.tData(127 downto 120); -- State Machine case r.state is @@ -110,56 +90,28 @@ begin -- Check for data if (sAxisMaster.tValid = '1') then -- Check for pause frame - if (PAUSE_EN_G = true) and - (sAxisMaster.tData(47 downto 0) = x"01_00_00_C2_80_01") and -- DST MAC (Pause MAC Address) - (sAxisMaster.tData(127 downto 96) = x"01_00_08_88") then -- Mac Type, Mac OpCode + if (sAxisMaster.tData(47 downto 0) = x"01_00_00_C2_80_01") and -- DST MAC (Pause MAC Address) + (sAxisMaster.tData(127 downto 96) = x"01_00_08_88") then -- Mac Type, Mac OpCode -- Check for no EOF if (sAxisMaster.tLast = '0') then -- Next State v.state := PAUSE_S; end if; else - if (VLAN_EN_G = false) then - -- Move the data - v.mAxisMaster := sAxisMaster; - -- Check for no EOF - if (sAxisMaster.tLast = '0') then - -- Next State - v.state := PASS_S; - end if; - else - -- Check for VLAN - if (sAxisMaster.tData(111 downto 96) = VLAN_TYPE_C) then - for i in (VLAN_SIZE_G-1) downto 0 loop - if (vidDet = false) and (vid = VLAN_VID_G(i)) then - vidDet := true; - v.idx := i; - -- Move the data - v.mAxisMasters(i) := sAxisMaster; - -- Check for no EOF - if (sAxisMaster.tLast = '0') then - -- Next State - v.state := VLAN_S; - end if; - end if; - end loop; - else - -- Move the data - v.mAxisMaster := sAxisMaster; - -- Check for no EOF - if (sAxisMaster.tLast = '0') then - -- Next State - v.state := PASS_S; - end if; - end if; + -- Move the data + v.mAxisMaster := sAxisMaster; + -- Check for no EOF + if (sAxisMaster.tLast = '0') then + -- Next State + v.state := PASS_S; end if; end if; end if; ---------------------------------------------------------------------- when PAUSE_S => - -------------------------------------------------------------------------------------------------------------------- - -- Refer to https://hasanmansur1.files.wordpress.com/2012/12/ethernet-flow-control-pause-frame-framing-structure.png - -------------------------------------------------------------------------------------------------------------------- + -------------------------------------------------------------------------------------------------------------------- + -- Refer to https://hasanmansur1.files.wordpress.com/2012/12/ethernet-flow-control-pause-frame-framing-structure.png + -------------------------------------------------------------------------------------------------------------------- -- Check for data if (sAxisMaster.tValid = '1') then -- Latch the pause data @@ -194,15 +146,6 @@ begin -- Next State v.state := IDLE_S; end if; - ---------------------------------------------------------------------- - when VLAN_S => - -- Move the data - v.mAxisMasters(r.idx) := sAxisMaster; - -- Check for a valid EOF - if (sAxisMaster.tValid = '1') and (sAxisMaster.tLast = '1') then - -- Next State - v.state := IDLE_S; - end if; ---------------------------------------------------------------------- end case; @@ -216,7 +159,6 @@ begin -- Outputs mAxisMaster <= r.mAxisMaster; - mAxisMasters <= r.mAxisMasters; rxPauseReq <= r.pauseEn; rxPauseValue <= r.pauseValue; @@ -231,9 +173,8 @@ begin end generate; - U_BypRxPause : if ((PAUSE_EN_G = false) and (VLAN_EN_G = false)) generate + U_BypRxPause : if (PAUSE_EN_G = false) generate mAxisMaster <= sAxisMaster; - mAxisMasters <= (others => AXI_STREAM_MASTER_INIT_C); rxPauseReq <= '0'; rxPauseValue <= (others => '0'); end generate; diff --git a/ethernet/EthMacCore/rtl/EthMacTop.vhd b/ethernet/EthMacCore/rtl/EthMacTop.vhd index ea86bfd9c2..3a87fc95c6 100644 --- a/ethernet/EthMacCore/rtl/EthMacTop.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTop.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.AxiStreamPkg.all; use surf.StdRtlPkg.all; @@ -39,67 +38,54 @@ entity EthMacTop is FIFO_ADDR_WIDTH_G : positive := 11; SYNTH_MODE_G : string := "inferred"; MEMORY_TYPE_G : string := "block"; - -- Non-VLAN Configurations + -- Misc. Configurations FILT_EN_G : boolean := false; PRIM_COMMON_CLK_G : boolean := false; PRIM_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C; BYP_EN_G : boolean := false; BYP_ETH_TYPE_G : slv(15 downto 0) := x"0000"; BYP_COMMON_CLK_G : boolean := false; - BYP_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C; - -- VLAN Configurations - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1; - VLAN_VID_G : Slv12Array := (0 => x"001"); - VLAN_COMMON_CLK_G : boolean := false; - VLAN_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); + BYP_CONFIG_G : AxiStreamConfigType := EMAC_AXIS_CONFIG_C); port ( -- Core Clock and Reset - ethClkEn : in sl := '1'; - ethClk : in sl; - ethRst : in sl; + ethClkEn : in sl := '1'; + ethClk : in sl; + ethRst : in sl; -- Primary Interface - primClk : in sl; - primRst : in sl; - ibMacPrimMaster : in AxiStreamMasterType; - ibMacPrimSlave : out AxiStreamSlaveType; - obMacPrimMaster : out AxiStreamMasterType; - obMacPrimSlave : in AxiStreamSlaveType; + primClk : in sl; + primRst : in sl; + ibMacPrimMaster : in AxiStreamMasterType; + ibMacPrimSlave : out AxiStreamSlaveType; + obMacPrimMaster : out AxiStreamMasterType; + obMacPrimSlave : in AxiStreamSlaveType; -- Bypass interface - bypClk : in sl := '0'; - bypRst : in sl := '0'; - ibMacBypMaster : in AxiStreamMasterType := AXI_STREAM_MASTER_INIT_C; - ibMacBypSlave : out AxiStreamSlaveType; - obMacBypMaster : out AxiStreamMasterType; - obMacBypSlave : in AxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C; - -- VLAN Interfaces - vlanClk : in sl := '0'; - vlanRst : in sl := '0'; - ibMacVlanMasters : in AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0) := (others => AXI_STREAM_MASTER_INIT_C); - ibMacVlanSlaves : out AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); - obMacVlanMasters : out AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - obMacVlanSlaves : in AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0) := (others => AXI_STREAM_SLAVE_FORCE_C); + bypClk : in sl := '0'; + bypRst : in sl := '0'; + ibMacBypMaster : in AxiStreamMasterType := AXI_STREAM_MASTER_INIT_C; + ibMacBypSlave : out AxiStreamSlaveType; + obMacBypMaster : out AxiStreamMasterType; + obMacBypSlave : in AxiStreamSlaveType := AXI_STREAM_SLAVE_FORCE_C; -- XLGMII PHY Interface - xlgmiiRxd : in slv(127 downto 0) := (others => '0'); - xlgmiiRxc : in slv(15 downto 0) := (others => '0'); - xlgmiiTxd : out slv(127 downto 0); - xlgmiiTxc : out slv(15 downto 0); + xlgmiiRxd : in slv(127 downto 0) := (others => '0'); + xlgmiiRxc : in slv(15 downto 0) := (others => '0'); + xlgmiiTxd : out slv(127 downto 0); + xlgmiiTxc : out slv(15 downto 0); -- XGMII PHY Interface - xgmiiRxd : in slv(63 downto 0) := (others => '0'); - xgmiiRxc : in slv(7 downto 0) := (others => '0'); - xgmiiTxd : out slv(63 downto 0); - xgmiiTxc : out slv(7 downto 0); + xgmiiRxd : in slv(63 downto 0) := (others => '0'); + xgmiiRxc : in slv(7 downto 0) := (others => '0'); + xgmiiTxd : out slv(63 downto 0); + xgmiiTxc : out slv(7 downto 0); -- GMII PHY Interface - gmiiRxDv : in sl := '0'; - gmiiRxEr : in sl := '0'; - gmiiRxd : in slv(7 downto 0) := (others => '0'); - gmiiTxEn : out sl; - gmiiTxEr : out sl; - gmiiTxd : out slv(7 downto 0); + gmiiRxDv : in sl := '0'; + gmiiRxEr : in sl := '0'; + gmiiRxd : in slv(7 downto 0) := (others => '0'); + gmiiTxEn : out sl; + gmiiTxEr : out sl; + gmiiTxd : out slv(7 downto 0); -- Configuration and status - phyReady : in sl; - ethConfig : in EthMacConfigType; - ethStatus : out EthMacStatusType); + phyReady : in sl; + ethConfig : in EthMacConfigType; + ethStatus : out EthMacStatusType); end EthMacTop; architecture mapping of EthMacTop is @@ -114,11 +100,6 @@ architecture mapping of EthMacTop is signal mBypMaster : AxiStreamMasterType; signal mBypCtrl : AxiStreamCtrlType; - signal sVlanMasters : AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - signal sVlanSlaves : AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); - signal mVlanMasters : AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - signal mVlanCtrl : AxiStreamCtrlArray(VLAN_SIZE_G-1 downto 0); - signal rxPauseReq : sl; signal rxPauseValue : slv(15 downto 0); signal flowCtrl : AxiStreamCtrlType; @@ -144,36 +125,25 @@ begin BYP_EN_G => BYP_EN_G, BYP_COMMON_CLK_G => BYP_COMMON_CLK_G, BYP_CONFIG_G => BYP_CONFIG_G, - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G, - VLAN_COMMON_CLK_G => VLAN_COMMON_CLK_G, - VLAN_CONFIG_G => VLAN_CONFIG_G, SYNTH_MODE_G => SYNTH_MODE_G) port map ( -- Master Clock and Reset - mClk => ethClk, - mRst => ethRst, + mClk => ethClk, + mRst => ethRst, -- Primary Interface - sPrimClk => primClk, - sPrimRst => primRst, - sPrimMaster => ibMacPrimMaster, - sPrimSlave => ibMacPrimSlave, - mPrimMaster => sPrimMaster, - mPrimSlave => sPrimSlave, + sPrimClk => primClk, + sPrimRst => primRst, + sPrimMaster => ibMacPrimMaster, + sPrimSlave => ibMacPrimSlave, + mPrimMaster => sPrimMaster, + mPrimSlave => sPrimSlave, -- Bypass interface - sBypClk => bypClk, - sBypRst => bypRst, - sBypMaster => ibMacBypMaster, - sBypSlave => ibMacBypSlave, - mBypMaster => sBypMaster, - mBypSlave => sBypSlave, - -- VLAN Interfaces - sVlanClk => vlanClk, - sVlanRst => vlanRst, - sVlanMasters => ibMacVlanMasters, - sVlanSlaves => ibMacVlanSlaves, - mVlanMasters => sVlanMasters, - mVlanSlaves => sVlanSlaves); + sBypClk => bypClk, + sBypRst => bypRst, + sBypMaster => ibMacBypMaster, + sBypSlave => ibMacBypSlave, + mBypMaster => sBypMaster, + mBypSlave => sBypSlave); ------------ -- TX Module @@ -188,12 +158,8 @@ begin PHY_TYPE_G => PHY_TYPE_G, DROP_ERR_PKT_G => DROP_ERR_PKT_G, JUMBO_G => JUMBO_G, - -- Non-VLAN Configurations + -- Misc. Configurations BYP_EN_G => BYP_EN_G, - -- VLAN Configurations - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G, - VLAN_VID_G => VLAN_VID_G, -- RAM sythesis Mode SYNTH_MODE_G => SYNTH_MODE_G) port map ( @@ -207,9 +173,6 @@ begin -- Bypass interface sBypMaster => sBypMaster, sBypSlave => sBypSlave, - -- VLAN Interfaces - sVlanMasters => sVlanMasters, - sVlanSlaves => sVlanSlaves, -- XLGMII PHY Interface xlgmiiTxd => xlgmiiTxd, xlgmiiTxc => xlgmiiTxc, @@ -237,10 +200,8 @@ begin --------------------- U_FlowCtrl : entity surf.EthMacFlowCtrl generic map ( - TPD_G => TPD_G, - BYP_EN_G => BYP_EN_G, - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G) + TPD_G => TPD_G, + BYP_EN_G => BYP_EN_G) port map ( -- Clock and Reset ethClk => ethClk, @@ -248,7 +209,6 @@ begin -- Inputs primCtrl => mPrimCtrl, bypCtrl => mBypCtrl, - vlanCtrl => mVlanCtrl, -- Output flowCtrl => flowCtrl); @@ -263,14 +223,10 @@ begin PAUSE_EN_G => PAUSE_EN_G, PHY_TYPE_G => PHY_TYPE_G, JUMBO_G => JUMBO_G, - -- Non-VLAN Configurations + -- Misc. Configurations FILT_EN_G => FILT_EN_G, BYP_EN_G => BYP_EN_G, BYP_ETH_TYPE_G => BYP_ETH_TYPE_G, - -- VLAN Configurations - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G, - VLAN_VID_G => VLAN_VID_G, -- RAM Synthesis mode SYNTH_MODE_G => SYNTH_MODE_G) port map ( @@ -284,9 +240,6 @@ begin -- Bypass Interface mBypMaster => mBypMaster, mBypCtrl => mBypCtrl, - -- VLAN Interfaces - mVlanMasters => mVlanMasters, - mVlanCtrl => mVlanCtrl, -- XLGMII PHY Interface xlgmiiRxd => xlgmiiRxd, xlgmiiRxc => xlgmiiRxc, @@ -322,39 +275,28 @@ begin PRIM_CONFIG_G => PRIM_CONFIG_G, BYP_EN_G => BYP_EN_G, BYP_COMMON_CLK_G => BYP_COMMON_CLK_G, - BYP_CONFIG_G => BYP_CONFIG_G, - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G, - VLAN_COMMON_CLK_G => VLAN_COMMON_CLK_G, - VLAN_CONFIG_G => VLAN_CONFIG_G) + BYP_CONFIG_G => BYP_CONFIG_G) port map ( -- Slave Clock and Reset - sClk => ethClk, - sRst => ethRst, + sClk => ethClk, + sRst => ethRst, -- Status/Config (sClk domain) - phyReady => phyReady, - rxFifoDrop => ethStatus.rxFifoDropCnt, - pauseThresh => ethConfig.pauseThresh, + phyReady => phyReady, + rxFifoDrop => ethStatus.rxFifoDropCnt, + pauseThresh => ethConfig.pauseThresh, -- Primary Interface - mPrimClk => primClk, - mPrimRst => primRst, - sPrimMaster => mPrimMaster, - sPrimCtrl => mPrimCtrl, - mPrimMaster => obMacPrimMaster, - mPrimSlave => obMacPrimSlave, + mPrimClk => primClk, + mPrimRst => primRst, + sPrimMaster => mPrimMaster, + sPrimCtrl => mPrimCtrl, + mPrimMaster => obMacPrimMaster, + mPrimSlave => obMacPrimSlave, -- Bypass interface - mBypClk => bypClk, - mBypRst => bypRst, - sBypMaster => mBypMaster, - sBypCtrl => mBypCtrl, - mBypMaster => obMacBypMaster, - mBypSlave => obMacBypSlave, - -- VLAN Interfaces - mVlanClk => vlanClk, - mVlanRst => vlanRst, - sVlanMasters => mVlanMasters, - sVlanCtrl => mVlanCtrl, - mVlanMasters => obMacVlanMasters, - mVlanSlaves => obMacVlanSlaves); + mBypClk => bypClk, + mBypRst => bypRst, + sBypMaster => mBypMaster, + sBypCtrl => mBypCtrl, + mBypMaster => obMacBypMaster, + mBypSlave => obMacBypSlave); end mapping; diff --git a/ethernet/EthMacCore/rtl/EthMacTx.vhd b/ethernet/EthMacCore/rtl/EthMacTx.vhd index 27cd40a8c4..2a916fc320 100644 --- a/ethernet/EthMacCore/rtl/EthMacTx.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTx.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.AxiStreamPkg.all; use surf.StdRtlPkg.all; @@ -33,12 +32,8 @@ entity EthMacTx is PHY_TYPE_G : string := "XGMII"; DROP_ERR_PKT_G : boolean := true; JUMBO_G : boolean := true; - -- Non-VLAN Configurations + -- Misc. Configurations BYP_EN_G : boolean := false; - -- VLAN Configurations - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1; - VLAN_VID_G : Slv12Array := (0 => x"001"); -- RAM Synthesis mode SYNTH_MODE_G : string := "inferred"); port ( @@ -52,9 +47,6 @@ entity EthMacTx is -- Bypass interface sBypMaster : in AxiStreamMasterType; sBypSlave : out AxiStreamSlaveType; - -- VLAN Interfaces - sVlanMasters : in AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - sVlanSlaves : out AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); -- XLGMII PHY Interface xlgmiiTxd : out slv(127 downto 0); xlgmiiTxc : out slv(15 downto 0); @@ -82,12 +74,12 @@ architecture mapping of EthMacTx is signal bypassMaster : AxiStreamMasterType; signal bypassSlave : AxiStreamSlaveType; - signal csumMaster : AxiStreamMasterType; - signal csumSlave : AxiStreamSlaveType; - signal csumMasters : AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - signal csumSlaves : AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); - signal macObMaster : AxiStreamMasterType; - signal macObSlave : AxiStreamSlaveType; + + signal csumMaster : AxiStreamMasterType; + signal csumSlave : AxiStreamSlaveType; + + signal macObMaster : AxiStreamMasterType; + signal macObSlave : AxiStreamSlaveType; begin @@ -112,16 +104,14 @@ begin mAxisMaster => bypassMaster, mAxisSlave => bypassSlave); - ------------------------------ - -- TX Non-VLAN Checksum Module - ------------------------------ + --------------------- + -- TX Checksum Module + --------------------- U_Csum : entity surf.EthMacTxCsum generic map ( TPD_G => TPD_G, DROP_ERR_PKT_G => DROP_ERR_PKT_G, - JUMBO_G => JUMBO_G, - VLAN_G => false, - VID_G => x"001") + JUMBO_G => JUMBO_G) port map ( -- Clock and Reset ethClk => ethClk, @@ -136,41 +126,6 @@ begin mAxisMaster => csumMaster, mAxisSlave => csumSlave); - -------------------------- - -- TX VLAN Checksum Module - -------------------------- - GEN_VLAN : if (VLAN_EN_G = true) generate - GEN_VEC : - for i in (VLAN_SIZE_G-1) downto 0 generate - U_Csum : entity surf.EthMacTxCsum - generic map ( - TPD_G => TPD_G, - DROP_ERR_PKT_G => DROP_ERR_PKT_G, - JUMBO_G => JUMBO_G, - VLAN_G => true, - VID_G => VLAN_VID_G(i)) - port map ( - -- Clock and Reset - ethClk => ethClk, - ethRst => ethRst, - -- Configurations - ipCsumEn => '1', - tcpCsumEn => '1', - udpCsumEn => '1', - -- Outbound data to MAC - sAxisMaster => sVlanMasters(i), - sAxisSlave => sVlanSlaves(i), - mAxisMaster => csumMasters(i), - mAxisSlave => csumSlaves(i)); - end generate GEN_VEC; - end generate; - - BYPASS_VLAN : if (VLAN_EN_G = false) generate - -- Terminate Unused buses - sVlanSlaves <= (others => AXI_STREAM_SLAVE_FORCE_C); - csumMasters <= (others => AXI_STREAM_MASTER_INIT_C); - end generate; - ------------------ -- TX Pause Module ------------------ @@ -178,9 +133,7 @@ begin generic map ( TPD_G => TPD_G, PAUSE_EN_G => PAUSE_EN_G, - PAUSE_512BITS_G => PAUSE_512BITS_G, - VLAN_EN_G => VLAN_EN_G, - VLAN_SIZE_G => VLAN_SIZE_G) + PAUSE_512BITS_G => PAUSE_512BITS_G) port map ( -- Clock and Reset ethClk => ethClk, @@ -188,8 +141,6 @@ begin -- Incoming data from client sAxisMaster => csumMaster, sAxisSlave => csumSlave, - sAxisMasters => csumMasters, - sAxisSlaves => csumSlaves, -- Outgoing data to MAC mAxisMaster => macObMaster, mAxisSlave => macObSlave, diff --git a/ethernet/EthMacCore/rtl/EthMacTxCsum.vhd b/ethernet/EthMacCore/rtl/EthMacTxCsum.vhd index 4ad511ad5b..97a56349d0 100644 --- a/ethernet/EthMacCore/rtl/EthMacTxCsum.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTxCsum.vhd @@ -18,7 +18,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -26,12 +25,10 @@ use surf.EthMacPkg.all; entity EthMacTxCsum is generic ( - TPD_G : time := 1 ns; - DROP_ERR_PKT_G : boolean := true; - JUMBO_G : boolean := true; - VLAN_G : boolean := false; - VID_G : slv(11 downto 0) := x"001"; - SYNTH_MODE_G : string := "inferred"); -- Synthesis mode for internal RAMs + TPD_G : time := 1 ns; + DROP_ERR_PKT_G : boolean := true; + JUMBO_G : boolean := true; + SYNTH_MODE_G : string := "inferred"); -- Synthesis mode for internal RAMs port ( -- Clock and Reset ethClk : in sl; @@ -249,24 +246,16 @@ begin -- Write the transaction data v.tranWr := '1'; else - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Check for EtherType = IPV4 = 0x0800 - if (rxMaster.tData(111 downto 96) = IPV4_TYPE_C) then - -- Set the flag - v.ipv4Det(0) := '1'; - end if; - -- Fill in the IPv4 header checksum - v.ipv4Hdr(0) := rxMaster.tData(119 downto 112); -- IPVersion + Header length - v.ipv4Hdr(1) := rxMaster.tData(127 downto 120); -- DSCP and ECN - else - -- Add the IEEE 802.1Q header - v.sMaster.tData(111 downto 96) := VLAN_TYPE_C; - v.sMaster.tData(119 downto 112) := x"0" & VID_G(11 downto 8); - v.sMaster.tData(127 downto 120) := VID_G(7 downto 0); + -- Check for EtherType = IPV4 = 0x0800 + if (rxMaster.tData(111 downto 96) = IPV4_TYPE_C) then + -- Set the flag + v.ipv4Det(0) := '1'; end if; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(0) := rxMaster.tData(119 downto 112); -- IPVersion + Header length + v.ipv4Hdr(1) := rxMaster.tData(127 downto 120); -- DSCP and ECN -- Next state - v.state := IPV4_HDR0_S; + v.state := IPV4_HDR0_S; end if; end if; ---------------------------------------------------------------------- @@ -292,45 +281,22 @@ begin -- Next state v.state := IDLE_S; else - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Fill in the IPv4 header checksum - v.ipv4Hdr(4) := rxMaster.tData(23 downto 16); -- IPV4_ID(15 downto 8) - v.ipv4Hdr(5) := rxMaster.tData(31 downto 24); -- IPV4_ID(7 downto 0) - v.ipv4Hdr(6) := rxMaster.tData(39 downto 32); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) - v.ipv4Hdr(7) := rxMaster.tData(47 downto 40); -- Fragment Offsets(7 downto 0) - v.ipv4Hdr(8) := rxMaster.tData(55 downto 48); -- Time-To-Live - v.ipv4Hdr(9) := rxMaster.tData(63 downto 56); -- Protocol - v.ipv4Hdr(12) := rxMaster.tData(87 downto 80); -- Source IP Address - v.ipv4Hdr(13) := rxMaster.tData(95 downto 88); -- Source IP Address - v.ipv4Hdr(14) := rxMaster.tData(103 downto 96); -- Source IP Address - v.ipv4Hdr(15) := rxMaster.tData(111 downto 104); -- Source IP Address - v.ipv4Hdr(16) := rxMaster.tData(119 downto 112); -- Destination IP Address - v.ipv4Hdr(17) := rxMaster.tData(127 downto 120); -- Destination IP Address - -- Fill in the TCP/UDP checksum - v.tData(63 downto 0) := rxMaster.tData(127 downto 80) & rxMaster.tData(63 downto 56) & x"00"; - v.tKeep(7 downto 0) := (others => '1'); - else - -- Check for EtherType = IPV4 = 0x0800 - if (rxMaster.tData(15 downto 0) = IPV4_TYPE_C) then - -- Set the flag - v.ipv4Det(0) := '1'; - end if; - -- Fill in the IPv4 header checksum - v.ipv4Hdr(0) := rxMaster.tData(23 downto 16); -- IPVersion + Header length - v.ipv4Hdr(1) := rxMaster.tData(31 downto 24); -- DSCP and ECN - v.ipv4Hdr(4) := rxMaster.tData(55 downto 48); -- IPV4_ID(15 downto 8) - v.ipv4Hdr(5) := rxMaster.tData(63 downto 56); -- IPV4_ID(7 downto 0) - v.ipv4Hdr(6) := rxMaster.tData(71 downto 64); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) - v.ipv4Hdr(7) := rxMaster.tData(79 downto 72); -- Fragment Offsets(7 downto 0) - v.ipv4Hdr(8) := rxMaster.tData(87 downto 80); -- Time-To-Live - v.ipv4Hdr(9) := rxMaster.tData(95 downto 88); -- Protocol - v.ipv4Hdr(12) := rxMaster.tData(119 downto 112); -- Source IP Address - v.ipv4Hdr(13) := rxMaster.tData(127 downto 120); -- Source IP Address - -- Fill in the TCP/UDP checksum - v.tData(31 downto 0) := rxMaster.tData(127 downto 112) & rxMaster.tData(95 downto 88) & x"00"; - v.tKeep(3 downto 0) := (others => '1'); - end if; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(4) := rxMaster.tData(23 downto 16); -- IPV4_ID(15 downto 8) + v.ipv4Hdr(5) := rxMaster.tData(31 downto 24); -- IPV4_ID(7 downto 0) + v.ipv4Hdr(6) := rxMaster.tData(39 downto 32); -- Flags(2 downto 0) and Fragment Offsets(12 downto 8) + v.ipv4Hdr(7) := rxMaster.tData(47 downto 40); -- Fragment Offsets(7 downto 0) + v.ipv4Hdr(8) := rxMaster.tData(55 downto 48); -- Time-To-Live + v.ipv4Hdr(9) := rxMaster.tData(63 downto 56); -- Protocol + v.ipv4Hdr(12) := rxMaster.tData(87 downto 80); -- Source IP Address + v.ipv4Hdr(13) := rxMaster.tData(95 downto 88); -- Source IP Address + v.ipv4Hdr(14) := rxMaster.tData(103 downto 96); -- Source IP Address + v.ipv4Hdr(15) := rxMaster.tData(111 downto 104); -- Source IP Address + v.ipv4Hdr(16) := rxMaster.tData(119 downto 112); -- Destination IP Address + v.ipv4Hdr(17) := rxMaster.tData(127 downto 120); -- Destination IP Address + -- Fill in the TCP/UDP checksum + v.tData(63 downto 0) := rxMaster.tData(127 downto 80) & rxMaster.tData(63 downto 56) & x"00"; + v.tKeep(7 downto 0) := (others => '1'); -- Check for UDP protocol if (v.ipv4Hdr(9) = UDP_C) then v.udpDet(0) := '1'; @@ -354,36 +320,17 @@ begin -- Fill in the TCP/UDP checksum v.tKeep := rxMaster.tKeep(15 downto 0); v.tData := rxMaster.tData(127 downto 0); - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Fill in the IPv4 header checksum - v.ipv4Hdr(18) := rxMaster.tData(7 downto 0); -- Destination IP Address - v.ipv4Hdr(19) := rxMaster.tData(15 downto 8); -- Destination IP Address - -- Check for UDP data with inbound length/checksum - if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then - -- Mask off inbound UDP length/checksum - v.tData := rxMaster.tData(127 downto 80) & x"00000000" & rxMaster.tData(47 downto 0); - end if; - -- Track the number of bytes - v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 2; - v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 2; - else - -- Fill in the IPv4 header checksum - v.ipv4Hdr(14) := rxMaster.tData(7 downto 0); -- Source IP Address - v.ipv4Hdr(15) := rxMaster.tData(15 downto 8); -- Source IP Address - v.ipv4Hdr(16) := rxMaster.tData(23 downto 16); -- Destination IP Address - v.ipv4Hdr(17) := rxMaster.tData(31 downto 24); -- Destination IP Address - v.ipv4Hdr(18) := rxMaster.tData(39 downto 32); -- Destination IP Address - v.ipv4Hdr(19) := rxMaster.tData(47 downto 40); -- Destination IP Address - -- Check for UDP data with inbound length/checksum - if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then - -- Mask off inbound UDP length/checksum - v.tData := rxMaster.tData(127 downto 112) & x"00000000" & rxMaster.tData(79 downto 0); - end if; - -- Track the number of bytes - v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 6; - v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 6; + -- Fill in the IPv4 header checksum + v.ipv4Hdr(18) := rxMaster.tData(7 downto 0); -- Destination IP Address + v.ipv4Hdr(19) := rxMaster.tData(15 downto 8); -- Destination IP Address + -- Check for UDP data with inbound length/checksum + if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then + -- Mask off inbound UDP length/checksum + v.tData := rxMaster.tData(127 downto 80) & x"00000000" & rxMaster.tData(47 downto 0); end if; + -- Track the number of bytes + v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 2; + v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C) - 2; -- Check for EOF if (rxMaster.tLast = '1') then -- Save the EOFE value @@ -412,14 +359,8 @@ begin if (r.ipv4Det(0) = '1') and (r.tcpDet(0) = '1') and (r.tcpFlag = '0') then -- Set the flag v.tcpFlag := '1'; - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Mask off inbound TCP checksum - v.tData := rxMaster.tData(127 downto 32) & x"0000" & rxMaster.tData(15 downto 0); - else - -- Mask off inbound TCP checksum - v.tData := rxMaster.tData(127 downto 64) & x"0000" & rxMaster.tData(47 downto 0); - end if; + -- Mask off inbound TCP checksum + v.tData := rxMaster.tData(127 downto 32) & x"0000" & rxMaster.tData(15 downto 0); end if; -- Track the number of bytes v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep, INT_EMAC_AXIS_CONFIG_C); @@ -483,117 +424,58 @@ begin end if; -- Check for IPv4 checksum/length insertion if (ipv4Det = '1') and (r.mvCnt = 1) then - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Check if firmware checksum enabled - if (ipCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(7 downto 0) := ipv4Len(15 downto 8); - v.txMaster.tData(15 downto 8) := ipv4Len(7 downto 0); - v.txMaster.tData(71 downto 64) := ipv4Csum(15 downto 8); - v.txMaster.tData(79 downto 72) := ipv4Csum(7 downto 0); - end if; - -- Check for mismatch between firmware/software IPv4 length - if (ipv4Len(15 downto 8) /= mMaster.tData(7 downto 0)) or (ipv4Len(7 downto 0) /= mMaster.tData(15 downto 8)) then - -- Set the flag - v.dbg(0) := '1'; - end if; - -- Check for mismatch between firmware/software IPv4 checksum - if (ipv4Csum(15 downto 8) /= mMaster.tData(71 downto 64)) or (ipv4Csum(7 downto 0) /= mMaster.tData(79 downto 72)) then - -- Set the flag - v.dbg(1) := '1'; - end if; - else - -- Check if firmware checksum enabled - if (ipCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(39 downto 32) := ipv4Len(15 downto 8); - v.txMaster.tData(47 downto 40) := ipv4Len(7 downto 0); - v.txMaster.tData(103 downto 96) := ipv4Csum(15 downto 8); - v.txMaster.tData(111 downto 104) := ipv4Csum(7 downto 0); - end if; - -- Check for mismatch between firmware/software IPv4 length - if (ipv4Len(15 downto 8) /= mMaster.tData(39 downto 32)) or (ipv4Len(7 downto 0) /= mMaster.tData(47 downto 40)) then - -- Set the flag - v.dbg(0) := '1'; - end if; - -- Check for mismatch between firmware/software IPv4 checksum - if (ipv4Csum(15 downto 8) /= mMaster.tData(103 downto 96)) or (ipv4Csum(7 downto 0) /= mMaster.tData(111 downto 104)) then - -- Set the flag - v.dbg(1) := '1'; - end if; + -- Check if firmware checksum enabled + if (ipCsumEn = '1') then + -- Overwrite the data field + v.txMaster.tData(7 downto 0) := ipv4Len(15 downto 8); + v.txMaster.tData(15 downto 8) := ipv4Len(7 downto 0); + v.txMaster.tData(71 downto 64) := ipv4Csum(15 downto 8); + v.txMaster.tData(79 downto 72) := ipv4Csum(7 downto 0); + end if; + -- Check for mismatch between firmware/software IPv4 length + if (ipv4Len(15 downto 8) /= mMaster.tData(7 downto 0)) or (ipv4Len(7 downto 0) /= mMaster.tData(15 downto 8)) then + -- Set the flag + v.dbg(0) := '1'; + end if; + -- Check for mismatch between firmware/software IPv4 checksum + if (ipv4Csum(15 downto 8) /= mMaster.tData(71 downto 64)) or (ipv4Csum(7 downto 0) /= mMaster.tData(79 downto 72)) then + -- Set the flag + v.dbg(1) := '1'; end if; end if; -- Check for UDP checksum/length insertion and no fragmentation if (ipv4Det = '1') and (udpDet = '1') and (fragDet = '0') and (r.mvCnt = 2) then - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Check if firmware checksum enabled - if (udpCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(55 downto 48) := protLen(15 downto 8); - v.txMaster.tData(63 downto 56) := protLen(7 downto 0); - v.txMaster.tData(71 downto 64) := protCsum(15 downto 8); - v.txMaster.tData(79 downto 72) := protCsum(7 downto 0); - end if; - -- Check for mismatch between firmware/software UDP length - if (protLen(15 downto 8) /= mMaster.tData(55 downto 48)) or (protLen(7 downto 0) /= mMaster.tData(63 downto 56)) then - -- Set the flag - v.dbg(2) := '1'; - end if; - -- Check for mismatch between firmware/software UDP checksum - if (protCsum(15 downto 8) /= mMaster.tData(71 downto 64)) or (protCsum(7 downto 0) /= mMaster.tData(79 downto 72)) then - -- Set the flag - v.dbg(3) := '1'; - end if; - else - -- Check if firmware checksum enabled - if (udpCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(87 downto 80) := protLen(15 downto 8); - v.txMaster.tData(95 downto 88) := protLen(7 downto 0); - v.txMaster.tData(103 downto 96) := protCsum(15 downto 8); - v.txMaster.tData(111 downto 104) := protCsum(7 downto 0); - end if; - -- Check for mismatch between firmware/software UDP length - if (protLen(15 downto 8) /= mMaster.tData(87 downto 80)) or (protLen(7 downto 0) /= mMaster.tData(95 downto 88)) then - -- Set the flag - v.dbg(2) := '1'; - end if; - -- Check for mismatch between firmware/software UDP checksum - if (protCsum(15 downto 8) /= mMaster.tData(103 downto 96)) or (protCsum(7 downto 0) /= mMaster.tData(111 downto 104)) then - -- Set the flag - v.dbg(3) := '1'; - end if; + -- Check if firmware checksum enabled + if (udpCsumEn = '1') then + -- Overwrite the data field + v.txMaster.tData(55 downto 48) := protLen(15 downto 8); + v.txMaster.tData(63 downto 56) := protLen(7 downto 0); + v.txMaster.tData(71 downto 64) := protCsum(15 downto 8); + v.txMaster.tData(79 downto 72) := protCsum(7 downto 0); + end if; + -- Check for mismatch between firmware/software UDP length + if (protLen(15 downto 8) /= mMaster.tData(55 downto 48)) or (protLen(7 downto 0) /= mMaster.tData(63 downto 56)) then + -- Set the flag + v.dbg(2) := '1'; + end if; + -- Check for mismatch between firmware/software UDP checksum + if (protCsum(15 downto 8) /= mMaster.tData(71 downto 64)) or (protCsum(7 downto 0) /= mMaster.tData(79 downto 72)) then + -- Set the flag + v.dbg(3) := '1'; end if; end if; -- Check for TCP checksum insertion and no fragmentation if (ipv4Det = '1') and (tcpDet = '1') and (fragDet = '0') and (r.mvCnt = 3) then - -- Check if NON-VLAN - if (VLAN_G = false) then - -- Check if firmware checksum enabled - if (tcpCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(23 downto 16) := protCsum(15 downto 8); - v.txMaster.tData(31 downto 24) := protCsum(7 downto 0); - end if; - -- Check for mismatch between firmware/software TCP checksum - if (protCsum(15 downto 8) /= mMaster.tData(23 downto 16)) or (protCsum(7 downto 0) /= mMaster.tData(31 downto 24)) then - -- Set the flag - v.dbg(4) := '1'; - end if; - else - -- Check if firmware checksum enabled - if (tcpCsumEn = '1') then - -- Overwrite the data field - v.txMaster.tData(55 downto 48) := protCsum(15 downto 8); - v.txMaster.tData(63 downto 56) := protCsum(7 downto 0); - end if; - -- Check for mismatch between firmware/software TCP checksum - if (protCsum(15 downto 8) /= mMaster.tData(55 downto 48)) or (protCsum(7 downto 0) /= mMaster.tData(63 downto 56)) then - -- Set the flag - v.dbg(4) := '1'; - end if; + -- Check if firmware checksum enabled + if (tcpCsumEn = '1') then + -- Overwrite the data field + v.txMaster.tData(23 downto 16) := protCsum(15 downto 8); + v.txMaster.tData(31 downto 24) := protCsum(7 downto 0); + end if; + -- Check for mismatch between firmware/software TCP checksum + if (protCsum(15 downto 8) /= mMaster.tData(23 downto 16)) or (protCsum(7 downto 0) /= mMaster.tData(31 downto 24)) then + -- Set the flag + v.dbg(4) := '1'; end if; end if; -- Check for tLast diff --git a/ethernet/EthMacCore/rtl/EthMacTxFifo.vhd b/ethernet/EthMacCore/rtl/EthMacTxFifo.vhd index d893aab7ae..47cb0f2a7a 100644 --- a/ethernet/EthMacCore/rtl/EthMacTxFifo.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTxFifo.vhd @@ -15,7 +15,6 @@ library ieee; use ieee.std_logic_1164.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -29,36 +28,25 @@ entity EthMacTxFifo is BYP_EN_G : boolean := false; BYP_COMMON_CLK_G : boolean := false; BYP_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C; - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive := 1; - VLAN_COMMON_CLK_G : boolean := false; - VLAN_CONFIG_G : AxiStreamConfigType := INT_EMAC_AXIS_CONFIG_C; SYNTH_MODE_G : string := "inferred"); -- Synthesis mode for internal RAMs port ( -- Master Clock and Reset - mClk : in sl; - mRst : in sl; + mClk : in sl; + mRst : in sl; -- Primary Interface - sPrimClk : in sl; - sPrimRst : in sl; - sPrimMaster : in AxiStreamMasterType; - sPrimSlave : out AxiStreamSlaveType; - mPrimMaster : out AxiStreamMasterType; - mPrimSlave : in AxiStreamSlaveType; + sPrimClk : in sl; + sPrimRst : in sl; + sPrimMaster : in AxiStreamMasterType; + sPrimSlave : out AxiStreamSlaveType; + mPrimMaster : out AxiStreamMasterType; + mPrimSlave : in AxiStreamSlaveType; -- Bypass interface - sBypClk : in sl; - sBypRst : in sl; - sBypMaster : in AxiStreamMasterType; - sBypSlave : out AxiStreamSlaveType; - mBypMaster : out AxiStreamMasterType; - mBypSlave : in AxiStreamSlaveType; - -- VLAN Interfaces - sVlanClk : in sl; - sVlanRst : in sl; - sVlanMasters : in AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - sVlanSlaves : out AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); - mVlanMasters : out AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - mVlanSlaves : in AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0)); + sBypClk : in sl; + sBypRst : in sl; + sBypMaster : in AxiStreamMasterType; + sBypSlave : out AxiStreamSlaveType; + mBypMaster : out AxiStreamMasterType; + mBypSlave : in AxiStreamSlaveType); end EthMacTxFifo; architecture mapping of EthMacTxFifo is @@ -142,47 +130,4 @@ begin end generate; - VLAN_DISABLED : if (VLAN_EN_G = false) generate - sVlanSlaves <= (others => AXI_STREAM_SLAVE_FORCE_C); - mVlanMasters <= (others => AXI_STREAM_MASTER_INIT_C); - end generate; - - VLAN_ENABLED : if (VLAN_EN_G = true) generate - VLAN_FIFO_BYPASS : if ((VLAN_COMMON_CLK_G = true) and (VLAN_CONFIG_G = INT_EMAC_AXIS_CONFIG_C)) generate - mVlanMasters <= sVlanMasters; - sVlanSlaves <= mVlanSlaves; - end generate; - - VLAN_FIFO : if ((VLAN_COMMON_CLK_G = false) or (VLAN_CONFIG_G /= INT_EMAC_AXIS_CONFIG_C)) generate - GEN_VEC : for i in (VLAN_SIZE_G-1) downto 0 generate - U_Fifo : entity surf.AxiStreamFifoV2 - generic map ( - -- General Configurations - TPD_G => TPD_G, - INT_PIPE_STAGES_G => 0, - PIPE_STAGES_G => 1, - SLAVE_READY_EN_G => true, - VALID_THOLD_G => 1, - -- FIFO configurations - SYNTH_MODE_G => SYNTH_MODE_G, - MEMORY_TYPE_G => "distributed", - GEN_SYNC_FIFO_G => VLAN_COMMON_CLK_G, - CASCADE_SIZE_G => 1, - FIFO_ADDR_WIDTH_G => 4, - -- AXI Stream Port Configurations - SLAVE_AXI_CONFIG_G => VLAN_CONFIG_G, - MASTER_AXI_CONFIG_G => INT_EMAC_AXIS_CONFIG_C) - port map ( - sAxisClk => sVlanClk, - sAxisRst => sVlanRst, - sAxisMaster => sVlanMasters(i), - sAxisSlave => sVlanSlaves(i), - mAxisClk => mClk, - mAxisRst => mRst, - mAxisMaster => mVlanMasters(i), - mAxisSlave => mVlanSlaves(i)); - end generate GEN_VEC; - end generate; - end generate; - end mapping; diff --git a/ethernet/EthMacCore/rtl/EthMacTxPause.vhd b/ethernet/EthMacCore/rtl/EthMacTxPause.vhd index 915cd3b1ee..a007c4d1d7 100644 --- a/ethernet/EthMacCore/rtl/EthMacTxPause.vhd +++ b/ethernet/EthMacCore/rtl/EthMacTxPause.vhd @@ -19,7 +19,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; - library surf; use surf.AxiStreamPkg.all; use surf.StdRtlPkg.all; @@ -29,9 +28,7 @@ entity EthMacTxPause is generic ( TPD_G : time := 1 ns; PAUSE_EN_G : boolean := true; - PAUSE_512BITS_G : natural range 1 to 1024 := 8; - VLAN_EN_G : boolean := false; - VLAN_SIZE_G : positive range 1 to 8 := 1); + PAUSE_512BITS_G : natural range 1 to 1024 := 8); port ( -- Clock and Reset ethClk : in sl; @@ -39,8 +36,6 @@ entity EthMacTxPause is -- Incoming data from client sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; - sAxisMasters : in AxiStreamMasterArray(VLAN_SIZE_G-1 downto 0); - sAxisSlaves : out AxiStreamSlaveArray(VLAN_SIZE_G-1 downto 0); -- Outgoing data to MAC mAxisMaster : out AxiStreamMasterType; mAxisSlave : in AxiStreamSlaveType; @@ -60,7 +55,6 @@ end EthMacTxPause; architecture rtl of EthMacTxPause is constant CNT_BITS_C : integer := bitSize(PAUSE_512BITS_G-1); - constant SIZE_C : natural := ite(VLAN_EN_G, (VLAN_SIZE_G+1), 1); type StateType is ( IDLE_S, @@ -75,7 +69,7 @@ architecture rtl of EthMacTxPause is remPreCnt : slv(CNT_BITS_C-1 downto 0); pauseTx : sl; mAxisMaster : AxiStreamMasterType; - rxSlave : AxiStreamSlaveType; + sAxisSlave : AxiStreamSlaveType; state : StateType; end record RegType; @@ -87,71 +81,29 @@ architecture rtl of EthMacTxPause is remPreCnt => (others => '0'), pauseTx => '0', mAxisMaster => AXI_STREAM_MASTER_INIT_C, - rxSlave => AXI_STREAM_SLAVE_INIT_C, + sAxisSlave => AXI_STREAM_SLAVE_INIT_C, state => IDLE_S); signal r : RegType := REG_INIT_C; signal rin : RegType; - signal rxMasters : AxiStreamMasterArray(SIZE_C-1 downto 0); - signal rxSlaves : AxiStreamSlaveArray(SIZE_C-1 downto 0); - - signal rxMaster : AxiStreamMasterType; - signal rxSlave : AxiStreamSlaveType; - -- attribute dont_touch : string; -- attribute dont_touch of r : signal is "true"; begin - rxMasters(0) <= sAxisMaster; - sAxisSlave <= rxSlaves(0); - - U_NoVlanGen : if (VLAN_EN_G = false) generate - - rxMaster <= rxMasters(0); - rxSlaves(0) <= rxSlave; - sAxisSlaves <= (others => AXI_STREAM_SLAVE_FORCE_C); - - end generate; - - U_VlanGen : if (VLAN_EN_G = true) generate - - GEN_VEC : - for i in (VLAN_SIZE_G-1) downto 0 generate - rxMasters(i+1) <= sAxisMasters(i); - sAxisSlaves(i) <= rxSlaves(i+1); - end generate GEN_VEC; - - U_AxiStreamMux : entity surf.AxiStreamMux - generic map ( - TPD_G => TPD_G, - NUM_SLAVES_G => SIZE_C) - port map ( - -- Clock and reset - axisClk => ethClk, - axisRst => ethRst, - -- Slaves - sAxisMasters => rxMasters, - sAxisSlaves => rxSlaves, - -- Master - mAxisMaster => rxMaster, - mAxisSlave => rxSlave); - - end generate; - U_TxPauseGen : if (PAUSE_EN_G = true) generate comb : process (clientPause, ethRst, mAxisSlave, pauseEnable, pauseTime, - phyReady, r, rxMaster, rxPauseReq, rxPauseValue) is + phyReady, r, rxPauseReq, rxPauseValue, sAxisMaster) is variable v : RegType; begin -- Latch the current value v := r; -- Reset the flags - v.pauseTx := '0'; - v.rxSlave := AXI_STREAM_SLAVE_INIT_C; + v.pauseTx := '0'; + v.sAxisSlave := AXI_STREAM_SLAVE_INIT_C; if (mAxisSlave.tReady = '1') then v.mAxisMaster.tValid := '0'; end if; @@ -184,7 +136,7 @@ begin -- Next state v.state := PAUSE_S; -- Transmit required and not paused by received pause count - elsif (rxMaster.tValid = '1') and (r.locPauseCnt = 0) then + elsif (sAxisMaster.tValid = '1') and (r.locPauseCnt = 0) then -- Next state v.state := PASS_S; end if; @@ -240,13 +192,13 @@ begin ---------------------------------------------------------------------- when PASS_S => -- Check if ready to move data - if (v.mAxisMaster.tValid = '0') and (rxMaster.tValid = '1') then + if (v.mAxisMaster.tValid = '0') and (sAxisMaster.tValid = '1') then -- Accept the data - v.rxSlave.tReady := '1'; + v.sAxisSlave.tReady := '1'; -- Move the data - v.mAxisMaster := rxMaster; + v.mAxisMaster := sAxisMaster; -- Check for EOF - if (rxMaster.tLast = '1') then + if (sAxisMaster.tLast = '1') then -- Next state v.state := IDLE_S; end if; @@ -255,7 +207,7 @@ begin end case; -- Combinatorial outputs before the reset - rxSlave <= v.rxSlave; + sAxisSlave <= v.sAxisSlave; -- Reset if (ethRst = '1') then @@ -281,8 +233,8 @@ begin end generate; U_BypTxPause : if (PAUSE_EN_G = false) generate - mAxisMaster <= rxMaster; - rxSlave <= mAxisSlave; + mAxisMaster <= sAxisMaster; + sAxisSlave <= mAxisSlave; pauseTx <= '0'; end generate; From 7395517e522e4dcce39a696cf7981e9ece423e77 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 10 Jul 2024 18:12:36 -0700 Subject: [PATCH 03/43] depreciating VLAN support in ethernet/IpV4Engine because never tested and never used --- ethernet/EthMacCore/rtl/EthMacPkg.vhd | 4 +- ethernet/IpV4Engine/rtl/ArpEngine.vhd | 198 +++++------------ ethernet/IpV4Engine/rtl/IpV4Engine.vhd | 15 +- ethernet/IpV4Engine/rtl/IpV4EngineDeMux.vhd | 133 +++-------- ethernet/IpV4Engine/rtl/IpV4EngineRx.vhd | 172 +++++---------- ethernet/IpV4Engine/rtl/IpV4EngineTx.vhd | 231 ++++++-------------- ethernet/IpV4Engine/tb/IpV4EngineCoreTb.vhd | 20 +- ethernet/IpV4Engine/tb/IpV4EngineTb.vhd | 14 +- ethernet/UdpEngine/rtl/UdpEngineWrapper.vhd | 4 +- 9 files changed, 231 insertions(+), 560 deletions(-) diff --git a/ethernet/EthMacCore/rtl/EthMacPkg.vhd b/ethernet/EthMacCore/rtl/EthMacPkg.vhd index d92ffdfa52..fc95888382 100644 --- a/ethernet/EthMacCore/rtl/EthMacPkg.vhd +++ b/ethernet/EthMacCore/rtl/EthMacPkg.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -30,7 +29,6 @@ package EthMacPkg is -- EtherTypes constant ARP_TYPE_C : slv(15 downto 0) := x"0608"; -- EtherType = ARP = 0x0806 constant IPV4_TYPE_C : slv(15 downto 0) := x"0008"; -- EtherType = IPV4 = 0x0800 - constant VLAN_TYPE_C : slv(15 downto 0) := x"0081"; -- EtherType = VLAN = 0x8100 -- IPV4 Protocol Constants constant UDP_C : slv(7 downto 0) := x"11"; -- Protocol = UDP = 0x11 @@ -68,7 +66,7 @@ package EthMacPkg is -- TDEST_INTERLEAVE_C => EMAC_AXIS_CONFIG_C.TDEST_INTERLEAVE_C, TSTRB_EN_C => EMAC_AXIS_CONFIG_C.TSTRB_EN_C, TDATA_BYTES_C => EMAC_AXIS_CONFIG_C.TDATA_BYTES_C, - TDEST_BITS_C => 0, -- TDEST not used internally of EthMacTop.vhd + TDEST_BITS_C => 0, -- TDEST not used internally of EthMacTop.vhd TID_BITS_C => EMAC_AXIS_CONFIG_C.TID_BITS_C, TKEEP_MODE_C => EMAC_AXIS_CONFIG_C.TKEEP_MODE_C, TUSER_BITS_C => EMAC_AXIS_CONFIG_C.TUSER_BITS_C, diff --git a/ethernet/IpV4Engine/rtl/ArpEngine.vhd b/ethernet/IpV4Engine/rtl/ArpEngine.vhd index d53315ad0c..075f676d22 100644 --- a/ethernet/IpV4Engine/rtl/ArpEngine.vhd +++ b/ethernet/IpV4Engine/rtl/ArpEngine.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -28,8 +27,7 @@ entity ArpEngine is generic ( TPD_G : time := 1 ns; CLIENT_SIZE_G : positive := 1; - CLK_FREQ_G : real := 156.25E+06; -- In units of Hz - VLAN_G : boolean := false); + CLK_FREQ_G : real := 156.25E+06); -- In units of Hz port ( -- Local Configuration localMac : in slv(47 downto 0); @@ -55,8 +53,8 @@ architecture rtl of ArpEngine is constant BROADCAST_MAC_C : slv(47 downto 0) := (others => '1'); constant HARDWWARE_TYPE_C : slv(15 downto 0) := x"0100"; -- HardwareType = ETH = 0x0001 constant PROTOCOL_TYPE_C : slv(15 downto 0) := x"0008"; -- ProtocolType = IP = 0x0800 - constant HARDWWARE_LEN_C : slv(7 downto 0) := x"06"; -- HardwareLength = 6 (6 Bytes/MAC) - constant PROTOCOL_LEN_C : slv(7 downto 0) := x"04"; -- ProtocolLength = 4 (6 Bytes/IP) + constant HARDWWARE_LEN_C : slv(7 downto 0) := x"06"; -- HardwareLength = 6 (6 Bytes/MAC) + constant PROTOCOL_LEN_C : slv(7 downto 0) := x"04"; -- ProtocolLength = 4 (6 Bytes/IP) constant ARP_REQ_C : slv(15 downto 0) := x"0100"; -- OpCode = ARP Request = 0x0001 constant ARP_REPLY_C : slv(15 downto 0) := x"0200"; -- OpCode = ARP Reply = 0x0002 constant TIMER_1_SEC_C : natural := getTimeRatio(CLK_FREQ_G, 1.0); @@ -100,7 +98,8 @@ architecture rtl of ArpEngine is begin - comb : process (arpAckSlaves, arpReqMasters, ibArpMaster, localIp, localMac, obArpSlave, r, rst) is + comb : process (arpAckSlaves, arpReqMasters, ibArpMaster, localIp, localMac, + obArpSlave, r, rst) is variable v : RegType; variable i : natural; begin @@ -155,45 +154,21 @@ begin v.arpAckMasters(r.ackCnt).tValid := '1'; v.arpAckMasters(r.ackCnt).tData(47 downto 0) := localMac; else - ------------------------ - -- Checking for non-VLAN - ------------------------ - if (VLAN_G = false) then - v.tData(0)(47 downto 0) := BROADCAST_MAC_C; - v.tData(0)(95 downto 48) := localMac; - v.tData(0)(111 downto 96) := ARP_TYPE_C; - v.tData(0)(127 downto 112) := HARDWWARE_TYPE_C; - v.tData(1)(15 downto 0) := PROTOCOL_TYPE_C; - v.tData(1)(23 downto 16) := HARDWWARE_LEN_C; - v.tData(1)(31 downto 24) := PROTOCOL_LEN_C; - v.tData(1)(47 downto 32) := ARP_REQ_C; - v.tData(1)(95 downto 48) := localMac; - v.tData(1)(127 downto 96) := localIp; - v.tData(2)(47 downto 0) := BROADCAST_MAC_C; - v.tData(2)(79 downto 48) := arpReqMasters(r.reqCnt).tData(31 downto 0); -- Known IP address - v.tData(2)(127 downto 80) := (others => '0'); - -------------------- - -- Checking for VLAN - -------------------- - else - v.tData(0)(47 downto 0) := BROADCAST_MAC_C; - v.tData(0)(95 downto 48) := localMac; - v.tData(0)(111 downto 96) := VLAN_TYPE_C; - v.tData(0)(127 downto 122) := (others => '0'); - v.tData(1)(15 downto 0) := ARP_TYPE_C; - v.tData(1)(31 downto 16) := HARDWWARE_TYPE_C; - v.tData(1)(47 downto 32) := PROTOCOL_TYPE_C; - v.tData(1)(55 downto 48) := HARDWWARE_LEN_C; - v.tData(1)(63 downto 56) := PROTOCOL_LEN_C; - v.tData(1)(79 downto 64) := ARP_REQ_C; - v.tData(1)(127 downto 80) := localMac; - v.tData(2)(31 downto 0) := localIp; - v.tData(2)(79 downto 32) := BROADCAST_MAC_C; - v.tData(2)(111 downto 80) := arpReqMasters(r.reqCnt).tData(31 downto 0); -- Known IP address - v.tData(2)(127 downto 112) := (others => '0'); - end if; + v.tData(0)(47 downto 0) := BROADCAST_MAC_C; + v.tData(0)(95 downto 48) := localMac; + v.tData(0)(111 downto 96) := ARP_TYPE_C; + v.tData(0)(127 downto 112) := HARDWWARE_TYPE_C; + v.tData(1)(15 downto 0) := PROTOCOL_TYPE_C; + v.tData(1)(23 downto 16) := HARDWWARE_LEN_C; + v.tData(1)(31 downto 24) := PROTOCOL_LEN_C; + v.tData(1)(47 downto 32) := ARP_REQ_C; + v.tData(1)(95 downto 48) := localMac; + v.tData(1)(127 downto 96) := localIp; + v.tData(2)(47 downto 0) := BROADCAST_MAC_C; + v.tData(2)(79 downto 48) := arpReqMasters(r.reqCnt).tData(31 downto 0); -- Known IP address + v.tData(2)(127 downto 80) := (others => '0'); -- Next state - v.state := TX_S; + v.state := TX_S; end if; end if; end if; @@ -259,70 +234,32 @@ begin v.state := IDLE_S; -- Reset the counter v.cnt := 0; - ------------------------ - -- Checking for non-VLAN - ------------------------ - if (VLAN_G = false) then - if (r.tData(0)(127 downto 112) = HARDWWARE_TYPE_C) -- Check for valid Hardware type - and (r.tData(1)(15 downto 0) = PROTOCOL_TYPE_C) -- Check for valid Protocol type - and (r.tData(1)(23 downto 16) = HARDWWARE_LEN_C) -- Check for valid Hardware Length - and (r.tData(1)(31 downto 24) = PROTOCOL_LEN_C) then -- Check for valid Protocol Length - -- Check OP-CODE = ARP Request - if (r.tData(1)(47 downto 32) = ARP_REQ_C) then - -- Check if the target IP address matches local address - if r.tData(2)(79 downto 48) = localIp then - -- Modified the local buffer to become a reply packet - v.tData(0)(47 downto 0) := r.tData(0)(95 downto 48); - v.tData(0)(95 downto 48) := localMac; - v.tData(1)(47 downto 32) := ARP_REPLY_C; - v.tData(1)(95 downto 48) := localMac; - v.tData(1)(127 downto 96) := localIp; - v.tData(2)(47 downto 0) := r.tData(1)(95 downto 48); - v.tData(2)(79 downto 48) := r.tData(1)(127 downto 96); - v.tData(2)(127 downto 80) := (others => '0'); - -- Next state - v.state := TX_S; - end if; - -- Check OP-CODE = ARP Reply - elsif (r.tData(1)(47 downto 32) = ARP_REPLY_C) then - -- Check if the target IP + MAC address matches local address - if (r.tData(2)(47 downto 0) = localMac) and (r.tData(2)(79 downto 48) = localIp) then - -- Next state - v.state := SCAN_S; - end if; + if (r.tData(0)(127 downto 112) = HARDWWARE_TYPE_C) -- Check for valid Hardware type + and (r.tData(1)(15 downto 0) = PROTOCOL_TYPE_C) -- Check for valid Protocol type + and (r.tData(1)(23 downto 16) = HARDWWARE_LEN_C) -- Check for valid Hardware Length + and (r.tData(1)(31 downto 24) = PROTOCOL_LEN_C) then -- Check for valid Protocol Length + -- Check OP-CODE = ARP Request + if (r.tData(1)(47 downto 32) = ARP_REQ_C) then + -- Check if the target IP address matches local address + if r.tData(2)(79 downto 48) = localIp then + -- Modified the local buffer to become a reply packet + v.tData(0)(47 downto 0) := r.tData(0)(95 downto 48); + v.tData(0)(95 downto 48) := localMac; + v.tData(1)(47 downto 32) := ARP_REPLY_C; + v.tData(1)(95 downto 48) := localMac; + v.tData(1)(127 downto 96) := localIp; + v.tData(2)(47 downto 0) := r.tData(1)(95 downto 48); + v.tData(2)(79 downto 48) := r.tData(1)(127 downto 96); + v.tData(2)(127 downto 80) := (others => '0'); + -- Next state + v.state := TX_S; end if; - end if; - -------------------- - -- Checking for VLAN - -------------------- - else - if (r.tData(1)(31 downto 16) = HARDWWARE_TYPE_C) -- Check for valid Hardware type - and (r.tData(1)(47 downto 32) = PROTOCOL_TYPE_C) -- Check for valid Protocol type - and (r.tData(1)(55 downto 48) = HARDWWARE_LEN_C) -- Check for valid Hardware Length - and (r.tData(1)(63 downto 56) = PROTOCOL_LEN_C) then -- Check for valid Protocol Length - -- Check OP-CODE = ARP Request - if (r.tData(1)(79 downto 64) = ARP_REQ_C) then - -- Check if the target IP address matches local address - if r.tData(2)(111 downto 80) = localIp then - -- Modified the local buffer to become a reply packet - v.tData(0)(47 downto 0) := r.tData(0)(95 downto 48); - v.tData(0)(95 downto 48) := localMac; - v.tData(1)(79 downto 64) := ARP_REPLY_C; - v.tData(1)(127 downto 80) := localMac; - v.tData(2)(31 downto 0) := localIp; - v.tData(2)(79 downto 32) := r.tData(1)(127 downto 80); - v.tData(2)(111 downto 80) := r.tData(2)(31 downto 0); - v.tData(2)(127 downto 112) := (others => '0'); - -- Next state - v.state := TX_S; - end if; - -- Check OP-CODE = ARP Reply - elsif (r.tData(1)(79 downto 64) = ARP_REPLY_C) then - -- Check if the target IP + MAC address matches local address - if (r.tData(2)(79 downto 32) = localMac) and (r.tData(2)(111 downto 80) = localIp) then - -- Next state - v.state := SCAN_S; - end if; + -- Check OP-CODE = ARP Reply + elsif (r.tData(1)(47 downto 32) = ARP_REPLY_C) then + -- Check if the target IP + MAC address matches local address + if (r.tData(2)(47 downto 0) = localMac) and (r.tData(2)(79 downto 48) = localIp) then + -- Next state + v.state := SCAN_S; end if; end if; end if; @@ -330,29 +267,14 @@ begin when SCAN_S => -- Check the tValid if (arpReqMasters(r.ackCnt).tValid = '1') and (v.arpAckMasters(r.ackCnt).tValid = '0') then - ------------------------ - -- Checking for non-VLAN - ------------------------ - if (VLAN_G = false) then - -- Check if Source's IP address match request IP address - if arpReqMasters(r.ackCnt).tData(31 downto 0) = r.tData(1)(127 downto 96) then - -- ACK the request - v.arpReqSlaves(r.ackCnt).tReady := '1'; - v.arpAckMasters(r.ackCnt).tValid := '1'; - v.arpAckMasters(r.ackCnt).tData(47 downto 0) := r.tData(1)(95 downto 48); -- Source's MAC address - -- Reset the timer - v.arpTimers(r.ackCnt) := 0; - end if; - else - -- Check if Source's IP address match request IP address - if arpReqMasters(r.ackCnt).tData(31 downto 0) = r.tData(2)(31 downto 0) then - -- ACK the request - v.arpReqSlaves(r.ackCnt).tReady := '1'; - v.arpAckMasters(r.ackCnt).tValid := '1'; - v.arpAckMasters(r.ackCnt).tData(47 downto 0) := r.tData(1)(127 downto 80); -- Source's MAC address - -- Reset the timer - v.arpTimers(r.ackCnt) := 0; - end if; + -- Check if Source's IP address match request IP address + if arpReqMasters(r.ackCnt).tData(31 downto 0) = r.tData(1)(127 downto 96) then + -- ACK the request + v.arpReqSlaves(r.ackCnt).tReady := '1'; + v.arpAckMasters(r.ackCnt).tValid := '1'; + v.arpAckMasters(r.ackCnt).tData(47 downto 0) := r.tData(1)(95 downto 48); -- Source's MAC address + -- Reset the timer + v.arpTimers(r.ackCnt) := 0; end if; end if; -- Check the counter @@ -369,23 +291,19 @@ begin -- Check if ready to move data if v.txArpMaster.tValid = '0' then -- Move data - v.txArpMaster.tValid := '1'; - v.txArpMaster.tData(127 downto 0) := r.tData(r.cnt); + v.txArpMaster.tValid := '1'; + v.txArpMaster.tData(127 downto 0) := r.tData(r.cnt); -- Increment the counter - v.cnt := r.cnt + 1; + v.cnt := r.cnt + 1; if r.cnt = 0 then ssiSetUserSof(EMAC_AXIS_CONFIG_C, v.txArpMaster, '1'); elsif r.cnt = 2 then -- Set the EOF flag - v.txArpMaster.tLast := '1'; + v.txArpMaster.tLast := '1'; -- Set the tKeep - if (VLAN_G = false) then - v.txArpMaster.tKeep(15 downto 0) := x"03FF"; - else - v.txArpMaster.tKeep(15 downto 0) := x"3FFF"; - end if; + v.txArpMaster.tKeep(15 downto 0) := x"03FF"; -- Next state - v.state := IDLE_S; + v.state := IDLE_S; end if; end if; ---------------------------------------------------------------------- diff --git a/ethernet/IpV4Engine/rtl/IpV4Engine.vhd b/ethernet/IpV4Engine/rtl/IpV4Engine.vhd index e9d354f53d..81146736dc 100644 --- a/ethernet/IpV4Engine/rtl/IpV4Engine.vhd +++ b/ethernet/IpV4Engine/rtl/IpV4Engine.vhd @@ -29,8 +29,7 @@ entity IpV4Engine is CLK_FREQ_G : real := 156.25E+06; -- In units of Hz TTL_G : slv(7 downto 0) := x"20"; IGMP_G : boolean := false; - IGMP_GRP_SIZE : positive := 1; - VLAN_G : boolean := false); -- true = VLAN support + IGMP_GRP_SIZE : positive := 1); port ( -- Local Configurations localMac : in slv(47 downto 0); -- big-Endian configuration @@ -97,8 +96,7 @@ begin U_EthFrameDeMux : entity surf.IpV4EngineDeMux generic map ( - TPD_G => TPD_G, - VLAN_G => VLAN_G) + TPD_G => TPD_G) port map ( -- Local Configurations localMac => localMac, @@ -135,8 +133,7 @@ begin generic map ( TPD_G => TPD_G, CLIENT_SIZE_G => CLIENT_SIZE_G, - CLK_FREQ_G => CLK_FREQ_G, - VLAN_G => VLAN_G) + CLK_FREQ_G => CLK_FREQ_G) port map ( -- Local Configurations localMac => localMac, @@ -159,8 +156,7 @@ begin generic map ( TPD_G => TPD_G, PROTOCOL_SIZE_G => PROTOCOL_SIZE_C, - PROTOCOL_G => PROTOCOL_C, - VLAN_G => VLAN_G) + PROTOCOL_G => PROTOCOL_C) port map ( -- Interface to Ethernet Frame MUX/DEMUX ibIpv4Master => ibIpv4Master, @@ -179,8 +175,7 @@ begin TPD_G => TPD_G, PROTOCOL_SIZE_G => PROTOCOL_SIZE_C, PROTOCOL_G => PROTOCOL_C, - TTL_G => TTL_G, - VLAN_G => VLAN_G) + TTL_G => TTL_G) port map ( -- Local Configurations localMac => localMac, diff --git a/ethernet/IpV4Engine/rtl/IpV4EngineDeMux.vhd b/ethernet/IpV4Engine/rtl/IpV4EngineDeMux.vhd index 9d7eaaea45..fa89a1e598 100644 --- a/ethernet/IpV4Engine/rtl/IpV4EngineDeMux.vhd +++ b/ethernet/IpV4Engine/rtl/IpV4EngineDeMux.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -26,8 +25,7 @@ use surf.EthMacPkg.all; entity IpV4EngineDeMux is generic ( - TPD_G : time := 1 ns; - VLAN_G : boolean := false); + TPD_G : time := 1 ns); port ( -- Local Configurations localMac : in slv(47 downto 0); -- big-Endian configuration @@ -48,11 +46,6 @@ architecture rtl of IpV4EngineDeMux is constant BROADCAST_MAC_C : slv(47 downto 0) := (others => '1'); - type StateType is ( - IDLE_S, - CHECK_S, - MOVE_S); - type RegType is record arpSel : sl; ipv4Sel : sl; @@ -60,7 +53,6 @@ architecture rtl of IpV4EngineDeMux is ibArpMaster : AxiStreamMasterType; ibIpv4Master : AxiStreamMasterType; obMacSlave : AxiStreamSlaveType; - state : StateType; end record RegType; constant REG_INIT_C : RegType := ( @@ -69,8 +61,7 @@ architecture rtl of IpV4EngineDeMux is dly => AXI_STREAM_MASTER_INIT_C, ibArpMaster => AXI_STREAM_MASTER_INIT_C, ibIpv4Master => AXI_STREAM_MASTER_INIT_C, - obMacSlave => AXI_STREAM_SLAVE_INIT_C, - state => IDLE_S); + obMacSlave => AXI_STREAM_SLAVE_INIT_C); signal r : RegType := REG_INIT_C; signal rin : RegType; @@ -94,99 +85,37 @@ begin -- Check if there is data to move if (obMacMaster.tValid = '1') and (v.ibArpMaster.tValid = '0') and (v.ibIpv4Master.tValid = '0') then - ---------------------------------------------------------------------- - -- Checking for non-VLAN - ---------------------------------------------------------------------- - if (VLAN_G = false) then - -- Accept for data - v.obMacSlave.tReady := '1'; - -- Check for SOF and not EOF - if (ssiGetUserSof(EMAC_AXIS_CONFIG_C, obMacMaster) = '1') and (obMacMaster.tLast = '0') then - -- Reset the flags - v.arpSel := '0'; - v.ipv4Sel := '0'; - -- Check for a valid ARP EtherType - if (obMacMaster.tData(111 downto 96) = ARP_TYPE_C) then - -- Check the destination MAC address - if(obMacMaster.tData(47 downto 0) = BROADCAST_MAC_C) or (obMacMaster.tData(47 downto 0) = localMac) then - v.arpSel := '1'; - v.ibArpMaster := obMacMaster; - end if; - -- Check for a valid IPV4 EtherType and (IPVersion + Header length) - elsif (obMacMaster.tData(111 downto 96) = IPV4_TYPE_C) and (obMacMaster.tData(119 downto 112) = x"45") then - -- Check the destination MAC address - if(obMacMaster.tData(47 downto 0) = BROADCAST_MAC_C) or (obMacMaster.tData(47 downto 0) = localMac) then - v.ipv4Sel := '1'; - v.ibIpv4Master := obMacMaster; - end if; + -- Accept for data + v.obMacSlave.tReady := '1'; + -- Check for SOF and not EOF + if (ssiGetUserSof(EMAC_AXIS_CONFIG_C, obMacMaster) = '1') and (obMacMaster.tLast = '0') then + -- Reset the flags + v.arpSel := '0'; + v.ipv4Sel := '0'; + -- Check for a valid ARP EtherType + if (obMacMaster.tData(111 downto 96) = ARP_TYPE_C) then + -- Check the destination MAC address + if(obMacMaster.tData(47 downto 0) = BROADCAST_MAC_C) or (obMacMaster.tData(47 downto 0) = localMac) then + v.arpSel := '1'; + v.ibArpMaster := obMacMaster; + end if; + -- Check for a valid IPV4 EtherType and (IPVersion + Header length) + elsif (obMacMaster.tData(111 downto 96) = IPV4_TYPE_C) and (obMacMaster.tData(119 downto 112) = x"45") then + -- Check the destination MAC address + if(obMacMaster.tData(47 downto 0) = BROADCAST_MAC_C) or (obMacMaster.tData(47 downto 0) = localMac) then + v.ipv4Sel := '1'; + v.ibIpv4Master := obMacMaster; end if; - elsif r.arpSel = '1' then - v.ibArpMaster := obMacMaster; - elsif r.ipv4Sel = '1' then - v.ibIpv4Master := obMacMaster; - end if; - if obMacMaster.tLast = '1' then - -- Reset the flags - v.arpSel := '0'; - v.ipv4Sel := '0'; end if; - ---------------------------------------------------------------------- - -- Checking for VLAN - ---------------------------------------------------------------------- - else - -- State Machine - case r.state is - ---------------------------------------------------------------------- - when IDLE_S => - -- Accept for data - v.obMacSlave.tReady := '1'; - -- Check for SOF and not EOF - if (ssiGetUserSof(EMAC_AXIS_CONFIG_C, obMacMaster) = '1') and (obMacMaster.tLast = '0') then - -- Check for a valid VLAN EtherType - if (obMacMaster.tData(111 downto 96) = VLAN_TYPE_C) then - -- Reset the flags - v.arpSel := '0'; - v.ipv4Sel := '0'; - -- Latch the data bus - v.dly := obMacMaster; - -- Next state - v.state := CHECK_S; - end if; - end if; - ---------------------------------------------------------------------- - when CHECK_S => - -- Check for a valid ARP EtherType - if (obMacMaster.tData(15 downto 0) = ARP_TYPE_C) then - -- Check the destination MAC address - if(r.dly.tData(47 downto 0) = BROADCAST_MAC_C) or (r.dly.tData(47 downto 0) = localMac) then - v.arpSel := '1'; - v.ibArpMaster := r.dly; - end if; - -- Check for a valid IPV4 EtherType and (IPVersion + Header length) - elsif (obMacMaster.tData(15 downto 0) = IPV4_TYPE_C) and (obMacMaster.tData(23 downto 16) = x"45") then - -- Check the destination MAC address - if(r.dly.tData(47 downto 0) = BROADCAST_MAC_C) or (r.dly.tData(47 downto 0) = localMac) then - v.ipv4Sel := '1'; - v.ibIpv4Master := r.dly; - end if; - end if; - -- Next state - v.state := MOVE_S; - ---------------------------------------------------------------------- - when MOVE_S => - -- Accept for data - v.obMacSlave.tReady := '1'; - if r.arpSel = '1' then - v.ibArpMaster := obMacMaster; - elsif r.ipv4Sel = '1' then - v.ibIpv4Master := obMacMaster; - end if; - if obMacMaster.tLast = '1' then - -- Next state - v.state := IDLE_S; - end if; - ---------------------------------------------------------------------- - end case; + elsif r.arpSel = '1' then + v.ibArpMaster := obMacMaster; + elsif r.ipv4Sel = '1' then + v.ibIpv4Master := obMacMaster; + end if; + if obMacMaster.tLast = '1' then + -- Reset the flags + v.arpSel := '0'; + v.ipv4Sel := '0'; end if; end if; diff --git a/ethernet/IpV4Engine/rtl/IpV4EngineRx.vhd b/ethernet/IpV4Engine/rtl/IpV4EngineRx.vhd index b47403efce..1af8e9d054 100644 --- a/ethernet/IpV4Engine/rtl/IpV4EngineRx.vhd +++ b/ethernet/IpV4Engine/rtl/IpV4EngineRx.vhd @@ -18,7 +18,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -30,8 +29,7 @@ entity IpV4EngineRx is TPD_G : time := 1 ns; SIM_ERROR_HALT_G : boolean := false; PROTOCOL_SIZE_G : positive := 1; - PROTOCOL_G : Slv8Array := (0 => UDP_C); - VLAN_G : boolean := false); + PROTOCOL_G : Slv8Array := (0 => UDP_C)); port ( -- Interface to Ethernet Frame MUX/DEMUX ibIpv4Master : in AxiStreamMasterType; @@ -147,31 +145,19 @@ begin -- Check for data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Accept the data - v.rxSlave.tReady := '1'; - -- Check for non-VLAN - if (VLAN_G = false) then - -- Calculate the IPV4 Pseudo Header length (in little Endian) - v.len(15 downto 8) := rxMaster.tData(7 downto 0); -- IPV4_Length(15 downto 8) - v.len(7 downto 0) := rxMaster.tData(15 downto 8); -- IPV4_Length(7 downto 0) - v.len := v.len - 20; -- IPV4 Pseudo Header's length = protocol length - 20 Bytes - -- Latch the protocol value - v.protocol := rxMaster.tData(63 downto 56); - -- Source IP Address(31 downto 0) - v.txMaster.tData(95 downto 64) := rxMaster.tData(111 downto 80); - -- Destination IP Address(31 downto 16) - v.txMaster.tData(111 downto 96) := rxMaster.tData(127 downto 112); - else - -- Calculate the IPV4 Pseudo Header length (in little Endian) - v.len(15 downto 8) := rxMaster.tData(39 downto 32); -- IPV4_Length(15 downto 8) - v.len(7 downto 0) := rxMaster.tData(47 downto 40); -- IPV4_Length(7 downto 0) - v.len := v.len - 20; -- IPV4 Pseudo Header's length = protocol length - 20 Bytes - -- Latch the protocol value - v.protocol := rxMaster.tData(95 downto 88); - -- Source IP Address(31 downto 16) - v.txMaster.tData(79 downto 64) := rxMaster.tData(127 downto 112); - end if; + v.rxSlave.tReady := '1'; + -- Calculate the IPV4 Pseudo Header length (in little Endian) + v.len(15 downto 8) := rxMaster.tData(7 downto 0); -- IPV4_Length(15 downto 8) + v.len(7 downto 0) := rxMaster.tData(15 downto 8); -- IPV4_Length(7 downto 0) + v.len := v.len - 20; -- IPV4 Pseudo Header's length = protocol length - 20 Bytes + -- Latch the protocol value + v.protocol := rxMaster.tData(63 downto 56); + -- Source IP Address(31 downto 0) + v.txMaster.tData(95 downto 64) := rxMaster.tData(111 downto 80); + -- Destination IP Address(31 downto 16) + v.txMaster.tData(111 downto 96) := rxMaster.tData(127 downto 112); -- Next state if protocol not detected during the "for loop" - v.state := IDLE_S; + v.state := IDLE_S; -- Loop through the protocol buses for i in (PROTOCOL_SIZE_G-1) downto 0 loop if (v.protocol = PROTOCOL_G(i)) then @@ -187,68 +173,30 @@ begin -- Check for data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Move the data - v.txMaster.tValid := '1'; + v.txMaster.tValid := '1'; -- Set the SOF ssiSetUserSof(EMAC_AXIS_CONFIG_C, v.txMaster, '1'); - -- Check for non-VLAN - if (VLAN_G = false) then - -- Destination IP Address(15 downto 0) - v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0); - -- Track the leftovers - v.tData(7 downto 0) := x"00"; - v.tData(15 downto 8) := r.protocol; - v.tData(23 downto 16) := r.len(15 downto 8); - v.tData(31 downto 24) := r.len(7 downto 0); - v.tData(127 downto 32) := rxMaster.tData(111 downto 16); - v.tKeep(3 downto 0) := "1111"; - v.tKeep(15 downto 4) := rxMaster.tKeep(13 downto 2); - v.tLast := rxMaster.tLast; - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for no remainder - if (rxMaster.tKeep(15 downto 14) = 0) then - -- Accept the data - v.rxSlave.tReady := '1'; - -- Next state - v.state := LAST_S; - else - -- Next state - v.state := IPV4_HDR2_S; - end if; - else + -- Destination IP Address(15 downto 0) + v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0); + -- Track the leftovers + v.tData(7 downto 0) := x"00"; + v.tData(15 downto 8) := r.protocol; + v.tData(23 downto 16) := r.len(15 downto 8); + v.tData(31 downto 24) := r.len(7 downto 0); + v.tData(127 downto 32) := rxMaster.tData(111 downto 16); + v.tKeep(3 downto 0) := "1111"; + v.tKeep(15 downto 4) := rxMaster.tKeep(13 downto 2); + v.tLast := rxMaster.tLast; + v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); + -- Check for no remainder + if (rxMaster.tKeep(15 downto 14) = 0) then -- Accept the data - v.rxSlave.tReady := '1'; - -- Source IP Address(15 downto 0) - v.txMaster.tData(95 downto 80) := rxMaster.tData(15 downto 0); - -- Destination IP Address(31 downto 0) - v.txMaster.tData(127 downto 96) := rxMaster.tData(47 downto 16); - -- Track the leftovers - v.tData(7 downto 0) := x"00"; - v.tData(15 downto 8) := r.protocol; - v.tData(23 downto 16) := r.len(15 downto 8); - v.tData(31 downto 24) := r.len(7 downto 0); - v.tData(111 downto 32) := rxMaster.tData(127 downto 48); - v.tKeep(3 downto 0) := "1111"; - v.tKeep(13 downto 4) := rxMaster.tKeep(15 downto 6); - v.tKeep(15 downto 14) := "00"; - v.tLast := rxMaster.tLast; - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for EOF - if (rxMaster.tLast = '1') then - -- Check the leftovers - if (v.tKeep /= 0) then - -- Next state - v.state := LAST_S; - else - -- Set EOF and EOFE - v.txMaster.tLast := '1'; - ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); - -- Next state - v.state := IDLE_S; - end if; - else - -- Next state - v.state := MOVE_S; - end if; + v.rxSlave.tReady := '1'; + -- Next state + v.state := LAST_S; + else + -- Next state + v.state := IPV4_HDR2_S; end if; end if; ---------------------------------------------------------------------- @@ -256,17 +204,17 @@ begin -- Check for data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Accept the data - v.rxSlave.tReady := '1'; + v.rxSlave.tReady := '1'; -- Move the data v.txMaster.tValid := '1'; v.txMaster.tData(127 downto 0) := r.tData; v.txMaster.tKeep(15 downto 0) := r.tKeep; -- Track the leftovers - v.tData(15 downto 0) := rxMaster.tData(127 downto 112); - v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); - v.tKeep(15 downto 2) := (others => '0'); - v.tLast := rxMaster.tLast; - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); + v.tData(15 downto 0) := rxMaster.tData(127 downto 112); + v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); + v.tKeep(15 downto 2) := (others => '0'); + v.tLast := rxMaster.tLast; + v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); -- Check for EOF if (rxMaster.tLast = '1') then -- Check the leftovers @@ -290,33 +238,19 @@ begin -- Check for data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Accept the data - v.rxSlave.tReady := '1'; + v.rxSlave.tReady := '1'; -- Move the data - v.txMaster.tValid := '1'; - -- Check for non-VLAN - if (VLAN_G = false) then - -- Move the data - v.txMaster.tData(15 downto 0) := r.tData(15 downto 0); - v.txMaster.tData(127 downto 16) := rxMaster.tData(111 downto 0); - v.txMaster.tKeep(1 downto 0) := r.tKeep(1 downto 0); - v.txMaster.tKeep(15 downto 2) := rxMaster.tKeep(13 downto 0); - -- Track the leftovers - v.tData(15 downto 0) := rxMaster.tData(127 downto 112); - v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); - v.tLast := rxMaster.tLast; - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - else - -- Move the data - v.txMaster.tData(111 downto 0) := r.tData(111 downto 0); - v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0); - v.txMaster.tKeep(13 downto 0) := r.tKeep(13 downto 0); - v.txMaster.tKeep(15 downto 14) := rxMaster.tKeep(1 downto 0); - -- Track the leftovers - v.tData(111 downto 0) := rxMaster.tData(127 downto 16); - v.tKeep(13 downto 0) := rxMaster.tKeep(15 downto 2); - v.tLast := rxMaster.tLast; - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - end if; + v.txMaster.tValid := '1'; + -- Move the data + v.txMaster.tData(15 downto 0) := r.tData(15 downto 0); + v.txMaster.tData(127 downto 16) := rxMaster.tData(111 downto 0); + v.txMaster.tKeep(1 downto 0) := r.tKeep(1 downto 0); + v.txMaster.tKeep(15 downto 2) := rxMaster.tKeep(13 downto 0); + -- Track the leftovers + v.tData(15 downto 0) := rxMaster.tData(127 downto 112); + v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); + v.tLast := rxMaster.tLast; + v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); -- Check for tLast if (v.tLast = '1') then -- Check the leftover tKeep is not empty @@ -343,7 +277,7 @@ begin v.txMaster.tLast := '1'; ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, r.eofe); -- Next state - v.state := IDLE_S; + v.state := IDLE_S; end if; ---------------------------------------------------------------------- end case; diff --git a/ethernet/IpV4Engine/rtl/IpV4EngineTx.vhd b/ethernet/IpV4Engine/rtl/IpV4EngineTx.vhd index 7809f12dea..153d042063 100644 --- a/ethernet/IpV4Engine/rtl/IpV4EngineTx.vhd +++ b/ethernet/IpV4Engine/rtl/IpV4EngineTx.vhd @@ -18,7 +18,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -30,8 +29,7 @@ entity IpV4EngineTx is TPD_G : time := 1 ns; PROTOCOL_SIZE_G : positive := 1; PROTOCOL_G : Slv8Array := (0 => UDP_C); - TTL_G : slv(7 downto 0) := x"20"; - VLAN_G : boolean := false); + TTL_G : slv(7 downto 0) := x"20"); port ( -- Local Configurations localMac : in slv(47 downto 0); -- big-Endian configuration @@ -152,23 +150,15 @@ begin v.txMaster.tDest := x"00"; end if; -- Set the DST MAC and SRC MAC - v.txMaster.tData(47 downto 0) := rxMaster.tData(47 downto 0); - v.txMaster.tData(95 downto 48) := localMac; - -- Check for non-VLAN - if (VLAN_G = false) then - v.txMaster.tData(111 downto 96) := IPV4_TYPE_C; - v.txMaster.tData(119 downto 112) := x"45"; -- IPVersion = 4,Header length = 5 - v.txMaster.tData(127 downto 120) := x"00"; --- DSCP and ECN - else - -- Set the EtherType = VLAN Type - v.txMaster.tData(111 downto 96) := VLAN_TYPE_C; - -- VID = 0x0 here because it gets overwritten in the MAC - v.txMaster.tData(127 downto 112) := (others => '0'); - end if; + v.txMaster.tData(47 downto 0) := rxMaster.tData(47 downto 0); + v.txMaster.tData(95 downto 48) := localMac; + v.txMaster.tData(111 downto 96) := IPV4_TYPE_C; + v.txMaster.tData(119 downto 112) := x"45"; -- IPVersion = 4,Header length = 5 + v.txMaster.tData(127 downto 120) := x"00"; --- DSCP and ECN -- Track the leftovers - v.tData(63 downto 0) := rxMaster.tData(127 downto 64); + v.tData(63 downto 0) := rxMaster.tData(127 downto 64); -- Next state - v.state := IPV4_HDR0_S; + v.state := IPV4_HDR0_S; end if; end if; ---------------------------------------------------------------------- @@ -176,105 +166,52 @@ begin -- Check for data if (v.txMaster.tValid = '0') then -- Send the IPV4 header - v.txMaster.tValid := '1'; - -- Check for non-VLAN - if (VLAN_G = false) then - v.txMaster.tData(7 downto 0) := x"00"; -- IPV4_Length(15 downto 8) Note: Calculated in EthMac core - v.txMaster.tData(15 downto 8) := x"00"; -- IPV4_Length(7 downto 0) Note: Calculated in EthMac core - v.txMaster.tData(23 downto 16) := r.id(15 downto 8); -- IPV4_ID(15 downto 8) - v.txMaster.tData(31 downto 24) := r.id(7 downto 0); -- IPV4_ID(7 downto 0) - v.txMaster.tData(39 downto 32) := x"40"; -- Flags(2 downto 0) = Don't Fragment (DF) and Fragment_Offsets(12 downto 8) = 0x0 - v.txMaster.tData(47 downto 40) := x"00"; -- Fragment_Offsets(7 downto 0) = 0x0 - v.txMaster.tData(55 downto 48) := TTL_G; -- Time-To-Live (number of hops before packet is discarded) - v.txMaster.tData(63 downto 56) := PROTOCOL_G(conv_integer(r.tDest)); -- Protocol - v.txMaster.tData(71 downto 64) := x"00"; -- IPV4_Checksum(15 downto 8) Note: Filled in next state - v.txMaster.tData(79 downto 72) := x"00"; -- IPV4_Checksum(7 downto 0) Note: Filled in next state - v.txMaster.tData(111 downto 80) := r.tData(31 downto 0); -- Source IP Address(31 downto 0) - v.txMaster.tData(127 downto 112) := r.tData(47 downto 32); -- Destination IP Address(31 downto 16) - else - v.txMaster.tData(15 downto 0) := IPV4_TYPE_C; - v.txMaster.tData(23 downto 16) := x"45"; -- IPVersion = 4,Header length = 5 - v.txMaster.tData(31 downto 24) := x"00"; -- DSCP and ECN - v.txMaster.tData(39 downto 32) := x"00"; -- IPV4_Length(15 downto 8) Note: Calculated in EthMac core - v.txMaster.tData(47 downto 40) := x"00"; -- IPV4_Length(7 downto 0) Note: Calculated in EthMac core - v.txMaster.tData(55 downto 48) := r.id(15 downto 8); -- IPV4_ID(15 downto 8) - v.txMaster.tData(63 downto 56) := r.id(7 downto 0); -- IPV4_ID(7 downto 0) - v.txMaster.tData(71 downto 64) := x"40"; -- Flags(2 downto 0) = Don't Fragment (DF) and Fragment_Offsets(12 downto 8) = 0x0 - v.txMaster.tData(79 downto 72) := x"00"; -- Fragment_Offsets(7 downto 0) = 0x0 - v.txMaster.tData(87 downto 80) := TTL_G; -- Time-To-Live (number of hops before packet is discarded) - v.txMaster.tData(95 downto 88) := PROTOCOL_G(conv_integer(r.tDest)); -- Protocol - v.txMaster.tData(103 downto 96) := x"00"; -- IPV4_Checksum(15 downto 8) Note: Calculated in EthMac core - v.txMaster.tData(111 downto 104) := x"00"; -- IPV4_Checksum(7 downto 0) Note: Calculated in EthMac core - v.txMaster.tData(127 downto 112) := r.tData(15 downto 0); -- Source IP Address(31 downto 16) - end if; + v.txMaster.tValid := '1'; + v.txMaster.tData(7 downto 0) := x"00"; -- IPV4_Length(15 downto 8) Note: Calculated in EthMac core + v.txMaster.tData(15 downto 8) := x"00"; -- IPV4_Length(7 downto 0) Note: Calculated in EthMac core + v.txMaster.tData(23 downto 16) := r.id(15 downto 8); -- IPV4_ID(15 downto 8) + v.txMaster.tData(31 downto 24) := r.id(7 downto 0); -- IPV4_ID(7 downto 0) + v.txMaster.tData(39 downto 32) := x"40"; -- Flags(2 downto 0) = Don't Fragment (DF) and Fragment_Offsets(12 downto 8) = 0x0 + v.txMaster.tData(47 downto 40) := x"00"; -- Fragment_Offsets(7 downto 0) = 0x0 + v.txMaster.tData(55 downto 48) := TTL_G; -- Time-To-Live (number of hops before packet is discarded) + v.txMaster.tData(63 downto 56) := PROTOCOL_G(conv_integer(r.tDest)); -- Protocol + v.txMaster.tData(71 downto 64) := x"00"; -- IPV4_Checksum(15 downto 8) Note: Filled in next state + v.txMaster.tData(79 downto 72) := x"00"; -- IPV4_Checksum(7 downto 0) Note: Filled in next state + v.txMaster.tData(111 downto 80) := r.tData(31 downto 0); -- Source IP Address(31 downto 0) + v.txMaster.tData(127 downto 112) := r.tData(47 downto 32); -- Destination IP Address(31 downto 16) -- Increment the counter - v.id := r.id + 1; + v.id := r.id + 1; -- Next state - v.state := IPV4_HDR1_S; + v.state := IPV4_HDR1_S; end if; ---------------------------------------------------------------------- when IPV4_HDR1_S => -- Check if ready to move data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Accept the data - v.rxSlave.tReady := '1'; - -- Check for non-VLAN - if (VLAN_G = false) then - -- Update the tData bus - v.txMaster.tData(15 downto 0) := r.tData(63 downto 48); -- Destination IP Address(15 downto 0) - v.txMaster.tData(111 downto 16) := rxMaster.tData(127 downto 32); - -- Update the tKeep bus - v.txMaster.tKeep(1 downto 0) := (others => '1'); - v.txMaster.tKeep(13 downto 2) := rxMaster.tKeep(15 downto 4); - v.txMaster.tKeep(15 downto 14) := (others => '0'); - -- Get the EOFE - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for tLast - if (rxMaster.tLast = '1') then - -- Move the data - v.txMaster.tValid := '1'; - -- Set the tLast flag - v.txMaster.tLast := '1'; - -- Set the EOFE - ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); - -- Next state - v.state := IDLE_S; - else - -- Next state - v.state := IPV4_HDR2_S; - end if; - else + v.rxSlave.tReady := '1'; + -- Update the tData bus + v.txMaster.tData(15 downto 0) := r.tData(63 downto 48); -- Destination IP Address(15 downto 0) + v.txMaster.tData(111 downto 16) := rxMaster.tData(127 downto 32); + -- Update the tKeep bus + v.txMaster.tKeep(1 downto 0) := (others => '1'); + v.txMaster.tKeep(13 downto 2) := rxMaster.tKeep(15 downto 4); + v.txMaster.tKeep(15 downto 14) := (others => '0'); + -- Get the EOFE + v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); + -- Check for tLast + if (rxMaster.tLast = '1') then -- Move the data - v.txMaster.tValid := '1'; - -- Update the tData bus - v.txMaster.tData(15 downto 0) := r.tData(31 downto 16); -- Source IP Address(15 downto 0) - v.txMaster.tData(47 downto 16) := r.tData(63 downto 32); -- Destination IP Address(31 downto 0) - v.txMaster.tData(127 downto 48) := rxMaster.tData(111 downto 32); - -- Update the tKeep bus - v.txMaster.tKeep(5 downto 0) := (others => '1'); - v.txMaster.tKeep(15 downto 6) := rxMaster.tKeep(13 downto 4); - -- Track the leftovers - v.tData(15 downto 0) := rxMaster.tData(127 downto 112); - v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); - -- Get the EOFE - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for tLast - if (rxMaster.tLast = '1') then - -- Check the leftover tKeep is not empty - if (v.tKeep /= 0) then - -- Next state - v.state := LAST_S; - else - -- Set the EOF/EOFE - v.txMaster.tLast := '1'; - ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); - -- Next state - v.state := IDLE_S; - end if; - else - -- Next state - v.state := MOVE_S; - end if; + v.txMaster.tValid := '1'; + -- Set the tLast flag + v.txMaster.tLast := '1'; + -- Set the EOFE + ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); + -- Next state + v.state := IDLE_S; + else + -- Next state + v.state := IPV4_HDR2_S; end if; end if; ---------------------------------------------------------------------- @@ -316,59 +253,31 @@ begin -- Check for data if (rxMaster.tValid = '1') and (v.txMaster.tValid = '0') then -- Accept the data - v.rxSlave.tReady := '1'; + v.rxSlave.tReady := '1'; -- Move the data - v.txMaster.tValid := '1'; - -- Check for non-VLAN - if (VLAN_G = false) then - -- Move the data - v.txMaster.tData(111 downto 0) := r.tData(111 downto 0); - v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0); - v.txMaster.tKeep(13 downto 0) := r.tKeep(13 downto 0); - v.txMaster.tKeep(15 downto 14) := rxMaster.tKeep(1 downto 0); - -- Track the leftovers - v.tData(111 downto 0) := rxMaster.tData(127 downto 16); - v.tKeep(13 downto 0) := rxMaster.tKeep(15 downto 2); - -- Get the EOFE - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for tLast - if (rxMaster.tLast = '1') then - -- Check the leftover tKeep is not empty - if (v.tKeep /= 0) then - -- Next state - v.state := LAST_S; - else - -- Set the EOF/EOFE - v.txMaster.tLast := '1'; - ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); - -- Next state - v.state := IDLE_S; - end if; - end if; - else - -- Move the data - v.txMaster.tData(15 downto 0) := r.tData(15 downto 0); - v.txMaster.tData(127 downto 16) := rxMaster.tData(111 downto 0); - v.txMaster.tKeep(1 downto 0) := r.tKeep(1 downto 0); - v.txMaster.tKeep(15 downto 2) := rxMaster.tKeep(13 downto 0); - -- Track the leftovers - v.tData(15 downto 0) := rxMaster.tData(127 downto 112); - v.tKeep(1 downto 0) := rxMaster.tKeep(15 downto 14); - -- Get the EOFE - v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); - -- Check for tLast - if (rxMaster.tLast = '1') then - -- Check the leftover tKeep is not empty - if (v.tKeep /= 0) then - -- Next state - v.state := LAST_S; - else - -- Set the EOF/EOFE - v.txMaster.tLast := '1'; - ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); - -- Next state - v.state := IDLE_S; - end if; + v.txMaster.tValid := '1'; + -- Move the data + v.txMaster.tData(111 downto 0) := r.tData(111 downto 0); + v.txMaster.tData(127 downto 112) := rxMaster.tData(15 downto 0); + v.txMaster.tKeep(13 downto 0) := r.tKeep(13 downto 0); + v.txMaster.tKeep(15 downto 14) := rxMaster.tKeep(1 downto 0); + -- Track the leftovers + v.tData(111 downto 0) := rxMaster.tData(127 downto 16); + v.tKeep(13 downto 0) := rxMaster.tKeep(15 downto 2); + -- Get the EOFE + v.eofe := ssiGetUserEofe(EMAC_AXIS_CONFIG_C, rxMaster); + -- Check for tLast + if (rxMaster.tLast = '1') then + -- Check the leftover tKeep is not empty + if (v.tKeep /= 0) then + -- Next state + v.state := LAST_S; + else + -- Set the EOF/EOFE + v.txMaster.tLast := '1'; + ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, v.eofe); + -- Next state + v.state := IDLE_S; end if; end if; end if; @@ -383,7 +292,7 @@ begin v.txMaster.tLast := '1'; ssiSetUserEofe(EMAC_AXIS_CONFIG_C, v.txMaster, r.eofe); -- Next state - v.state := IDLE_S; + v.state := IDLE_S; end if; ---------------------------------------------------------------------- end case; diff --git a/ethernet/IpV4Engine/tb/IpV4EngineCoreTb.vhd b/ethernet/IpV4Engine/tb/IpV4EngineCoreTb.vhd index 8a8ddd9e96..23bebd75de 100644 --- a/ethernet/IpV4Engine/tb/IpV4EngineCoreTb.vhd +++ b/ethernet/IpV4Engine/tb/IpV4EngineCoreTb.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -31,8 +30,6 @@ entity IpV4EngineCoreTb is LOCAL_IP_G : slv(31 downto 0); REMOTE_MAC_G : slv(47 downto 0); REMOTE_IP_G : slv(31 downto 0); - VLAN_G : boolean; - VID_G : slv(15 downto 0); MAX_CNT_G : natural; UDP_LEN_G : natural); port ( @@ -115,7 +112,8 @@ architecture rtl of IpV4EngineCoreTb is begin - comb : process (arpAckMaster, arpReqSlave, ibProtocolMaster, obProtocolSlave, r, rst) is + comb : process (arpAckMaster, arpReqSlave, ibProtocolMaster, + obProtocolSlave, r, rst) is variable v : RegType; variable i : natural; begin @@ -188,15 +186,15 @@ begin v.txCnt := r.txCnt + 1; ssiSetUserSof(EMAC_AXIS_CONFIG_C, v.obProtocolMaster, '1'); v.obProtocolMaster.tdata(47 downto 0) := r.remoteMac; -- Remote IP address - v.obProtocolMaster.tdata(63 downto 48) := VID_G; -- VLAN's ID - v.obProtocolMaster.tdata(95 downto 64) := LOCAL_IP_G; -- Source IPv4 Address + v.obProtocolMaster.tdata(63 downto 48) := (others => '0'); + v.obProtocolMaster.tdata(95 downto 64) := LOCAL_IP_G; -- Source IPv4 Address v.obProtocolMaster.tdata(127 downto 96) := REMOTE_IP_G; -- Destination IPv4 Address elsif r.txCnt = 1 then v.txCnt := r.txCnt + 1; - v.obProtocolMaster.tdata(7 downto 0) := x"00"; -- Zeros - v.obProtocolMaster.tdata(15 downto 8) := UDP_C; -- Protocol + v.obProtocolMaster.tdata(7 downto 0) := x"00"; -- Zeros + v.obProtocolMaster.tdata(15 downto 8) := UDP_C; -- Protocol v.obProtocolMaster.tdata(23 downto 16) := r.len(15 downto 8); -- Datagram Length - v.obProtocolMaster.tdata(31 downto 24) := r.len(7 downto 0); -- Datagram Length + v.obProtocolMaster.tdata(31 downto 24) := r.len(7 downto 0); -- Datagram Length v.obProtocolMaster.tdata(127 downto 32) := (others => '0'); else -- Send data @@ -244,7 +242,7 @@ begin v.rxCnt := r.rxCnt + 1; -- Check for errors if (ssiGetUserSof(EMAC_AXIS_CONFIG_C, ibProtocolMaster) = '0') - or (ibProtocolMaster.tdata(47 downto 0) /= r.remoteMac) -- Remote IP address + or (ibProtocolMaster.tdata(47 downto 0) /= r.remoteMac) -- Remote IP address or (ibProtocolMaster.tdata(95 downto 64) /= REMOTE_IP_G) -- Source IPv4 Address or (ibProtocolMaster.tdata(127 downto 96) /= LOCAL_IP_G) then -- Destination IPv4 Address v.failed(1) := '1'; @@ -253,7 +251,7 @@ begin -- Increment the counter v.rxCnt := r.rxCnt + 1; -- Check for errors - if (ibProtocolMaster.tdata(7 downto 0) /= x"00") -- Zeros + if (ibProtocolMaster.tdata(7 downto 0) /= x"00") -- Zeros or (ibProtocolMaster.tdata(15 downto 8) /= UDP_C) -- Protocol or (ibProtocolMaster.tdata(23 downto 16) /= r.len(15 downto 8)) -- Datagram Length or (ibProtocolMaster.tdata(31 downto 24) /= r.len(7 downto 0)) then -- Datagram Length diff --git a/ethernet/IpV4Engine/tb/IpV4EngineTb.vhd b/ethernet/IpV4Engine/tb/IpV4EngineTb.vhd index 77e4c17d10..813665e490 100644 --- a/ethernet/IpV4Engine/tb/IpV4EngineTb.vhd +++ b/ethernet/IpV4Engine/tb/IpV4EngineTb.vhd @@ -17,7 +17,6 @@ use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; @@ -35,9 +34,6 @@ architecture testbed of IpV4EngineTb is constant REMOTE_MAC_C : slv(47 downto 0) := x"DEADBEEFCAFE"; constant REMOTE_IP_C : slv(31 downto 0) := x"ABCDEFFF"; - constant VLAN_C : boolean := false; - constant VID_C : slv(15 downto 0) := x"0000"; - constant PROTOCOL_C : Slv8Array(0 downto 0) := (0 => UDP_C); constant MAX_CNT_C : natural := 256; constant UDP_LEN_C : natural := 16*MAX_CNT_C; @@ -65,7 +61,7 @@ begin ClkRst_Inst : entity surf.ClkRst generic map ( CLK_PERIOD_G => CLK_PERIOD_C, - RST_START_DELAY_G => 0 ns, -- Wait this long into simulation before asserting reset + RST_START_DELAY_G => 0 ns, -- Wait this long into simulation before asserting reset RST_HOLD_TIME_G => 1000 ns) -- Hold reset for this long) port map ( clkP => clk, @@ -80,8 +76,7 @@ begin PROTOCOL_SIZE_G => 1, PROTOCOL_G => PROTOCOL_C, CLIENT_SIZE_G => 1, - ARP_TIMEOUT_G => 156250000, - VLAN_G => VLAN_C) + ARP_TIMEOUT_G => 156250000) port map ( -- Local Configurations localMac => LOCAL_MAC_C, @@ -166,8 +161,7 @@ begin PROTOCOL_SIZE_G => 1, PROTOCOL_G => PROTOCOL_C, CLIENT_SIZE_G => 1, - ARP_TIMEOUT_G => 156250000, - VLAN_G => VLAN_C) + ARP_TIMEOUT_G => 156250000) port map ( -- Local Configurations localMac => REMOTE_MAC_C, @@ -216,8 +210,6 @@ begin LOCAL_IP_G => LOCAL_IP_C, REMOTE_MAC_G => REMOTE_MAC_C, REMOTE_IP_G => REMOTE_IP_C, - VLAN_G => VLAN_C, - VID_G => VID_C, MAX_CNT_G => MAX_CNT_C, UDP_LEN_G => UDP_LEN_C) port map ( diff --git a/ethernet/UdpEngine/rtl/UdpEngineWrapper.vhd b/ethernet/UdpEngine/rtl/UdpEngineWrapper.vhd index fdde578a71..7763736090 100644 --- a/ethernet/UdpEngine/rtl/UdpEngineWrapper.vhd +++ b/ethernet/UdpEngine/rtl/UdpEngineWrapper.vhd @@ -45,7 +45,6 @@ entity UdpEngineWrapper is CLK_FREQ_G : real := 156.25E+06; -- In units of Hz COMM_TIMEOUT_G : positive := 30; -- In units of seconds, Client's Communication timeout before re-ARPing or DHCP discover/request TTL_G : slv(7 downto 0) := x"20"; -- IPv4's Time-To-Live (TTL) - VLAN_G : boolean := false; -- true = VLAN support SYNTH_MODE_G : string := "inferred"); -- Synthesis mode for internal RAMs port ( -- Local Configurations @@ -134,8 +133,7 @@ begin CLIENT_SIZE_G => CLIENT_SIZE_G, CLK_FREQ_G => CLK_FREQ_G, IGMP_G => IGMP_G, - IGMP_GRP_SIZE => IGMP_GRP_SIZE, - VLAN_G => VLAN_G) + IGMP_GRP_SIZE => IGMP_GRP_SIZE) port map ( -- Local Configurations localMac => localMac, From 2a251612200f77ef12f544d776866a68ab159713 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Wed, 24 Jul 2024 08:14:24 -0700 Subject: [PATCH 04/43] Pgp2fcGtyCore was build with 2023.1 (not 2020.1) --- protocols/pgp/pgp2fc/gtyUltraScale+/ruckus.tcl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/protocols/pgp/pgp2fc/gtyUltraScale+/ruckus.tcl b/protocols/pgp/pgp2fc/gtyUltraScale+/ruckus.tcl index 565e8facf8..f6668faf6c 100644 --- a/protocols/pgp/pgp2fc/gtyUltraScale+/ruckus.tcl +++ b/protocols/pgp/pgp2fc/gtyUltraScale+/ruckus.tcl @@ -2,7 +2,7 @@ source $::env(RUCKUS_QUIET_FLAG) $::env(RUCKUS_PROC_TCL) # Load local source Code and constraints -if { $::env(VIVADO_VERSION) >= 2020.1 } { +if { $::env(VIVADO_VERSION) >= 2023.1 } { loadSource -lib surf -dir "$::DIR_PATH/rtl" @@ -10,5 +10,5 @@ if { $::env(VIVADO_VERSION) >= 2020.1 } { #loadIpCore -path "$::DIR_PATH/ip/Pgp2fcGtyCore.xci" } else { - puts "\n\nWARNING: $::DIR_PATH requires Vivado 2020.1 (or later)\n\n" + puts "\n\nWARNING: $::DIR_PATH requires Vivado 2023.1 (or later)\n\n" } From e190495a278c5549066744c25f57d548ea075680 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 15 Aug 2024 10:59:38 -0700 Subject: [PATCH 05/43] bug fix for locked IPs in MicroblazeBasicCore.bd for v2022.2 (or later) --- xilinx/general/microblaze/ruckus.tcl | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/xilinx/general/microblaze/ruckus.tcl b/xilinx/general/microblaze/ruckus.tcl index 65e47b3310..748eda01f7 100644 --- a/xilinx/general/microblaze/ruckus.tcl +++ b/xilinx/general/microblaze/ruckus.tcl @@ -19,13 +19,15 @@ if { [info exists ::env(VITIS_SRC_PATH)] != 1 } { loadSource -lib surf -path "$::DIR_PATH/generate/MicroblazeBasicCoreWrapper.vhd" # Load the .bd file - if { $::env(VIVADO_VERSION) == 2023.2 || - $::env(VIVADO_VERSION) == 2023.1 || - $::env(VIVADO_VERSION) == 2022.2 } { - puts "\nVivado v$::env(VIVADO_VERSION) not supported for general/microblaze\n" - exit -1 - } elseif { $::env(VIVADO_VERSION) >= 2021.1 } { + if { $::env(VIVADO_VERSION) >= 2021.1 } { loadBlockDesign -path "$::DIR_PATH/bd/2021.1/MicroblazeBasicCore.bd" + + # Word around for the locked IPs + open_bd_design [get_bd_designs MicroblazeBasicCore] + upgrade_ip [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -log ip_upgrade.log + export_ip_user_files -of_objects [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -no_script -sync -force -quiet + close_bd_design [get_bd_designs MicroblazeBasicCore] + } else { loadBlockDesign -path "$::DIR_PATH/bd/2020.1/MicroblazeBasicCore.bd" } From 7ad37a4d26e8d6a66edc36e5b1c686c8d36d9c8b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 15 Aug 2024 15:53:42 -0700 Subject: [PATCH 06/43] bug fix for microblaze/bd/2021.1 --- .../bd/2021.1/MicroblazeBasicCore.tcl | 466 ++++++++++++++++++ xilinx/general/microblaze/ruckus.tcl | 14 +- 2 files changed, 475 insertions(+), 5 deletions(-) create mode 100644 xilinx/general/microblaze/bd/2021.1/MicroblazeBasicCore.tcl diff --git a/xilinx/general/microblaze/bd/2021.1/MicroblazeBasicCore.tcl b/xilinx/general/microblaze/bd/2021.1/MicroblazeBasicCore.tcl new file mode 100644 index 0000000000..72165f1f63 --- /dev/null +++ b/xilinx/general/microblaze/bd/2021.1/MicroblazeBasicCore.tcl @@ -0,0 +1,466 @@ + +################################################################ +# This is a generated script based on design: MicroblazeBasicCore +# +# Though there are limitations about the generated script, +# the main purpose of this utility is to make learning +# IP Integrator Tcl commands easier. +################################################################ + +namespace eval _tcl { +proc get_script_folder {} { + set script_path [file normalize [info script]] + set script_folder [file dirname $script_path] + return $script_folder +} +} +variable script_folder +set script_folder [_tcl::get_script_folder] + +################################################################ +# Check if script is running in correct Vivado version. +################################################################ +# set scripts_vivado_version 2021.1 +# set current_vivado_version [version -short] + +# if { [string first $scripts_vivado_version $current_vivado_version] == -1 } { + # puts "" + # catch {common::send_gid_msg -ssname BD::TCL -id 2041 -severity "ERROR" "This script was generated using Vivado <$scripts_vivado_version> and is being run in <$current_vivado_version> of Vivado. Please run the script in Vivado <$scripts_vivado_version> then open the design in Vivado <$current_vivado_version>. Upgrade the design by running \"Tools => Report => Report IP Status...\", then run write_bd_tcl to create an updated script."} + + # return 1 +# } + +################################################################ +# START +################################################################ + +# To test this script, run the following commands from Vivado Tcl console: +# source MicroblazeBasicCore_script.tcl + +# If there is no project opened, this script will create a +# project, but make sure you do not have an existing project +# <./myproj/project_1.xpr> in the current working folder. + +set list_projs [get_projects -quiet] +if { $list_projs eq "" } { + create_project project_1 myproj -part xc7a200tfbg676-2 + set_property BOARD_PART xilinx.com:ac701:part0:1.4 [current_project] +} + + +# CHANGE DESIGN NAME HERE +variable design_name +set design_name MicroblazeBasicCore + +# If you do not already have an existing IP Integrator design open, +# you can create a design using the following command: +# create_bd_design $design_name + +# Creating design if needed +set errMsg "" +set nRet 0 + +set cur_design [current_bd_design -quiet] +set list_cells [get_bd_cells -quiet] + +if { ${design_name} eq "" } { + # USE CASES: + # 1) Design_name not set + + set errMsg "Please set the variable to a non-empty value." + set nRet 1 + +} elseif { ${cur_design} ne "" && ${list_cells} eq "" } { + # USE CASES: + # 2): Current design opened AND is empty AND names same. + # 3): Current design opened AND is empty AND names diff; design_name NOT in project. + # 4): Current design opened AND is empty AND names diff; design_name exists in project. + + if { $cur_design ne $design_name } { + common::send_gid_msg -ssname BD::TCL -id 2001 -severity "INFO" "Changing value of from <$design_name> to <$cur_design> since current design is empty." + set design_name [get_property NAME $cur_design] + } + common::send_gid_msg -ssname BD::TCL -id 2002 -severity "INFO" "Constructing design in IPI design <$cur_design>..." + +} elseif { ${cur_design} ne "" && $list_cells ne "" && $cur_design eq $design_name } { + # USE CASES: + # 5) Current design opened AND has components AND same names. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 1 +} elseif { [get_files -quiet ${design_name}.bd] ne "" } { + # USE CASES: + # 6) Current opened design, has components, but diff names, design_name exists in project. + # 7) No opened design, design_name exists in project. + + set errMsg "Design <$design_name> already exists in your project, please set the variable to another value." + set nRet 2 + +} else { + # USE CASES: + # 8) No opened design, design_name not in project. + # 9) Current opened design, has components, but diff names, design_name not in project. + + common::send_gid_msg -ssname BD::TCL -id 2003 -severity "INFO" "Currently there is no design <$design_name> in project, so creating one..." + + create_bd_design $design_name + + common::send_gid_msg -ssname BD::TCL -id 2004 -severity "INFO" "Making design <$design_name> as current_bd_design." + current_bd_design $design_name + +} + + # Add USER_COMMENTS on $design_name + set_property USER_COMMENTS.comment_1 "Example MicroBlaze Design in IP Integrator" [get_bd_designs $design_name] + +common::send_gid_msg -ssname BD::TCL -id 2005 -severity "INFO" "Currently the variable is equal to \"$design_name\"." + +if { $nRet != 0 } { + catch {common::send_gid_msg -ssname BD::TCL -id 2006 -severity "ERROR" $errMsg} + return $nRet +} + +set bCheckIPsPassed 1 +################################################################## +# CHECK IPs +################################################################## +set bCheckIPs 1 +if { $bCheckIPs == 1 } { + set list_check_ips "\ +xilinx.com:ip:axi_gpio:2.0\ +xilinx.com:ip:axi_intc:4.1\ +xilinx.com:ip:axi_timer:2.0\ +xilinx.com:ip:xlconstant:1.1\ +xilinx.com:ip:mdm:3.2\ +xilinx.com:ip:microblaze:11.0\ +xilinx.com:ip:proc_sys_reset:5.0\ +xilinx.com:ip:xlconcat:2.1\ +xilinx.com:ip:lmb_bram_if_cntlr:4.0\ +xilinx.com:ip:lmb_v10:3.0\ +xilinx.com:ip:blk_mem_gen:8.4\ +" + + set list_ips_missing "" + common::send_gid_msg -ssname BD::TCL -id 2011 -severity "INFO" "Checking if the following IPs exist in the project's IP catalog: $list_check_ips ." + + foreach ip_vlnv $list_check_ips { + set ip_obj [get_ipdefs -all $ip_vlnv] + if { $ip_obj eq "" } { + lappend list_ips_missing $ip_vlnv + } + } + + if { $list_ips_missing ne "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2012 -severity "ERROR" "The following IPs are not found in the IP Catalog:\n $list_ips_missing\n\nResolution: Please add the repository containing the IP(s) to the project." } + set bCheckIPsPassed 0 + } + +} + +if { $bCheckIPsPassed != 1 } { + common::send_gid_msg -ssname BD::TCL -id 2023 -severity "WARNING" "Will not continue with creation of design due to the error(s) above." + return 3 +} + +################################################################## +# DESIGN PROCs +################################################################## + + +# Hierarchical cell: microblaze_0_local_memory +proc create_hier_cell_microblaze_0_local_memory { parentCell nameHier } { + + variable script_folder + + if { $parentCell eq "" || $nameHier eq "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2092 -severity "ERROR" "create_hier_cell_microblaze_0_local_memory() - Empty argument(s)!"} + return + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + # Create cell and set as current instance + set hier_obj [create_bd_cell -type hier $nameHier] + current_bd_instance $hier_obj + + # Create interface pins + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 DLMB + + create_bd_intf_pin -mode MirroredMaster -vlnv xilinx.com:interface:lmb_rtl:1.0 ILMB + + + # Create pins + create_bd_pin -dir I -type clk LMB_Clk + create_bd_pin -dir I -type rst SYS_Rst + + # Create instance: dlmb_bram_if_cntlr, and set properties + set dlmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 dlmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $dlmb_bram_if_cntlr + + # Create instance: dlmb_v10, and set properties + set dlmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 dlmb_v10 ] + + # Create instance: ilmb_bram_if_cntlr, and set properties + set ilmb_bram_if_cntlr [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_bram_if_cntlr:4.0 ilmb_bram_if_cntlr ] + set_property -dict [ list \ + CONFIG.C_ECC {0} \ + ] $ilmb_bram_if_cntlr + + # Create instance: ilmb_v10, and set properties + set ilmb_v10 [ create_bd_cell -type ip -vlnv xilinx.com:ip:lmb_v10:3.0 ilmb_v10 ] + + # Create instance: lmb_bram, and set properties + set lmb_bram [ create_bd_cell -type ip -vlnv xilinx.com:ip:blk_mem_gen:8.4 lmb_bram ] + set_property -dict [ list \ + CONFIG.Memory_Type {True_Dual_Port_RAM} \ + CONFIG.use_bram_block {BRAM_Controller} \ + ] $lmb_bram + + # Create interface connections + connect_bd_intf_net -intf_net microblaze_0_dlmb [get_bd_intf_pins DLMB] [get_bd_intf_pins dlmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_dlmb_bus [get_bd_intf_pins dlmb_bram_if_cntlr/SLMB] [get_bd_intf_pins dlmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_dlmb_cntlr [get_bd_intf_pins dlmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTA] + connect_bd_intf_net -intf_net microblaze_0_ilmb [get_bd_intf_pins ILMB] [get_bd_intf_pins ilmb_v10/LMB_M] + connect_bd_intf_net -intf_net microblaze_0_ilmb_bus [get_bd_intf_pins ilmb_bram_if_cntlr/SLMB] [get_bd_intf_pins ilmb_v10/LMB_Sl_0] + connect_bd_intf_net -intf_net microblaze_0_ilmb_cntlr [get_bd_intf_pins ilmb_bram_if_cntlr/BRAM_PORT] [get_bd_intf_pins lmb_bram/BRAM_PORTB] + + # Create port connections + connect_bd_net -net SYS_Rst_1 [get_bd_pins SYS_Rst] [get_bd_pins dlmb_bram_if_cntlr/LMB_Rst] [get_bd_pins dlmb_v10/SYS_Rst] [get_bd_pins ilmb_bram_if_cntlr/LMB_Rst] [get_bd_pins ilmb_v10/SYS_Rst] + connect_bd_net -net microblaze_0_Clk [get_bd_pins LMB_Clk] [get_bd_pins dlmb_bram_if_cntlr/LMB_Clk] [get_bd_pins dlmb_v10/LMB_Clk] [get_bd_pins ilmb_bram_if_cntlr/LMB_Clk] [get_bd_pins ilmb_v10/LMB_Clk] + + # Restore current instance + current_bd_instance $oldCurInst +} + + +# Procedure to create entire design; Provide argument to make +# procedure reusable. If parentCell is "", will use root. +proc create_root_design { parentCell } { + + variable script_folder + variable design_name + + if { $parentCell eq "" } { + set parentCell [get_bd_cells /] + } + + # Get object for parentCell + set parentObj [get_bd_cells $parentCell] + if { $parentObj == "" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2090 -severity "ERROR" "Unable to find parent cell <$parentCell>!"} + return + } + + # Make sure parentObj is hier blk + set parentType [get_property TYPE $parentObj] + if { $parentType ne "hier" } { + catch {common::send_gid_msg -ssname BD::TCL -id 2091 -severity "ERROR" "Parent <$parentObj> has TYPE = <$parentType>. Expected to be ."} + return + } + + # Save current instance; Restore later + set oldCurInst [current_bd_instance .] + + # Set parent object as current + current_bd_instance $parentObj + + + # Create interface ports + set M0_AXIS [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:axis_rtl:1.0 M0_AXIS ] + set_property -dict [ list \ + CONFIG.FREQ_HZ {156250000} \ + ] $M0_AXIS + + set M_AXI_DP [ create_bd_intf_port -mode Master -vlnv xilinx.com:interface:aximm_rtl:1.0 M_AXI_DP ] + set_property -dict [ list \ + CONFIG.ADDR_WIDTH {32} \ + CONFIG.DATA_WIDTH {32} \ + CONFIG.FREQ_HZ {156250000} \ + CONFIG.HAS_BURST {0} \ + CONFIG.HAS_CACHE {0} \ + CONFIG.HAS_LOCK {0} \ + CONFIG.HAS_QOS {0} \ + CONFIG.HAS_REGION {0} \ + CONFIG.NUM_READ_OUTSTANDING {2} \ + CONFIG.NUM_WRITE_OUTSTANDING {2} \ + CONFIG.PROTOCOL {AXI4LITE} \ + ] $M_AXI_DP + + set S0_AXIS [ create_bd_intf_port -mode Slave -vlnv xilinx.com:interface:axis_rtl:1.0 S0_AXIS ] + set_property -dict [ list \ + CONFIG.FREQ_HZ {156250000} \ + CONFIG.HAS_TKEEP {0} \ + CONFIG.HAS_TLAST {1} \ + CONFIG.HAS_TREADY {1} \ + CONFIG.HAS_TSTRB {0} \ + CONFIG.LAYERED_METADATA {undef} \ + CONFIG.TDATA_NUM_BYTES {4} \ + CONFIG.TDEST_WIDTH {0} \ + CONFIG.TID_WIDTH {0} \ + CONFIG.TUSER_WIDTH {0} \ + ] $S0_AXIS + + + # Create ports + set GPIO_0_OUT [ create_bd_port -dir O -from 0 -to 0 -type data GPIO_0_OUT ] + set INTERRUPT [ create_bd_port -dir I -from 7 -to 0 INTERRUPT ] + set clk [ create_bd_port -dir I -type clk -freq_hz 156250000 clk ] + set dcm_locked [ create_bd_port -dir I dcm_locked ] + set reset [ create_bd_port -dir I -type rst reset ] + set_property -dict [ list \ + CONFIG.POLARITY {ACTIVE_HIGH} \ + ] $reset + + # Create instance: axi_gpio_0, and set properties + set axi_gpio_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_gpio:2.0 axi_gpio_0 ] + set_property -dict [ list \ + CONFIG.C_ALL_OUTPUTS {1} \ + CONFIG.C_GPIO_WIDTH {1} \ + ] $axi_gpio_0 + + # Create instance: axi_intc_0, and set properties + set axi_intc_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_intc:4.1 axi_intc_0 ] + set_property -dict [ list \ + CONFIG.C_HAS_FAST {1} \ + CONFIG.C_IRQ_IS_LEVEL {0} \ + CONFIG.C_KIND_OF_EDGE {0xFFFFFFFF} \ + CONFIG.C_KIND_OF_INTR {0xFFFFFC00} \ + CONFIG.C_KIND_OF_LVL {0xFFFFFFFF} \ + CONFIG.C_NUM_SW_INTR {10} \ + ] $axi_intc_0 + + # Create instance: axi_timer_0, and set properties + set axi_timer_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_timer:2.0 axi_timer_0 ] + + # Create instance: gnd_0, and set properties + set gnd_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconstant:1.1 gnd_0 ] + set_property -dict [ list \ + CONFIG.CONST_VAL {0} \ + ] $gnd_0 + + # Create instance: mdm_1, and set properties + set mdm_1 [ create_bd_cell -type ip -vlnv xilinx.com:ip:mdm:3.2 mdm_1 ] + set_property -dict [ list \ + CONFIG.C_USE_UART {1} \ + ] $mdm_1 + + # Create instance: microblaze_0, and set properties + set microblaze_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:microblaze:11.0 microblaze_0 ] + set_property -dict [ list \ + CONFIG.C_DEBUG_ENABLED {1} \ + CONFIG.C_D_AXI {1} \ + CONFIG.C_D_LMB {1} \ + CONFIG.C_FSL_LINKS {1} \ + CONFIG.C_I_LMB {1} \ + CONFIG.C_NUMBER_OF_PC_BRK {4} \ + CONFIG.C_USE_BARREL {1} \ + CONFIG.C_USE_DIV {1} \ + CONFIG.C_USE_EXTENDED_FSL_INSTR {1} \ + CONFIG.C_USE_FPU {2} \ + CONFIG.C_USE_HW_MUL {2} \ + CONFIG.C_USE_MSR_INSTR {1} \ + CONFIG.C_USE_PCMP_INSTR {1} \ + ] $microblaze_0 + + # Create instance: microblaze_0_local_memory + create_hier_cell_microblaze_0_local_memory [current_bd_instance .] microblaze_0_local_memory + + # Create instance: microblaze_axi_periph, and set properties + set microblaze_axi_periph [ create_bd_cell -type ip -vlnv xilinx.com:ip:axi_interconnect:2.1 microblaze_axi_periph ] + set_property -dict [ list \ + CONFIG.NUM_MI {5} \ + ] $microblaze_axi_periph + + # Create instance: rst_clk_wiz_1_100M, and set properties + set rst_clk_wiz_1_100M [ create_bd_cell -type ip -vlnv xilinx.com:ip:proc_sys_reset:5.0 rst_clk_wiz_1_100M ] + set_property -dict [ list \ + CONFIG.C_AUX_RESET_HIGH {1} \ + CONFIG.C_AUX_RST_WIDTH {1} \ + CONFIG.C_EXT_RST_WIDTH {1} \ + ] $rst_clk_wiz_1_100M + + # Create instance: xlconcat_0, and set properties + set xlconcat_0 [ create_bd_cell -type ip -vlnv xilinx.com:ip:xlconcat:2.1 xlconcat_0 ] + set_property -dict [ list \ + CONFIG.IN0_WIDTH {8} \ + CONFIG.IN1_WIDTH {1} \ + CONFIG.IN2_WIDTH {1} \ + CONFIG.NUM_PORTS {3} \ + ] $xlconcat_0 + + # Create interface connections + connect_bd_intf_net -intf_net S0_AXIS_0_1 [get_bd_intf_ports S0_AXIS] [get_bd_intf_pins microblaze_0/S0_AXIS] + connect_bd_intf_net -intf_net axi_intc_0_interrupt [get_bd_intf_pins axi_intc_0/interrupt] [get_bd_intf_pins microblaze_0/INTERRUPT] + connect_bd_intf_net -intf_net microblaze_0_M0_AXIS [get_bd_intf_ports M0_AXIS] [get_bd_intf_pins microblaze_0/M0_AXIS] + connect_bd_intf_net -intf_net microblaze_0_M_AXI_DP [get_bd_intf_pins microblaze_0/M_AXI_DP] [get_bd_intf_pins microblaze_axi_periph/S00_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M00_AXI [get_bd_intf_ports M_AXI_DP] [get_bd_intf_pins microblaze_axi_periph/M00_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M01_AXI [get_bd_intf_pins axi_intc_0/s_axi] [get_bd_intf_pins microblaze_axi_periph/M01_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M02_AXI [get_bd_intf_pins axi_timer_0/S_AXI] [get_bd_intf_pins microblaze_axi_periph/M02_AXI] + connect_bd_intf_net -intf_net microblaze_0_axi_periph_M03_AXI [get_bd_intf_pins mdm_1/S_AXI] [get_bd_intf_pins microblaze_axi_periph/M03_AXI] + connect_bd_intf_net -intf_net microblaze_0_debug [get_bd_intf_pins mdm_1/MBDEBUG_0] [get_bd_intf_pins microblaze_0/DEBUG] + connect_bd_intf_net -intf_net microblaze_0_dlmb_1 [get_bd_intf_pins microblaze_0/DLMB] [get_bd_intf_pins microblaze_0_local_memory/DLMB] + connect_bd_intf_net -intf_net microblaze_0_ilmb_1 [get_bd_intf_pins microblaze_0/ILMB] [get_bd_intf_pins microblaze_0_local_memory/ILMB] + connect_bd_intf_net -intf_net microblaze_axi_periph_M04_AXI [get_bd_intf_pins axi_gpio_0/S_AXI] [get_bd_intf_pins microblaze_axi_periph/M04_AXI] + + # Create port connections + connect_bd_net -net In0_0_1 [get_bd_ports INTERRUPT] [get_bd_pins xlconcat_0/In0] + connect_bd_net -net axi_gpio_0_gpio_io_o [get_bd_ports GPIO_0_OUT] [get_bd_pins axi_gpio_0/gpio_io_o] + connect_bd_net -net axi_timer_0_interrupt [get_bd_pins axi_timer_0/interrupt] [get_bd_pins xlconcat_0/In1] + connect_bd_net -net dcm_locked_0_1 [get_bd_ports dcm_locked] [get_bd_pins rst_clk_wiz_1_100M/dcm_locked] + connect_bd_net -net gnd_0_dout [get_bd_pins axi_timer_0/capturetrig0] [get_bd_pins axi_timer_0/capturetrig1] [get_bd_pins axi_timer_0/freeze] [get_bd_pins gnd_0/dout] + connect_bd_net -net mdm_1_Interrupt [get_bd_pins mdm_1/Interrupt] [get_bd_pins xlconcat_0/In2] + connect_bd_net -net mdm_1_debug_sys_rst [get_bd_pins mdm_1/Debug_SYS_Rst] [get_bd_pins rst_clk_wiz_1_100M/mb_debug_sys_rst] + connect_bd_net -net microblaze_0_Clk [get_bd_ports clk] [get_bd_pins axi_gpio_0/s_axi_aclk] [get_bd_pins axi_intc_0/processor_clk] [get_bd_pins axi_intc_0/s_axi_aclk] [get_bd_pins axi_timer_0/s_axi_aclk] [get_bd_pins mdm_1/S_AXI_ACLK] [get_bd_pins microblaze_0/Clk] [get_bd_pins microblaze_0_local_memory/LMB_Clk] [get_bd_pins microblaze_axi_periph/ACLK] [get_bd_pins microblaze_axi_periph/M00_ACLK] [get_bd_pins microblaze_axi_periph/M01_ACLK] [get_bd_pins microblaze_axi_periph/M02_ACLK] [get_bd_pins microblaze_axi_periph/M03_ACLK] [get_bd_pins microblaze_axi_periph/M04_ACLK] [get_bd_pins microblaze_axi_periph/S00_ACLK] [get_bd_pins rst_clk_wiz_1_100M/slowest_sync_clk] + connect_bd_net -net reset_1 [get_bd_ports reset] [get_bd_pins rst_clk_wiz_1_100M/aux_reset_in] [get_bd_pins rst_clk_wiz_1_100M/ext_reset_in] + connect_bd_net -net rst_clk_wiz_1_100M_bus_struct_reset [get_bd_pins microblaze_0_local_memory/SYS_Rst] [get_bd_pins rst_clk_wiz_1_100M/bus_struct_reset] + connect_bd_net -net rst_clk_wiz_1_100M_interconnect_aresetn [get_bd_pins microblaze_axi_periph/ARESETN] [get_bd_pins rst_clk_wiz_1_100M/interconnect_aresetn] + connect_bd_net -net rst_clk_wiz_1_100M_mb_reset [get_bd_pins axi_intc_0/processor_rst] [get_bd_pins microblaze_0/Reset] [get_bd_pins rst_clk_wiz_1_100M/mb_reset] + connect_bd_net -net rst_clk_wiz_1_100M_peripheral_aresetn [get_bd_pins axi_gpio_0/s_axi_aresetn] [get_bd_pins axi_intc_0/s_axi_aresetn] [get_bd_pins axi_timer_0/s_axi_aresetn] [get_bd_pins mdm_1/S_AXI_ARESETN] [get_bd_pins microblaze_axi_periph/M00_ARESETN] [get_bd_pins microblaze_axi_periph/M01_ARESETN] [get_bd_pins microblaze_axi_periph/M02_ARESETN] [get_bd_pins microblaze_axi_periph/M03_ARESETN] [get_bd_pins microblaze_axi_periph/M04_ARESETN] [get_bd_pins microblaze_axi_periph/S00_ARESETN] [get_bd_pins rst_clk_wiz_1_100M/peripheral_aresetn] + connect_bd_net -net xlconcat_0_dout [get_bd_pins axi_intc_0/intr] [get_bd_pins xlconcat_0/dout] + + # Create address segments + assign_bd_address -offset 0x80000000 -range 0x80000000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs M_AXI_DP/Reg] -force + assign_bd_address -offset 0x00040000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_gpio_0/S_AXI/Reg] -force + assign_bd_address -offset 0x00010000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_intc_0/S_AXI/Reg] -force + assign_bd_address -offset 0x00020000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs axi_timer_0/S_AXI/Reg] -force + assign_bd_address -offset 0x00000000 -range 0x00008000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs microblaze_0_local_memory/dlmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x00000000 -range 0x00008000 -target_address_space [get_bd_addr_spaces microblaze_0/Instruction] [get_bd_addr_segs microblaze_0_local_memory/ilmb_bram_if_cntlr/SLMB/Mem] -force + assign_bd_address -offset 0x00030000 -range 0x00010000 -target_address_space [get_bd_addr_spaces microblaze_0/Data] [get_bd_addr_segs mdm_1/S_AXI/Reg] -force + + + # Restore current instance + current_bd_instance $oldCurInst + + validate_bd_design + save_bd_design +} +# End of create_root_design() + + +################################################################## +# MAIN FLOW +################################################################## + +create_root_design "" + + diff --git a/xilinx/general/microblaze/ruckus.tcl b/xilinx/general/microblaze/ruckus.tcl index 748eda01f7..9fda5c785c 100644 --- a/xilinx/general/microblaze/ruckus.tcl +++ b/xilinx/general/microblaze/ruckus.tcl @@ -20,13 +20,17 @@ if { [info exists ::env(VITIS_SRC_PATH)] != 1 } { # Load the .bd file if { $::env(VIVADO_VERSION) >= 2021.1 } { - loadBlockDesign -path "$::DIR_PATH/bd/2021.1/MicroblazeBasicCore.bd" + loadBlockDesign -path "$::DIR_PATH/bd/2021.1/MicroblazeBasicCore.tcl" # Word around for the locked IPs - open_bd_design [get_bd_designs MicroblazeBasicCore] - upgrade_ip [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -log ip_upgrade.log - export_ip_user_files -of_objects [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -no_script -sync -force -quiet - close_bd_design [get_bd_designs MicroblazeBasicCore] + # VivadoRefresh $::env(VIVADO_PROJECT) + # update_compile_order -fileset sources_1 + # open_bd_design [get_files {MicroblazeBasicCore.bd}] + # report_ip_status + # upgrade_ip [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -log ip_upgrade.log + # export_ip_user_files -of_objects [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -no_script -sync -force -quiet + # close_bd_design [get_bd_designs MicroblazeBasicCore] + # GenerateBdWrappers } else { loadBlockDesign -path "$::DIR_PATH/bd/2020.1/MicroblazeBasicCore.bd" From a3f26a3ea15e8f44074018cec8c83b257e464c70 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 15 Aug 2024 15:58:51 -0700 Subject: [PATCH 07/43] bug fix for microblaze/bd/2021.1 --- xilinx/general/microblaze/ruckus.tcl | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/xilinx/general/microblaze/ruckus.tcl b/xilinx/general/microblaze/ruckus.tcl index 9fda5c785c..6e8f27322b 100644 --- a/xilinx/general/microblaze/ruckus.tcl +++ b/xilinx/general/microblaze/ruckus.tcl @@ -21,17 +21,6 @@ if { [info exists ::env(VITIS_SRC_PATH)] != 1 } { # Load the .bd file if { $::env(VIVADO_VERSION) >= 2021.1 } { loadBlockDesign -path "$::DIR_PATH/bd/2021.1/MicroblazeBasicCore.tcl" - - # Word around for the locked IPs - # VivadoRefresh $::env(VIVADO_PROJECT) - # update_compile_order -fileset sources_1 - # open_bd_design [get_files {MicroblazeBasicCore.bd}] - # report_ip_status - # upgrade_ip [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -log ip_upgrade.log - # export_ip_user_files -of_objects [get_ips {MicroblazeBasicCore_rst_clk_wiz_1_100M_0 MicroblazeBasicCore_axi_gpio_0_0}] -no_script -sync -force -quiet - # close_bd_design [get_bd_designs MicroblazeBasicCore] - # GenerateBdWrappers - } else { loadBlockDesign -path "$::DIR_PATH/bd/2020.1/MicroblazeBasicCore.bd" } From 11a7628a8c835d372f1e4ec8beefb3bc0b4e9486 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:23:47 -0700 Subject: [PATCH 08/43] copying src from FilMarini:surf:roce fork --- axi/axi-stream/rtl/AxiStreamCompact.vhd | 265 ++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 axi/axi-stream/rtl/AxiStreamCompact.vhd diff --git a/axi/axi-stream/rtl/AxiStreamCompact.vhd b/axi/axi-stream/rtl/AxiStreamCompact.vhd new file mode 100644 index 0000000000..bb094b4d07 --- /dev/null +++ b/axi/axi-stream/rtl/AxiStreamCompact.vhd @@ -0,0 +1,265 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: +-- Block to compact AXI-Streams if tKeep bits are not contiguous +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +-- use ieee.std_logic_arith.all; +use ieee.numeric_std.all; + + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; + +entity AxiStreamCompact is + + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + SLAVE_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_AXI_CONFIG_G : AxiStreamConfigType); + port ( + axisClk : in sl; + axisRst : in sl; + -- is it a RoCE transmission? + isRoCE : in sl; + -- Slave Port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Master Port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); +end entity AxiStreamCompact; + +architecture rtl of AxiStreamCompact is + + function getTKeepMin ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in 0 to axisConfig.TDATA_BYTES_C-1 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMin; + + function getTKeepMax ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMax; + + constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; + constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + -- count : slv(bitSize(MST_BYTES_C)-1 downto 0); + count : natural; + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + tLastDet : boolean; + tLastOnNext : boolean; + tUserSet : boolean; + fullBus : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + -- count => (others => '0'), + count => 0, + obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + tLastDet => false, + tLastOnNext => false, + tUserSet => false, + fullBus => false + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; + +begin -- architecture rtl + + -- Make sure data widths are the same + assert (MST_BYTES_C >= SLV_BYTES_C) + report "Master data widths must be greater or equal than slave" severity failure; + + comb : process (pipeAxisSlave, r, sAxisMaster) is + variable v : RegType; + variable tKeepMin : natural; + variable tKeepWidth : natural; + variable tDataWidth : natural; + variable tDataMin : natural; + variable tDataCount : natural; + variable tDataVar : slv(sAxisMaster.tData'range); + begin -- process + -- Latch current value + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + v.fullBus := false; + v.tLastDet := false; + v.tLastOnNext := false; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + + -- Accept input data + if v.obMaster.tValid = '0' and not r.tLastOnNext then + + -- Ready to accept + v.ibSlave.tReady := '1'; + + -- Input data is valid + if sAxisMaster.tValid = '1' then + + -- get tKeet boundaries + tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); + tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); + tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); + + -- Checks + -- -- Overflow + if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then + v.fullBus := true; + end if; + -- -- tLast + v.tLastDet := false; + -- v.tLastDet := r.tLastOnNext; + if sAxisMaster.tLast = '1' then + v.tLastDet := true; + if tKeepWidth + r.count > MST_BYTES_C then + v.tLastDet := false; + v.tLastOnNext := true; + end if; + end if; + + -- Gen bus + -- Shift if bus was full + if r.fullBus and not r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + end if; + ---- Remove initial bits + tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); + v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); + v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); + if not r.tUserSet then + v.obMaster.tUser := sAxisMaster.tUser; + v.tUserSet := true; + end if; + + -- Update counter + v.count := r.count + tKeepWidth; + + end if; + end if; + + -- Bus is full + if v.fullBus or v.tLastDet or r.tLastOnNext then + -- Set tValid + v.obMaster.tValid := '1'; + -- Update bit counter and shift data + if v.fullBus then + v.count := r.count + tKeepWidth - MST_BYTES_C; + else + v.count := 0; + end if; + -- Set tLast + if v.tLastDet and not v.tLastOnNext then + v.obMaster.tLast := '1'; + else + v.obMaster.tLast := '0'; + end if; + -- Set tData in case of forced tLast + if r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); + v.obMaster.tLast := '1'; + end if; + v.tUserSet := false; + end if; + + sAxisSlave <= v.ibSlave; + pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); + pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); + pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); + pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); + pipeAxisMaster.tValid <= r.obMaster.tValid; + pipeAxisMaster.tUser <= r.obMaster.tUser; + pipeAxisMaster.tLast <= r.obMaster.tLast; + + rin <= v; + + + end process comb; + + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if ((RST_ASYNC_G = false) and (axisRst = '1')) or (isRoCE = '0') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); + + +end architecture rtl; From 3df82f7d686bdfb0ed4808f1461538135e034ab4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:32:51 -0700 Subject: [PATCH 09/43] copying src from FilMarini:surf:roce fork --- axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd diff --git a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd new file mode 100644 index 0000000000..879364ca2c --- /dev/null +++ b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd @@ -0,0 +1,156 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: +-- Append slv and the end and AXI-Stream package +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; + +entity AxiStreamTrailerAppend is + + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + TRAILER_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_SLAVE_AXI_CONFIG_G : AxiStreamConfigType); + port ( + axisClk : in sl; + axisRst : in sl; + -- Slave port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Trailer data + sAxisTrailerMaster : in AxiStreamMasterType; + sAxisTrailerSlave : out AxiStreamSlaveType; + -- Master port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); +end entity AxiStreamTrailerAppend; + +architecture rtl of AxiStreamTrailerAppend is + + type RegType is record + obMaster : AxiStreamMasterType; + ibSlaves : AxiStreamSlaveArray(1 downto 0); + sel : sl; + end record RegType; + + constant REG_INIT_C : RegType := ( + obMaster => axiStreamMasterInit(MASTER_SLAVE_AXI_CONFIG_G), + ibSlaves => (others => AXI_STREAM_SLAVE_INIT_C), + sel => '0' + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; + +begin -- architecture rtl + + -- Make sure data widths are apropriate + assert (MASTER_SLAVE_AXI_CONFIG_G.TDATA_BYTES_C >= TRAILER_AXI_CONFIG_G.TDATA_BYTES_C) + report "Trailer data widths must be less or equal than axi-stream" severity failure; + + comb : process (pipeAxisSlave, r, sAxisMaster, sAxisTrailerMaster) is + variable v : RegType; + variable ibM : AxiStreamMasterType; + begin -- process comb + v := r; + + -- Init ready + for i in 0 to 1 loop + v.ibSlaves(i).tReady := '0'; + end loop; -- i + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + + if v.obMaster.tValid = '0' then + -- Get inbound data + if r.sel = '0' then + ibM := sAxisMaster; + v.ibSlaves(0).tReady := '1'; + v.ibSlaves(1).tReady := '0'; + else + ibM := sAxisTrailerMaster; + v.ibSlaves(1).tReady := '1'; + v.ibSlaves(0).tReady := '0'; + end if; + + -- Mirror data until tLast + if ibM.tValid = '1' then + v.obMaster := ibM; + if ibM.tLast = '1' then + v.sel := not r.sel; + if r.sel = '0' then + v.obMaster.tLast := '0'; + else + -- tKeep workaround + v.obMaster.tKeep(v.obMaster.tKeep'length-1 downto 0) := (others => '0'); + v.obMaster.tKeep(TRAILER_AXI_CONFIG_G.TDATA_BYTES_C-1 downto 0) := (others => '1'); + end if; + end if; + end if; + + end if; + + sAxisSlave <= v.ibSlaves(0); + sAxisTrailerSlave <= v.ibSlaves(1); + pipeAxisMaster <= r.obMaster; + + rin <= v; + + end process comb; + + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if (RST_ASYNC_G = false) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); + + +end architecture rtl; From 04fb1a5fb1e31460b3da3059012c2b44ce080af5 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:39:50 -0700 Subject: [PATCH 10/43] emacs VHDL beautify --- axi/axi-stream/rtl/AxiStreamCompact.vhd | 451 ++++++++++++------------ 1 file changed, 225 insertions(+), 226 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamCompact.vhd b/axi/axi-stream/rtl/AxiStreamCompact.vhd index bb094b4d07..3a5136eaae 100644 --- a/axi/axi-stream/rtl/AxiStreamCompact.vhd +++ b/axi/axi-stream/rtl/AxiStreamCompact.vhd @@ -12,254 +12,253 @@ -- may be copied, modified, propagated, or distributed except according to -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- use ieee.std_logic_arith.all; use ieee.numeric_std.all; - library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; entity AxiStreamCompact is - generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - PIPE_STAGES_G : natural := 0; - SLAVE_AXI_CONFIG_G : AxiStreamConfigType; - MASTER_AXI_CONFIG_G : AxiStreamConfigType); - port ( - axisClk : in sl; - axisRst : in sl; - -- is it a RoCE transmission? - isRoCE : in sl; - -- Slave Port - sAxisMaster : in AxiStreamMasterType; - sAxisSlave : out AxiStreamSlaveType; - -- Master Port - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType); + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + SLAVE_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_AXI_CONFIG_G : AxiStreamConfigType); + port ( + axisClk : in sl; + axisRst : in sl; + -- is it a RoCE transmission? + isRoCE : in sl; + -- Slave Port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Master Port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamCompact; architecture rtl of AxiStreamCompact is - function getTKeepMin ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in 0 to axisConfig.TDATA_BYTES_C-1 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMin; - - function getTKeepMax ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMax; - - constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; - constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; - - type RegType is record - -- count : slv(bitSize(MST_BYTES_C)-1 downto 0); - count : natural; - obMaster : AxiStreamMasterType; - ibSlave : AxiStreamSlaveType; - tLastDet : boolean; - tLastOnNext : boolean; - tUserSet : boolean; - fullBus : boolean; - end record RegType; - - constant REG_INIT_C : RegType := ( - -- count => (others => '0'), - count => 0, - obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), - ibSlave => AXI_STREAM_SLAVE_INIT_C, - tLastDet => false, - tLastOnNext => false, - tUserSet => false, - fullBus => false - ); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal pipeAxisMaster : AxiStreamMasterType; - signal pipeAxisSlave : AxiStreamSlaveType; + function getTKeepMin ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in 0 to axisConfig.TDATA_BYTES_C-1 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMin; + + function getTKeepMax ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMax; + + constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; + constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + -- count : slv(bitSize(MST_BYTES_C)-1 downto 0); + count : natural; + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + tLastDet : boolean; + tLastOnNext : boolean; + tUserSet : boolean; + fullBus : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + -- count => (others => '0'), + count => 0, + obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + tLastDet => false, + tLastOnNext => false, + tUserSet => false, + fullBus => false + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; begin -- architecture rtl - -- Make sure data widths are the same - assert (MST_BYTES_C >= SLV_BYTES_C) - report "Master data widths must be greater or equal than slave" severity failure; - - comb : process (pipeAxisSlave, r, sAxisMaster) is - variable v : RegType; - variable tKeepMin : natural; - variable tKeepWidth : natural; - variable tDataWidth : natural; - variable tDataMin : natural; - variable tDataCount : natural; - variable tDataVar : slv(sAxisMaster.tData'range); - begin -- process - -- Latch current value - v := r; - - -- Init ready - v.ibSlave.tReady := '0'; - v.fullBus := false; - v.tLastDet := false; - v.tLastOnNext := false; - - -- Choose ready source and clear valid - if (pipeAxisSlave.tReady = '1') then - v.obMaster.tValid := '0'; - end if; - - -- Accept input data - if v.obMaster.tValid = '0' and not r.tLastOnNext then - - -- Ready to accept - v.ibSlave.tReady := '1'; - - -- Input data is valid - if sAxisMaster.tValid = '1' then - - -- get tKeet boundaries - tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); - tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); - tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); - - -- Checks - -- -- Overflow - if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then - v.fullBus := true; - end if; - -- -- tLast - v.tLastDet := false; - -- v.tLastDet := r.tLastOnNext; - if sAxisMaster.tLast = '1' then - v.tLastDet := true; - if tKeepWidth + r.count > MST_BYTES_C then - v.tLastDet := false; - v.tLastOnNext := true; - end if; - end if; - - -- Gen bus - -- Shift if bus was full - if r.fullBus and not r.tLastOnNext then - v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); - end if; - ---- Remove initial bits - tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); - v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); - v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); - v.obMaster.tKeep := (others => '0'); - v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); - if not r.tUserSet then - v.obMaster.tUser := sAxisMaster.tUser; - v.tUserSet := true; - end if; - - -- Update counter - v.count := r.count + tKeepWidth; - + -- Make sure data widths are the same + assert (MST_BYTES_C >= SLV_BYTES_C) + report "Master data widths must be greater or equal than slave" severity failure; + + comb : process (pipeAxisSlave, r, sAxisMaster) is + variable v : RegType; + variable tKeepMin : natural; + variable tKeepWidth : natural; + variable tDataWidth : natural; + variable tDataMin : natural; + variable tDataCount : natural; + variable tDataVar : slv(sAxisMaster.tData'range); + begin -- process + -- Latch current value + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + v.fullBus := false; + v.tLastDet := false; + v.tLastOnNext := false; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; end if; - end if; - - -- Bus is full - if v.fullBus or v.tLastDet or r.tLastOnNext then - -- Set tValid - v.obMaster.tValid := '1'; - -- Update bit counter and shift data - if v.fullBus then - v.count := r.count + tKeepWidth - MST_BYTES_C; - else - v.count := 0; - end if; - -- Set tLast - if v.tLastDet and not v.tLastOnNext then - v.obMaster.tLast := '1'; - else - v.obMaster.tLast := '0'; - end if; - -- Set tData in case of forced tLast - if r.tLastOnNext then - v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); - v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); - v.obMaster.tLast := '1'; + + -- Accept input data + if v.obMaster.tValid = '0' and not r.tLastOnNext then + + -- Ready to accept + v.ibSlave.tReady := '1'; + + -- Input data is valid + if sAxisMaster.tValid = '1' then + + -- get tKeet boundaries + tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); + tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); + tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); + + -- Checks + -- -- Overflow + if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then + v.fullBus := true; + end if; + -- -- tLast + v.tLastDet := false; + -- v.tLastDet := r.tLastOnNext; + if sAxisMaster.tLast = '1' then + v.tLastDet := true; + if tKeepWidth + r.count > MST_BYTES_C then + v.tLastDet := false; + v.tLastOnNext := true; + end if; + end if; + + -- Gen bus + -- Shift if bus was full + if r.fullBus and not r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + end if; + ---- Remove initial bits + tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); + v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); + v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); + if not r.tUserSet then + v.obMaster.tUser := sAxisMaster.tUser; + v.tUserSet := true; + end if; + + -- Update counter + v.count := r.count + tKeepWidth; + + end if; end if; - v.tUserSet := false; - end if; - - sAxisSlave <= v.ibSlave; - pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); - pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); - pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); - pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); - pipeAxisMaster.tValid <= r.obMaster.tValid; - pipeAxisMaster.tUser <= r.obMaster.tUser; - pipeAxisMaster.tLast <= r.obMaster.tLast; - - rin <= v; - - - end process comb; - - seq : process (axisClk, axisRst) is - begin - if (RST_ASYNC_G) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if ((RST_ASYNC_G = false) and (axisRst = '1')) or (isRoCE = '0') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; + + -- Bus is full + if v.fullBus or v.tLastDet or r.tLastOnNext then + -- Set tValid + v.obMaster.tValid := '1'; + -- Update bit counter and shift data + if v.fullBus then + v.count := r.count + tKeepWidth - MST_BYTES_C; + else + v.count := 0; + end if; + -- Set tLast + if v.tLastDet and not v.tLastOnNext then + v.obMaster.tLast := '1'; + else + v.obMaster.tLast := '0'; + end if; + -- Set tData in case of forced tLast + if r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); + v.obMaster.tLast := '1'; + end if; + v.tUserSet := false; end if; - end if; - end process seq; - - -- Optional output pipeline registers to ease timing - AxiStreamPipeline_1 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => PIPE_STAGES_G) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, - sAxisSlave => pipeAxisSlave, - mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, - mAxisSlave => mAxisSlave); + sAxisSlave <= v.ibSlave; + pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); + pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); + pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); + pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); + pipeAxisMaster.tValid <= r.obMaster.tValid; + pipeAxisMaster.tUser <= r.obMaster.tUser; + pipeAxisMaster.tLast <= r.obMaster.tLast; + + rin <= v; + + + end process comb; + + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if ((RST_ASYNC_G = false) and (axisRst = '1')) or (isRoCE = '0') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); end architecture rtl; From 00ebb0500fa68ac4180aa9b5ad198e9a4e564518 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:49:29 -0700 Subject: [PATCH 11/43] removing isRoCE port (application specific) and switch to standard reset convention --- axi/axi-stream/rtl/AxiStreamCompact.vhd | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamCompact.vhd b/axi/axi-stream/rtl/AxiStreamCompact.vhd index 3a5136eaae..c71c6223a1 100644 --- a/axi/axi-stream/rtl/AxiStreamCompact.vhd +++ b/axi/axi-stream/rtl/AxiStreamCompact.vhd @@ -32,10 +32,9 @@ entity AxiStreamCompact is SLAVE_AXI_CONFIG_G : AxiStreamConfigType; MASTER_AXI_CONFIG_G : AxiStreamConfigType); port ( + -- Clock and Reset axisClk : in sl; axisRst : in sl; - -- is it a RoCE transmission? - isRoCE : in sl; -- Slave Port sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; @@ -115,7 +114,7 @@ begin -- architecture rtl assert (MST_BYTES_C >= SLV_BYTES_C) report "Master data widths must be greater or equal than slave" severity failure; - comb : process (pipeAxisSlave, r, sAxisMaster) is + comb : process (axisRst, pipeAxisSlave, r, sAxisMaster) is variable v : RegType; variable tKeepMin : natural; variable tKeepWidth : natural; @@ -217,6 +216,7 @@ begin -- architecture rtl v.tUserSet := false; end if; + -- Outputs sAxisSlave <= v.ibSlave; pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); @@ -226,8 +226,13 @@ begin -- architecture rtl pipeAxisMaster.tUser <= r.obMaster.tUser; pipeAxisMaster.tLast <= r.obMaster.tLast; - rin <= v; + -- Reset + if (RST_ASYNC_G = false and axisRst = '1') then + v := REG_INIT_C; + end if; + -- Register the variable for next clock cycle + rin <= v; end process comb; @@ -235,12 +240,8 @@ begin -- architecture rtl begin if (RST_ASYNC_G) and (axisRst = '1') then r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if ((RST_ASYNC_G = false) and (axisRst = '1')) or (isRoCE = '0') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; - end if; + elsif rising_edge(axisClk) then + r <= rin after TPD_G; end if; end process seq; From 3549aa907bea5b540c28e7bcc777229ff8228e0b Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:53:12 -0700 Subject: [PATCH 12/43] emacs VHDL beautify --- axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd | 224 +++++++++--------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd index 879364ca2c..f9cc9ce6e0 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd @@ -12,6 +12,7 @@ -- may be copied, modified, propagated, or distributed except according to -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; @@ -22,135 +23,134 @@ use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; entity AxiStreamTrailerAppend is - - generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - PIPE_STAGES_G : natural := 0; - TRAILER_AXI_CONFIG_G : AxiStreamConfigType; - MASTER_SLAVE_AXI_CONFIG_G : AxiStreamConfigType); - port ( - axisClk : in sl; - axisRst : in sl; - -- Slave port - sAxisMaster : in AxiStreamMasterType; - sAxisSlave : out AxiStreamSlaveType; - -- Trailer data - sAxisTrailerMaster : in AxiStreamMasterType; - sAxisTrailerSlave : out AxiStreamSlaveType; - -- Master port - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType); + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + TRAILER_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_SLAVE_AXI_CONFIG_G : AxiStreamConfigType); + port ( + -- Clock and Reset + axisClk : in sl; + axisRst : in sl; + -- Slave port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Trailer data + sAxisTrailerMaster : in AxiStreamMasterType; + sAxisTrailerSlave : out AxiStreamSlaveType; + -- Master port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamTrailerAppend; architecture rtl of AxiStreamTrailerAppend is - type RegType is record - obMaster : AxiStreamMasterType; - ibSlaves : AxiStreamSlaveArray(1 downto 0); - sel : sl; - end record RegType; + type RegType is record + obMaster : AxiStreamMasterType; + ibSlaves : AxiStreamSlaveArray(1 downto 0); + sel : sl; + end record RegType; - constant REG_INIT_C : RegType := ( - obMaster => axiStreamMasterInit(MASTER_SLAVE_AXI_CONFIG_G), - ibSlaves => (others => AXI_STREAM_SLAVE_INIT_C), - sel => '0' - ); + constant REG_INIT_C : RegType := ( + obMaster => axiStreamMasterInit(MASTER_SLAVE_AXI_CONFIG_G), + ibSlaves => (others => AXI_STREAM_SLAVE_INIT_C), + sel => '0' + ); - signal r : RegType := REG_INIT_C; - signal rin : RegType; + signal r : RegType := REG_INIT_C; + signal rin : RegType; - signal pipeAxisMaster : AxiStreamMasterType; - signal pipeAxisSlave : AxiStreamSlaveType; + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; begin -- architecture rtl - -- Make sure data widths are apropriate - assert (MASTER_SLAVE_AXI_CONFIG_G.TDATA_BYTES_C >= TRAILER_AXI_CONFIG_G.TDATA_BYTES_C) - report "Trailer data widths must be less or equal than axi-stream" severity failure; - - comb : process (pipeAxisSlave, r, sAxisMaster, sAxisTrailerMaster) is - variable v : RegType; - variable ibM : AxiStreamMasterType; - begin -- process comb - v := r; - - -- Init ready - for i in 0 to 1 loop - v.ibSlaves(i).tReady := '0'; - end loop; -- i - - -- Choose ready source and clear valid - if (pipeAxisSlave.tReady = '1') then - v.obMaster.tValid := '0'; - end if; - - if v.obMaster.tValid = '0' then - -- Get inbound data - if r.sel = '0' then - ibM := sAxisMaster; - v.ibSlaves(0).tReady := '1'; - v.ibSlaves(1).tReady := '0'; - else - ibM := sAxisTrailerMaster; - v.ibSlaves(1).tReady := '1'; - v.ibSlaves(0).tReady := '0'; - end if; + -- Make sure data widths are appropriate + assert (MASTER_SLAVE_AXI_CONFIG_G.TDATA_BYTES_C >= TRAILER_AXI_CONFIG_G.TDATA_BYTES_C) + report "Trailer data widths must be less or equal than axi-stream" severity failure; + + comb : process (pipeAxisSlave, r, sAxisMaster, sAxisTrailerMaster) is + variable v : RegType; + variable ibM : AxiStreamMasterType; + begin -- process comb + v := r; - -- Mirror data until tLast - if ibM.tValid = '1' then - v.obMaster := ibM; - if ibM.tLast = '1' then - v.sel := not r.sel; - if r.sel = '0' then - v.obMaster.tLast := '0'; - else - -- tKeep workaround - v.obMaster.tKeep(v.obMaster.tKeep'length-1 downto 0) := (others => '0'); - v.obMaster.tKeep(TRAILER_AXI_CONFIG_G.TDATA_BYTES_C-1 downto 0) := (others => '1'); - end if; - end if; + -- Init ready + for i in 0 to 1 loop + v.ibSlaves(i).tReady := '0'; + end loop; -- i + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; end if; - end if; + if v.obMaster.tValid = '0' then + -- Get inbound data + if r.sel = '0' then + ibM := sAxisMaster; + v.ibSlaves(0).tReady := '1'; + v.ibSlaves(1).tReady := '0'; + else + ibM := sAxisTrailerMaster; + v.ibSlaves(1).tReady := '1'; + v.ibSlaves(0).tReady := '0'; + end if; + + -- Mirror data until tLast + if ibM.tValid = '1' then + v.obMaster := ibM; + if ibM.tLast = '1' then + v.sel := not r.sel; + if r.sel = '0' then + v.obMaster.tLast := '0'; + else + -- tKeep workaround + v.obMaster.tKeep(v.obMaster.tKeep'length-1 downto 0) := (others => '0'); + v.obMaster.tKeep(TRAILER_AXI_CONFIG_G.TDATA_BYTES_C-1 downto 0) := (others => '1'); + end if; + end if; + end if; + + end if; - sAxisSlave <= v.ibSlaves(0); - sAxisTrailerSlave <= v.ibSlaves(1); - pipeAxisMaster <= r.obMaster; + sAxisSlave <= v.ibSlaves(0); + sAxisTrailerSlave <= v.ibSlaves(1); + pipeAxisMaster <= r.obMaster; - rin <= v; + rin <= v; - end process comb; + end process comb; - seq : process (axisClk, axisRst) is - begin - if (RST_ASYNC_G) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if (RST_ASYNC_G = false) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; end if; - end if; - end process seq; - - -- Optional output pipeline registers to ease timing - AxiStreamPipeline_1 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => PIPE_STAGES_G) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, - sAxisSlave => pipeAxisSlave, - mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, - mAxisSlave => mAxisSlave); - + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); end architecture rtl; From afca65594982c9cc5d608cd6a21a4a3206c242a4 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 23 Aug 2024 13:54:56 -0700 Subject: [PATCH 13/43] removing isRoCE port (application specific) and switch to standard reset convention --- axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd index f9cc9ce6e0..273a9a2042 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd @@ -70,7 +70,7 @@ begin -- architecture rtl assert (MASTER_SLAVE_AXI_CONFIG_G.TDATA_BYTES_C >= TRAILER_AXI_CONFIG_G.TDATA_BYTES_C) report "Trailer data widths must be less or equal than axi-stream" severity failure; - comb : process (pipeAxisSlave, r, sAxisMaster, sAxisTrailerMaster) is + comb : process (axisRst, pipeAxisSlave, r, sAxisMaster, sAxisTrailerMaster) is variable v : RegType; variable ibM : AxiStreamMasterType; begin -- process comb @@ -115,10 +115,17 @@ begin -- architecture rtl end if; + -- Outputs sAxisSlave <= v.ibSlaves(0); sAxisTrailerSlave <= v.ibSlaves(1); pipeAxisMaster <= r.obMaster; + -- Reset + if (RST_ASYNC_G = false and axisRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle rin <= v; end process comb; @@ -127,12 +134,8 @@ begin -- architecture rtl begin if (RST_ASYNC_G) and (axisRst = '1') then r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; - end if; + elsif rising_edge(axisClk) then + r <= rin after TPD_G; end if; end process seq; From e6cfae8fb07cf7ea13f9b59185a58fed825f437d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 26 Aug 2024 11:51:25 -0700 Subject: [PATCH 14/43] Remove variables from configuration --- python/surf/axi/_AxiVersion.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index 33c3f32f43..573df47cbd 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -89,6 +89,7 @@ def parseUpTime(var,read): self.add(pr.RemoteVariable( name = 'FpgaReloadHalt', description = 'Used to halt automatic reloads via AxiVersion', + groups = ['NoConfig'] offset = 0x100, bitSize = 1, bitOffset = 0x00, @@ -127,6 +128,7 @@ def FpgaReloadAtAddress(arg): self.add(pr.RemoteVariable( name = 'UserReset', description = 'Optional User Reset', + groups = ['NoConfig'], hidden = True, offset = 0x10C, bitSize = 1, From 853d681a4282dde36c11af47a853528787dbea30 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Mon, 26 Aug 2024 14:14:00 -0700 Subject: [PATCH 15/43] Fix syntax error --- python/surf/axi/_AxiVersion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/surf/axi/_AxiVersion.py b/python/surf/axi/_AxiVersion.py index 573df47cbd..6cc0cb1cbb 100644 --- a/python/surf/axi/_AxiVersion.py +++ b/python/surf/axi/_AxiVersion.py @@ -89,7 +89,7 @@ def parseUpTime(var,read): self.add(pr.RemoteVariable( name = 'FpgaReloadHalt', description = 'Used to halt automatic reloads via AxiVersion', - groups = ['NoConfig'] + groups = ['NoConfig'], offset = 0x100, bitSize = 1, bitOffset = 0x00, From c1b2c199df7cd0167fdb9ab3058949b79ba326e5 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 09:55:26 -0700 Subject: [PATCH 16/43] Add testbench --- protocols/saci/rtl/SaciAxiLiteMaster.vhd | 6 +- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 179 ++++++++++++++ tests/test_SaciAxiLiteMaster.py | 264 +++++++++++++++++++++ 3 files changed, 446 insertions(+), 3 deletions(-) create mode 100644 protocols/saci/sim/SaciAxiLiteMasterTb.vhd create mode 100644 tests/test_SaciAxiLiteMaster.py diff --git a/protocols/saci/rtl/SaciAxiLiteMaster.vhd b/protocols/saci/rtl/SaciAxiLiteMaster.vhd index 2ee688c5ee..4f575e7501 100644 --- a/protocols/saci/rtl/SaciAxiLiteMaster.vhd +++ b/protocols/saci/rtl/SaciAxiLiteMaster.vhd @@ -25,7 +25,7 @@ use surf.StdRtlPkg.all; use surf.AxiLitePkg.all; use surf.SaciMasterPkg.all; -entity AxiLiteSaciMaster is +entity SaciAxiLiteMaster is generic ( TPD_G : time := 1 ns); port ( @@ -41,9 +41,9 @@ entity AxiLiteSaciMaster is axilReadSlave : out AxiLiteReadSlaveType; axilWriteMaster : in AxiLiteWriteMasterType; axilWriteSlave : out AxiLiteWriteSlaveType); -end AxiLiteSaciMaster; +end SaciAxiLiteMaster; -architecture rtl of AxiLiteSaciMaster is +architecture rtl of SaciAxiLiteMaster is -- AXI-Lite Master Interface signal axilReq : AxiLiteReqType; diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd new file mode 100644 index 0000000000..46051cd9a0 --- /dev/null +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -0,0 +1,179 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: surf.AxiLiteCrossbar cocoTB testbed +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; + +entity AxiLiteCrossbarTb is + port ( + -- AXI-Lite Interface + S_AXI_ACLK : in std_logic; + S_AXI_ARESETN : in std_logic; + S_AXI_AWADDR : in std_logic_vector(31 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(31 downto 0); + S_AXI_WSTRB : in std_logic_vector(3 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARADDR : in std_logic_vector(31 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RDATA : out std_logic_vector(31 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic); +end AxiLiteCrossbarTb; + +architecture mapping of AxiLiteCrossbarTb is + + signal fpgaAxilClk : sl; + signal fpgaAxilRst : sl; + + signal fpgaAxilReadMaster : AxiLiteReadMasterType; + signal fpgaAxilReadSlave : AxiLiteReadSlaveType; + signal fpgaAxilWriteMaster : AxiLiteWriteMasterType; + signal fpgaAxilWriteSlave : AxiLiteWriteSlaveType; + + signal asicAxilClk : sl; + signal asicAxilRst : sl; + + signal asicAxilReadMaster : AxiLiteReadMasterType; + signal asicAxilReadSlave : AxiLiteReadSlaveType; + signal asicAxilWriteMaster : AxiLiteWriteMasterType; + signal asicAxilWriteSlave : AxiLiteWriteSlaveType; + + signal saciClk : sl; + signal saciCmd : sl; + signal saciSelL : slv(0 downto 0); + signal saciRsp : slv(0 downto 0); + signal saciBusReq : sl; + signal saciBusGr : sl := '1'; + +begin + + U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator + generic map ( + EN_ERROR_RESP => true, + FREQ_HZ => 125000000, + ADDR_WIDTH => 32) + port map ( + -- IP Integrator AXI-Lite Interface + S_AXI_ACLK => S_AXI_ACLK, + S_AXI_ARESETN => S_AXI_ARESETN, + S_AXI_AWADDR => S_AXI_AWADDR, + S_AXI_AWPROT => S_AXI_AWPROT, + S_AXI_AWVALID => S_AXI_AWVALID, + S_AXI_AWREADY => S_AXI_AWREADY, + S_AXI_WDATA => S_AXI_WDATA, + S_AXI_WSTRB => S_AXI_WSTRB, + S_AXI_WVALID => S_AXI_WVALID, + S_AXI_WREADY => S_AXI_WREADY, + S_AXI_BRESP => S_AXI_BRESP, + S_AXI_BVALID => S_AXI_BVALID, + S_AXI_BREADY => S_AXI_BREADY, + S_AXI_ARADDR => S_AXI_ARADDR, + S_AXI_ARPROT => S_AXI_ARPROT, + S_AXI_ARVALID => S_AXI_ARVALID, + S_AXI_ARREADY => S_AXI_ARREADY, + S_AXI_RDATA => S_AXI_RDATA, + S_AXI_RRESP => S_AXI_RRESP, + S_AXI_RVALID => S_AXI_RVALID, + S_AXI_RREADY => S_AXI_RREADY, + -- SURF AXI-Lite Interface + axilClk => fpgaAxilClk, + axilRst => fpgaAxilRst, + axilReadMaster => fpgaAxilReadMaster, + axilReadSlave => fpgaAxilReadSlave, + axilWriteMaster => fpgaAxilWriteMaster, + axilWriteSlave => fpgaAxilWriteSlave); + + ------------------------------------------------------------------------------------------------- + -- FPGA Side + ------------------------------------------------------------------------------------------------- + U_AxiLiteSaciMaster_1 : entity surf.AxiLiteSaciMaster + generic map ( + TPD_G => TPD_G, + AXIL_CLK_PERIOD_G => 125.0e6, +-- AXIL_TIMEOUT_G => AXIL_TIMEOUT_G, + SACI_CLK_PERIOD_G => 1.0e6, + SACI_CLK_FREERUN_G => false, + SACI_NUM_CHIPS_G => 1, + SACI_RSP_BUSSED_G => false) + port map ( + saciClk => saciClk, -- [out] + saciCmd => saciCmd, -- [out] + saciSelL => saciSelL, -- [out] + saciRsp => saciRsp, -- [in] + saciBusReq => saciBusReq, -- [out] + saciBusGr => saciBusGr, -- [in] + axilClk => fpgaAxilClk, -- [in] + axilRst => fpgaAxilRst, -- [in] + axilReadMaster => fpgaAxilReadMaster, -- [in] + axilReadSlave => fpgaAxilReadSlave, -- [out] + axilWriteMaster => fpgaAxilWriteMaster, -- [in] + axilWriteSlave => fpgaAxilWriteSlave); -- [out] + + ------------------------------------------------------------------------------------------------- + -- ASIC side + ------------------------------------------------------------------------------------------------- + U_ClkRst_1 : entity surf.ClkRst + generic map ( + CLK_PERIOD_G => 8.0 ns) + port map ( + clkP => asicAxilClk, -- [out] + rst => asicAxilRst) -- [out] + + U_SaciAxiLiteMaster_1 : entity surf.SaciAxiLiteMaster + generic map ( + TPD_G => TPD_G) + port map ( + saciClk => saciClk, -- [in] + saciCmd => saciCmd, -- [in] + saciSelL => saciSelL, -- [in] + saciRsp => saciRsp(0), -- [out] + axilClk => asicAxilClk, -- [in] + axilRst => asicAxilRst, -- [in] + axilReadMaster => asicAxilReadMaster, -- [in] + axilReadSlave => asicAxilReadSlave, -- [out] + axilWriteMaster => asicAxilWriteMaster, -- [in] + axilWriteSlave => asicAxilWriteSlave); -- [out] + + + U_MEM : entity surf.AxiDualPortRam + generic map ( + ADDR_WIDTH_G => 22, + DATA_WIDTH_G => 32) + port map ( + -- Axi Port + axiClk => asicAxilClk, + axiRst => asicAxilRst, + axiReadMaster => asicAxilReadMasters, + axiReadSlave => asicAxilReadSlaves, + axiWriteMaster => asicAxilWriteMasters, + axiWriteSlave => asicAxilWriteSlaves); + + +end mapping; diff --git a/tests/test_SaciAxiLiteMaster.py b/tests/test_SaciAxiLiteMaster.py new file mode 100644 index 0000000000..184858d15f --- /dev/null +++ b/tests/test_SaciAxiLiteMaster.py @@ -0,0 +1,264 @@ +############################################################################## +## This file is part of 'SLAC Firmware Standard Library'. +## It is subject to the license terms in the LICENSE.txt file found in the +## top-level directory of this distribution and at: +## https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +## No part of 'SLAC Firmware Standard Library', including this file, +## may be copied, modified, propagated, or distributed except according to +## the terms contained in the LICENSE.txt file. +############################################################################## + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge, Timer +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiLiteBus, AxiLiteMaster + +# test_AxiLiteCrossbarTb +from cocotb_test.simulator import run +import pytest +import glob +import os +import itertools +import logging +import random + +class TB: + def __init__(self, dut): + + # Pointer to DUT object + self.dut = dut + + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + # Start clock (125 MHz) in a separate thread + cocotb.start_soon(Clock(dut.S_AXI_ACLK, 8.0, units='ns').start()) + + # Create the AXI-Lite Master + self.axil_master = AxiLiteMaster( + bus = AxiLiteBus.from_prefix(dut, 'S_AXI'), + clock = dut.S_AXI_ACLK, + reset = dut.S_AXI_ARESETN, + reset_active_level=False) + + def set_idle_generator(self, generator=None): + if generator: + self.axil_master.write_if.aw_channel.set_pause_generator(generator()) + self.axil_master.write_if.w_channel.set_pause_generator(generator()) + self.axil_master.read_if.ar_channel.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.axil_master.write_if.b_channel.set_pause_generator(generator()) + self.axil_master.read_if.r_channel.set_pause_generator(generator()) + + async def cycle_reset(self): + self.dut.S_AXI_ARESETN.setimmediatevalue(0) + await RisingEdge(self.dut.S_AXI_ACLK) + await RisingEdge(self.dut.S_AXI_ACLK) + self.dut.S_AXI_ARESETN.value = 0 + await RisingEdge(self.dut.S_AXI_ACLK) + await RisingEdge(self.dut.S_AXI_ACLK) + self.dut.S_AXI_ARESETN.value = 1 + await RisingEdge(self.dut.S_AXI_ACLK) + await RisingEdge(self.dut.S_AXI_ACLK) + +async def run_test_bytes(dut, data_in=None, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + byte_lanes = tb.axil_master.write_if.byte_lanes + + await tb.cycle_reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + for length in range(1, byte_lanes*2): + for memDev in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: + for offset in range(byte_lanes): + addr = offset+memDev + tb.log.info( f'length={length},addr={hex(addr)}' ) + test_data = bytearray([x % 256 for x in range(length)]) + await tb.axil_master.write(addr, test_data) + data = await tb.axil_master.read(addr, length) + assert data.data == test_data + + await RisingEdge(dut.S_AXI_ACLK) + await RisingEdge(dut.S_AXI_ACLK) + + +async def run_test_words(dut): + + tb = TB(dut) + + byte_lanes = tb.axil_master.write_if.byte_lanes + + await tb.cycle_reset() + + for length in list(range(1, 4)): + for memDev in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: + for offset in list(range(byte_lanes)): + addr = offset + tb.log.info( f'length={length},addr={hex(addr)}' ) + + test_data = bytearray([x % 256 for x in range(length)]) + event = tb.axil_master.init_write(addr, test_data) + await event.wait() + event = tb.axil_master.init_read(addr, length) + await event.wait() + assert event.data.data == test_data + + test_data = bytearray([x % 256 for x in range(length)]) + await tb.axil_master.write(addr, test_data) + assert (await tb.axil_master.read(addr, length)).data == test_data + + test_data = [x * 0x1001 for x in range(length)] + await tb.axil_master.write_words(addr, test_data) + assert await tb.axil_master.read_words(addr, length) == test_data + + test_data = [x * 0x10200201 for x in range(length)] + await tb.axil_master.write_dwords(addr, test_data) + assert await tb.axil_master.read_dwords(addr, length) == test_data + + test_data = [x * 0x1020304004030201 for x in range(length)] + await tb.axil_master.write_qwords(addr, test_data) + assert await tb.axil_master.read_qwords(addr, length) == test_data + + test_data = 0x01*length + await tb.axil_master.write_byte(addr, test_data) + assert await tb.axil_master.read_byte(addr) == test_data + + test_data = 0x1001*length + await tb.axil_master.write_word(addr, test_data) + assert await tb.axil_master.read_word(addr) == test_data + + test_data = 0x10200201*length + await tb.axil_master.write_dword(addr, test_data) + assert await tb.axil_master.read_dword(addr) == test_data + + test_data = 0x1020304004030201*length + await tb.axil_master.write_qword(addr, test_data) + assert await tb.axil_master.read_qword(addr) == test_data + + await RisingEdge(dut.S_AXI_ACLK) + await RisingEdge(dut.S_AXI_ACLK) + +async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None): + + tb = TB(dut) + + await tb.cycle_reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + async def worker(master, offset, aperture, count=16): + for k in range(count): + length = random.randint(1, min(32, aperture)) + addr = offset+random.randint(0, aperture-length) + test_data = bytearray([x % 256 for x in range(length)]) + + await Timer(random.randint(1, 100), 'ns') + + await master.write(addr, test_data) + + await Timer(random.randint(1, 100), 'ns') + + data = await master.read(addr, length) + assert data.data == test_data + + workers = [] + + for k in [0x0000_0000,0x0010_2000,0x0016_0000]: + workers.append(cocotb.start_soon(worker(tb.axil_master, k, 0x1000, count=16))) + + while workers: + await workers.pop(0).join() + + await RisingEdge(dut.S_AXI_ACLK) + await RisingEdge(dut.S_AXI_ACLK) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +if cocotb.SIM_NAME: + + ################# + # run_test_bytes + ################# + factory = TestFactory(run_test_bytes) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.add_option("backpressure_inserter", [None, cycle_pause]) + factory.generate_tests() + + ################# + # run_test_words + ################# + factory = TestFactory(run_test_words) + factory.generate_tests() + + ################# + # run_stress_test + ################# + factory = TestFactory(run_stress_test) + factory.generate_tests() + +tests_dir = os.path.dirname(__file__) +tests_module = 'SaciAxiLiteMasterTb' + +############################################################################## + +@pytest.mark.parametrize( + "parameters", [ + None + ]) +def test_AxiLiteCrossbarTb(parameters): + + # https://github.com/themperek/cocotb-test#arguments-for-simulatorrun + # https://github.com/themperek/cocotb-test/blob/master/cocotb_test/simulator.py + run( + # top level HDL + toplevel = f'surf.{tests_module}'.lower(), + + # name of the file that contains @cocotb.test() -- this file + # https://docs.cocotb.org/en/stable/building.html?#envvar-MODULE + module = f'test_{tests_module}', + + # https://docs.cocotb.org/en/stable/building.html?#var-TOPLEVEL_LANG + toplevel_lang = 'vhdl', + + # VHDL source files to include. + # Can be specified as a list or as a dict of lists with the library name as key, + # if the simulator supports named libraries. + vhdl_sources = { + 'surf' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/surf/*'), + 'ruckus' : glob.glob(f'{tests_dir}/../build/SRC_VHDL/ruckus/*'), + }, + + # A dictionary of top-level parameters/generics. + parameters = parameters, + + # The directory used to compile the tests. (default: sim_build) + sim_build = f'{tests_dir}/sim_build/{tests_module}', + + # A dictionary of extra environment variables set in simulator process. + extra_env=parameters, + + # Select a simulator + simulator="ghdl", + + # use of synopsys package "std_logic_arith" needs the -fsynopsys option + # -frelaxed-rules option to allow IP integrator attributes + # When two operators are overloaded, give preference to the explicit declaration (-fexplicit) + vhdl_compile_args = ['-fsynopsys','-frelaxed-rules', '-fexplicit'], + + ######################################################################## + # Dump waveform to file ($ gtkwave sim_build/path/To/{tests_module}.ghw) + ######################################################################## + # sim_args =[f'--wave={tests_module}.ghw'], + ) From 559d568380bacd7f5f3cd782b35f38262c9e9235 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 09:56:59 -0700 Subject: [PATCH 17/43] Only test at 0x00000000 --- tests/test_SaciAxiLiteMaster.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_SaciAxiLiteMaster.py b/tests/test_SaciAxiLiteMaster.py index 184858d15f..386ea2a5fa 100644 --- a/tests/test_SaciAxiLiteMaster.py +++ b/tests/test_SaciAxiLiteMaster.py @@ -172,7 +172,7 @@ async def worker(master, offset, aperture, count=16): workers = [] - for k in [0x0000_0000,0x0010_2000,0x0016_0000]: + for k in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: workers.append(cocotb.start_soon(worker(tb.axil_master, k, 0x1000, count=16))) while workers: From e719672872e1132cd5714858b094d998c338fbe0 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 11:19:31 -0700 Subject: [PATCH 18/43] Fix syntax errors --- protocols/saci/rtl/SaciAxiLiteMaster.vhd | 63 +++++++++++++++++++--- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 28 +++++----- tests/test_SaciAxiLiteMaster.py | 2 +- 3 files changed, 74 insertions(+), 19 deletions(-) diff --git a/protocols/saci/rtl/SaciAxiLiteMaster.vhd b/protocols/saci/rtl/SaciAxiLiteMaster.vhd index 4f575e7501..90b69c971d 100644 --- a/protocols/saci/rtl/SaciAxiLiteMaster.vhd +++ b/protocols/saci/rtl/SaciAxiLiteMaster.vhd @@ -29,6 +29,8 @@ entity SaciAxiLiteMaster is generic ( TPD_G : time := 1 ns); port ( + -- Global Reset + rstL : in sl; -- SACI Slave interface saciClk : in sl; saciCmd : in sl; @@ -37,10 +39,10 @@ entity SaciAxiLiteMaster is -- AXI-Lite Register Interface axilClk : in sl; axilRst : in sl; - axilReadMaster : in AxiLiteReadMasterType; - axilReadSlave : out AxiLiteReadSlaveType; - axilWriteMaster : in AxiLiteWriteMasterType; - axilWriteSlave : out AxiLiteWriteSlaveType); + axilReadMaster : out AxiLiteReadMasterType; + axilReadSlave : in AxiLiteReadSlaveType; + axilWriteMaster : out AxiLiteWriteMasterType; + axilWriteSlave : in AxiLiteWriteSlaveType); end SaciAxiLiteMaster; architecture rtl of SaciAxiLiteMaster is @@ -49,6 +51,11 @@ architecture rtl of SaciAxiLiteMaster is signal axilReq : AxiLiteReqType; signal axilAck : AxiLiteAckType; + -- SACI resets + signal rstOutL : sl; + signal rstInL : sl; + + -- SACI Slave parallel interface signal exec : sl; signal ack : sl; @@ -64,6 +71,8 @@ architecture rtl of SaciAxiLiteMaster is begin + rstInL <= rstOutL; + U_SaciSlave_1 : entity surf.SaciSlave generic map ( TPD_G => TPD_G) @@ -83,14 +92,56 @@ begin wrData => wrData, -- [out] rdData => rdData); -- [in] - axilReq.request <= exec; + ------------------------------------------------------ + -- Synchronize exec to axilReq.request + ------------------------------------------------------ + U_Synchronizer_1 : entity surf.Synchronizer + generic map ( + TPD_G => TPD_G, + RST_POLARITY_G => '1', + OUT_POLARITY_G => '1', + RST_ASYNC_G => true, + STAGES_G => 2, + BYPASS_SYNC_G => false, + INIT_G => "0") + port map ( + clk => axilClk, -- [in] + rst => axilRst, -- [in] + dataIn => exec, -- [in] + dataOut => axilReq.request); -- [out] + + ------------------------------------------------------ + -- These should have settled to be sampled by axilClk + -- By the time exec gets synced to axilReq + ------------------------------------------------------ axilReq.rnw <= not readL; axilReq.address(1 downto 0) <= "00"; axilReq.address(13 downto 2) <= addr; axilReq.address(20 downto 14) <= cmd; axilReq.wrData <= wrData; - ack <= axilAck.done; + ------------------------------------------------------ + -- Synchronize axilAck.done to saciClk + ------------------------------------------------------ + U_Synchronizer_2 : entity surf.Synchronizer + generic map ( + TPD_G => TPD_G, + RST_POLARITY_G => '1', + OUT_POLARITY_G => '1', + RST_ASYNC_G => true, + STAGES_G => 2, + BYPASS_SYNC_G => false, + INIT_G => "0") + port map ( + clk => saciClk, -- [in] + rst => '0', -- [in] + dataIn => axilAck.done, -- [in] + dataOut => ack); -- [out] + + ------------------------------------------------------ + -- This should have settled to be sampled by saciClk + -- By the time axilAck.done gets synced to ack + ------------------------------------------------------ rdData <= axilAck.rdData; U_AxiLiteMaster_1 : entity surf.AxiLiteMaster diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index 46051cd9a0..8896466eb9 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -21,7 +21,7 @@ library surf; use surf.StdRtlPkg.all; use surf.AxiLitePkg.all; -entity AxiLiteCrossbarTb is +entity SaciAxiLiteMasterTb is port ( -- AXI-Lite Interface S_AXI_ACLK : in std_logic; @@ -45,9 +45,9 @@ entity AxiLiteCrossbarTb is S_AXI_RRESP : out std_logic_vector(1 downto 0); S_AXI_RVALID : out std_logic; S_AXI_RREADY : in std_logic); -end AxiLiteCrossbarTb; +end SaciAxiLiteMasterTb; -architecture mapping of AxiLiteCrossbarTb is +architecture mapping of SaciAxiLiteMasterTb is signal fpgaAxilClk : sl; signal fpgaAxilRst : sl; @@ -65,6 +65,8 @@ architecture mapping of AxiLiteCrossbarTb is signal asicAxilWriteMaster : AxiLiteWriteMasterType; signal asicAxilWriteSlave : AxiLiteWriteSlaveType; + signal rstL : sl; + signal saciClk : sl; signal saciCmd : sl; signal saciSelL : slv(0 downto 0); @@ -115,7 +117,7 @@ begin ------------------------------------------------------------------------------------------------- U_AxiLiteSaciMaster_1 : entity surf.AxiLiteSaciMaster generic map ( - TPD_G => TPD_G, + TPD_G => 1 ns, AXIL_CLK_PERIOD_G => 125.0e6, -- AXIL_TIMEOUT_G => AXIL_TIMEOUT_G, SACI_CLK_PERIOD_G => 1.0e6, @@ -144,15 +146,17 @@ begin CLK_PERIOD_G => 8.0 ns) port map ( clkP => asicAxilClk, -- [out] - rst => asicAxilRst) -- [out] + rst => asicAxilRst, -- [out] + rstL => rstL); -- [out] - U_SaciAxiLiteMaster_1 : entity surf.SaciAxiLiteMaster + U_SaciAxiLiteMaster_1 : entity surf.SaciAxiLiteMaster generic map ( - TPD_G => TPD_G) + TPD_G => 1 ns) port map ( + rstL => rstL, -- [in] saciClk => saciClk, -- [in] saciCmd => saciCmd, -- [in] - saciSelL => saciSelL, -- [in] + saciSelL => saciSelL(0), -- [in] saciRsp => saciRsp(0), -- [out] axilClk => asicAxilClk, -- [in] axilRst => asicAxilRst, -- [in] @@ -170,10 +174,10 @@ begin -- Axi Port axiClk => asicAxilClk, axiRst => asicAxilRst, - axiReadMaster => asicAxilReadMasters, - axiReadSlave => asicAxilReadSlaves, - axiWriteMaster => asicAxilWriteMasters, - axiWriteSlave => asicAxilWriteSlaves); + axiReadMaster => asicAxilReadMaster, + axiReadSlave => asicAxilReadSlave, + axiWriteMaster => asicAxilWriteMaster, + axiWriteSlave => asicAxilWriteSlave); end mapping; diff --git a/tests/test_SaciAxiLiteMaster.py b/tests/test_SaciAxiLiteMaster.py index 386ea2a5fa..11d1acb30a 100644 --- a/tests/test_SaciAxiLiteMaster.py +++ b/tests/test_SaciAxiLiteMaster.py @@ -217,7 +217,7 @@ def cycle_pause(): "parameters", [ None ]) -def test_AxiLiteCrossbarTb(parameters): +def test_SaciAxiLiteMasterTb(parameters): # https://github.com/themperek/cocotb-test#arguments-for-simulatorrun # https://github.com/themperek/cocotb-test/blob/master/cocotb_test/simulator.py From c47865770276012f3f9bac1e50315e7e1a624f1d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 12:44:37 -0700 Subject: [PATCH 19/43] Fix typo --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index 8896466eb9..076e7f1e47 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -119,8 +119,9 @@ begin generic map ( TPD_G => 1 ns, AXIL_CLK_PERIOD_G => 125.0e6, --- AXIL_TIMEOUT_G => AXIL_TIMEOUT_G, - SACI_CLK_PERIOD_G => 1.0e6, + AXIL_TIMEOUT_G => AXIL_TIMEOUT_G, + AXIL_TIMEOUT_G => 1.0e-3, + SACI_CLK_PERIOD_G => 1.0e-6, SACI_CLK_FREERUN_G => false, SACI_NUM_CHIPS_G => 1, SACI_RSP_BUSSED_G => false) From a01a49718d4280d5e61896814adb01931897fbf6 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 12:57:17 -0700 Subject: [PATCH 20/43] Fix axi lite clock period --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index 076e7f1e47..10504f579e 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -118,8 +118,7 @@ begin U_AxiLiteSaciMaster_1 : entity surf.AxiLiteSaciMaster generic map ( TPD_G => 1 ns, - AXIL_CLK_PERIOD_G => 125.0e6, - AXIL_TIMEOUT_G => AXIL_TIMEOUT_G, + AXIL_CLK_PERIOD_G => 8.0e-9, AXIL_TIMEOUT_G => 1.0e-3, SACI_CLK_PERIOD_G => 1.0e-6, SACI_CLK_FREERUN_G => false, From b9c4351e701971c6cec641877215640f3c80370f Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Thu, 5 Sep 2024 13:21:31 -0700 Subject: [PATCH 21/43] renaming file --- .../{test_SaciAxiLiteMaster.py => test_SaciAxiLiteMasterTb.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/{test_SaciAxiLiteMaster.py => test_SaciAxiLiteMasterTb.py} (99%) diff --git a/tests/test_SaciAxiLiteMaster.py b/tests/test_SaciAxiLiteMasterTb.py similarity index 99% rename from tests/test_SaciAxiLiteMaster.py rename to tests/test_SaciAxiLiteMasterTb.py index 11d1acb30a..dd70909266 100644 --- a/tests/test_SaciAxiLiteMaster.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -15,7 +15,7 @@ from cocotbext.axi import AxiLiteBus, AxiLiteMaster -# test_AxiLiteCrossbarTb +# test_SaciAxiLiteMasterTb from cocotb_test.simulator import run import pytest import glob From bf74f4423e54c9c9c2fe1017de86ea1b98c16fe1 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 14:35:44 -0700 Subject: [PATCH 22/43] Move to pure VHDL sim --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 118 +++++++++++---------- tests/test_SaciAxiLiteMasterTb.py | 69 ++++-------- 2 files changed, 80 insertions(+), 107 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index 10504f579e..a4347d8e26 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -22,29 +22,7 @@ use surf.StdRtlPkg.all; use surf.AxiLitePkg.all; entity SaciAxiLiteMasterTb is - port ( - -- AXI-Lite Interface - S_AXI_ACLK : in std_logic; - S_AXI_ARESETN : in std_logic; - S_AXI_AWADDR : in std_logic_vector(31 downto 0); - S_AXI_AWPROT : in std_logic_vector(2 downto 0); - S_AXI_AWVALID : in std_logic; - S_AXI_AWREADY : out std_logic; - S_AXI_WDATA : in std_logic_vector(31 downto 0); - S_AXI_WSTRB : in std_logic_vector(3 downto 0); - S_AXI_WVALID : in std_logic; - S_AXI_WREADY : out std_logic; - S_AXI_BRESP : out std_logic_vector(1 downto 0); - S_AXI_BVALID : out std_logic; - S_AXI_BREADY : in std_logic; - S_AXI_ARADDR : in std_logic_vector(31 downto 0); - S_AXI_ARPROT : in std_logic_vector(2 downto 0); - S_AXI_ARVALID : in std_logic; - S_AXI_ARREADY : out std_logic; - S_AXI_RDATA : out std_logic_vector(31 downto 0); - S_AXI_RRESP : out std_logic_vector(1 downto 0); - S_AXI_RVALID : out std_logic; - S_AXI_RREADY : in std_logic); + end SaciAxiLiteMasterTb; architecture mapping of SaciAxiLiteMasterTb is @@ -76,41 +54,69 @@ architecture mapping of SaciAxiLiteMasterTb is begin - U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator +-- U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator +-- generic map ( +-- EN_ERROR_RESP => true, +-- FREQ_HZ => 125000000, +-- ADDR_WIDTH => 32) +-- port map ( +-- -- IP Integrator AXI-Lite Interface +-- S_AXI_ACLK => S_AXI_ACLK, +-- S_AXI_ARESETN => S_AXI_ARESETN, +-- S_AXI_AWADDR => S_AXI_AWADDR, +-- S_AXI_AWPROT => S_AXI_AWPROT, +-- S_AXI_AWVALID => S_AXI_AWVALID, +-- S_AXI_AWREADY => S_AXI_AWREADY, +-- S_AXI_WDATA => S_AXI_WDATA, +-- S_AXI_WSTRB => S_AXI_WSTRB, +-- S_AXI_WVALID => S_AXI_WVALID, +-- S_AXI_WREADY => S_AXI_WREADY, +-- S_AXI_BRESP => S_AXI_BRESP, +-- S_AXI_BVALID => S_AXI_BVALID, +-- S_AXI_BREADY => S_AXI_BREADY, +-- S_AXI_ARADDR => S_AXI_ARADDR, +-- S_AXI_ARPROT => S_AXI_ARPROT, +-- S_AXI_ARVALID => S_AXI_ARVALID, +-- S_AXI_ARREADY => S_AXI_ARREADY, +-- S_AXI_RDATA => S_AXI_RDATA, +-- S_AXI_RRESP => S_AXI_RRESP, +-- S_AXI_RVALID => S_AXI_RVALID, +-- S_AXI_RREADY => S_AXI_RREADY, +-- -- SURF AXI-Lite Interface +-- axilClk => fpgaAxilClk, +-- axilRst => fpgaAxilRst, +-- axilReadMaster => fpgaAxilReadMaster, +-- axilReadSlave => fpgaAxilReadSlave, +-- axilWriteMaster => fpgaAxilWriteMaster, +-- axilWriteSlave => fpgaAxilWriteSlave); + + U_ClkRst_2 : entity surf.ClkRst generic map ( - EN_ERROR_RESP => true, - FREQ_HZ => 125000000, - ADDR_WIDTH => 32) + CLK_PERIOD_G => 8.0 ns, + CLK_DELAY_G => 3.2 ns) port map ( - -- IP Integrator AXI-Lite Interface - S_AXI_ACLK => S_AXI_ACLK, - S_AXI_ARESETN => S_AXI_ARESETN, - S_AXI_AWADDR => S_AXI_AWADDR, - S_AXI_AWPROT => S_AXI_AWPROT, - S_AXI_AWVALID => S_AXI_AWVALID, - S_AXI_AWREADY => S_AXI_AWREADY, - S_AXI_WDATA => S_AXI_WDATA, - S_AXI_WSTRB => S_AXI_WSTRB, - S_AXI_WVALID => S_AXI_WVALID, - S_AXI_WREADY => S_AXI_WREADY, - S_AXI_BRESP => S_AXI_BRESP, - S_AXI_BVALID => S_AXI_BVALID, - S_AXI_BREADY => S_AXI_BREADY, - S_AXI_ARADDR => S_AXI_ARADDR, - S_AXI_ARPROT => S_AXI_ARPROT, - S_AXI_ARVALID => S_AXI_ARVALID, - S_AXI_ARREADY => S_AXI_ARREADY, - S_AXI_RDATA => S_AXI_RDATA, - S_AXI_RRESP => S_AXI_RRESP, - S_AXI_RVALID => S_AXI_RVALID, - S_AXI_RREADY => S_AXI_RREADY, - -- SURF AXI-Lite Interface - axilClk => fpgaAxilClk, - axilRst => fpgaAxilRst, - axilReadMaster => fpgaAxilReadMaster, - axilReadSlave => fpgaAxilReadSlave, - axilWriteMaster => fpgaAxilWriteMaster, - axilWriteSlave => fpgaAxilWriteSlave); + clkP => fpgaAxilClk, -- [out] + rst => fpgaAxilRst); -- [out] + + process is + begin + wait for 10 us; + wait until fpgaAxilClk = '1'; + wait until fpgaAxilClk = '1'; + wait until fpgaAxilClk = '1'; + + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00000000", + X"12345678"); + + wait until fpgaAxilClk = '1'; + wait + + end process; + ------------------------------------------------------------------------------------------------- -- FPGA Side diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index dd70909266..f800327396 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -98,50 +98,17 @@ async def run_test_words(dut): await tb.cycle_reset() - for length in list(range(1, 4)): - for memDev in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: - for offset in list(range(byte_lanes)): - addr = offset - tb.log.info( f'length={length},addr={hex(addr)}' ) - - test_data = bytearray([x % 256 for x in range(length)]) - event = tb.axil_master.init_write(addr, test_data) - await event.wait() - event = tb.axil_master.init_read(addr, length) - await event.wait() - assert event.data.data == test_data - - test_data = bytearray([x % 256 for x in range(length)]) - await tb.axil_master.write(addr, test_data) - assert (await tb.axil_master.read(addr, length)).data == test_data - - test_data = [x * 0x1001 for x in range(length)] - await tb.axil_master.write_words(addr, test_data) - assert await tb.axil_master.read_words(addr, length) == test_data - - test_data = [x * 0x10200201 for x in range(length)] - await tb.axil_master.write_dwords(addr, test_data) - assert await tb.axil_master.read_dwords(addr, length) == test_data - - test_data = [x * 0x1020304004030201 for x in range(length)] - await tb.axil_master.write_qwords(addr, test_data) - assert await tb.axil_master.read_qwords(addr, length) == test_data - - test_data = 0x01*length - await tb.axil_master.write_byte(addr, test_data) - assert await tb.axil_master.read_byte(addr) == test_data - - test_data = 0x1001*length - await tb.axil_master.write_word(addr, test_data) - assert await tb.axil_master.read_word(addr) == test_data - - test_data = 0x10200201*length - await tb.axil_master.write_dword(addr, test_data) - assert await tb.axil_master.read_dword(addr) == test_data - - test_data = 0x1020304004030201*length - await tb.axil_master.write_qword(addr, test_data) - assert await tb.axil_master.read_qword(addr) == test_data + for offset in range(0, 0x100, 4): + addr = offset + tb.log.info( f'addr={hex(addr)}' ) + + test_data = bytearray([x % 256 for x in range(4)]) + event = tb.axil_master.init_write(addr, test_data) + await event.wait() + event = tb.axil_master.init_read(addr, length) + await event.wait() + assert event.data.data == test_data + tb.log.info( f'wr_data={hex(test_data)}, rd_data={hex(event.data.data)}') await RisingEdge(dut.S_AXI_ACLK) await RisingEdge(dut.S_AXI_ACLK) @@ -191,10 +158,10 @@ def cycle_pause(): ################# # run_test_bytes ################# - factory = TestFactory(run_test_bytes) - factory.add_option("idle_inserter", [None, cycle_pause]) - factory.add_option("backpressure_inserter", [None, cycle_pause]) - factory.generate_tests() + #factory = TestFactory(run_test_bytes) + #factory.add_option("idle_inserter", [None, cycle_pause]) + #factory.add_option("backpressure_inserter", [None, cycle_pause]) + #factory.generate_tests() ################# # run_test_words @@ -205,8 +172,8 @@ def cycle_pause(): ################# # run_stress_test ################# - factory = TestFactory(run_stress_test) - factory.generate_tests() + #factory = TestFactory(run_stress_test) + #factory.generate_tests() tests_dir = os.path.dirname(__file__) tests_module = 'SaciAxiLiteMasterTb' @@ -260,5 +227,5 @@ def test_SaciAxiLiteMasterTb(parameters): ######################################################################## # Dump waveform to file ($ gtkwave sim_build/path/To/{tests_module}.ghw) ######################################################################## - # sim_args =[f'--wave={tests_module}.ghw'], + sim_args =[f'--wave={tests_module}.ghw'], ) From bddd59156890acd4c8d1c0cae2763432a688363b Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 14:59:57 -0700 Subject: [PATCH 23/43] Assign upper addr bits, expand sim --- protocols/saci/rtl/SaciAxiLiteMaster.vhd | 1 + protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 57 +++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/protocols/saci/rtl/SaciAxiLiteMaster.vhd b/protocols/saci/rtl/SaciAxiLiteMaster.vhd index 90b69c971d..abe0e364b5 100644 --- a/protocols/saci/rtl/SaciAxiLiteMaster.vhd +++ b/protocols/saci/rtl/SaciAxiLiteMaster.vhd @@ -118,6 +118,7 @@ begin axilReq.address(1 downto 0) <= "00"; axilReq.address(13 downto 2) <= addr; axilReq.address(20 downto 14) <= cmd; + axilReq.address(31 downto 21) <= (others => '0'); axilReq.wrData <= wrData; ------------------------------------------------------ diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index a4347d8e26..e07dc51130 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -98,25 +98,78 @@ begin clkP => fpgaAxilClk, -- [out] rst => fpgaAxilRst); -- [out] + + process is + variable wrData : slv(31 downto 0); + variable rdData : slv(31 downto 0); begin wait for 10 us; wait until fpgaAxilClk = '1'; wait until fpgaAxilClk = '1'; wait until fpgaAxilClk = '1'; + wrData := X"12345678"; axiLiteBusSimWrite( fpgaAxilClk, fpgaAxilWriteMaster, fpgaAxilWriteSlave, X"00000000", - X"12345678"); + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00000000", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + wrData := X"9abcdef0"; + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00000004", + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00000004", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + + wrData := X"deadbeef"; + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00100008", + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00100008", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + wait until fpgaAxilClk = '1'; - wait + wait; end process; + + ------------------------------------------------------------------------------------------------- -- FPGA Side From 62fb73b1891cb1c1315e0e2b48712c4e227ea136 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 15:29:15 -0700 Subject: [PATCH 24/43] Restore cocotb sim --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 191 ++++++++++++++------- tests/test_SaciAxiLiteMasterTb.py | 9 +- 2 files changed, 136 insertions(+), 64 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index a4347d8e26..e6bc68e517 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -22,7 +22,29 @@ use surf.StdRtlPkg.all; use surf.AxiLitePkg.all; entity SaciAxiLiteMasterTb is - + port ( + -- AXI-Lite Interface + S_AXI_ACLK : in std_logic; + S_AXI_ARESETN : in std_logic; + S_AXI_AWADDR : in std_logic_vector(31 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(31 downto 0); + S_AXI_WSTRB : in std_logic_vector(3 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARADDR : in std_logic_vector(31 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RDATA : out std_logic_vector(31 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic); end SaciAxiLiteMasterTb; architecture mapping of SaciAxiLiteMasterTb is @@ -54,68 +76,117 @@ architecture mapping of SaciAxiLiteMasterTb is begin --- U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator --- generic map ( --- EN_ERROR_RESP => true, --- FREQ_HZ => 125000000, --- ADDR_WIDTH => 32) --- port map ( --- -- IP Integrator AXI-Lite Interface --- S_AXI_ACLK => S_AXI_ACLK, --- S_AXI_ARESETN => S_AXI_ARESETN, --- S_AXI_AWADDR => S_AXI_AWADDR, --- S_AXI_AWPROT => S_AXI_AWPROT, --- S_AXI_AWVALID => S_AXI_AWVALID, --- S_AXI_AWREADY => S_AXI_AWREADY, --- S_AXI_WDATA => S_AXI_WDATA, --- S_AXI_WSTRB => S_AXI_WSTRB, --- S_AXI_WVALID => S_AXI_WVALID, --- S_AXI_WREADY => S_AXI_WREADY, --- S_AXI_BRESP => S_AXI_BRESP, --- S_AXI_BVALID => S_AXI_BVALID, --- S_AXI_BREADY => S_AXI_BREADY, --- S_AXI_ARADDR => S_AXI_ARADDR, --- S_AXI_ARPROT => S_AXI_ARPROT, --- S_AXI_ARVALID => S_AXI_ARVALID, --- S_AXI_ARREADY => S_AXI_ARREADY, --- S_AXI_RDATA => S_AXI_RDATA, --- S_AXI_RRESP => S_AXI_RRESP, --- S_AXI_RVALID => S_AXI_RVALID, --- S_AXI_RREADY => S_AXI_RREADY, --- -- SURF AXI-Lite Interface --- axilClk => fpgaAxilClk, --- axilRst => fpgaAxilRst, --- axilReadMaster => fpgaAxilReadMaster, --- axilReadSlave => fpgaAxilReadSlave, --- axilWriteMaster => fpgaAxilWriteMaster, --- axilWriteSlave => fpgaAxilWriteSlave); - - U_ClkRst_2 : entity surf.ClkRst + U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator generic map ( - CLK_PERIOD_G => 8.0 ns, - CLK_DELAY_G => 3.2 ns) + EN_ERROR_RESP => true, + FREQ_HZ => 125000000, + ADDR_WIDTH => 32) port map ( - clkP => fpgaAxilClk, -- [out] - rst => fpgaAxilRst); -- [out] - - process is - begin - wait for 10 us; - wait until fpgaAxilClk = '1'; - wait until fpgaAxilClk = '1'; - wait until fpgaAxilClk = '1'; - - axiLiteBusSimWrite( - fpgaAxilClk, - fpgaAxilWriteMaster, - fpgaAxilWriteSlave, - X"00000000", - X"12345678"); - - wait until fpgaAxilClk = '1'; - wait + -- IP Integrator AXI-Lite Interface + S_AXI_ACLK => S_AXI_ACLK, + S_AXI_ARESETN => S_AXI_ARESETN, + S_AXI_AWADDR => S_AXI_AWADDR, + S_AXI_AWPROT => S_AXI_AWPROT, + S_AXI_AWVALID => S_AXI_AWVALID, + S_AXI_AWREADY => S_AXI_AWREADY, + S_AXI_WDATA => S_AXI_WDATA, + S_AXI_WSTRB => S_AXI_WSTRB, + S_AXI_WVALID => S_AXI_WVALID, + S_AXI_WREADY => S_AXI_WREADY, + S_AXI_BRESP => S_AXI_BRESP, + S_AXI_BVALID => S_AXI_BVALID, + S_AXI_BREADY => S_AXI_BREADY, + S_AXI_ARADDR => S_AXI_ARADDR, + S_AXI_ARPROT => S_AXI_ARPROT, + S_AXI_ARVALID => S_AXI_ARVALID, + S_AXI_ARREADY => S_AXI_ARREADY, + S_AXI_RDATA => S_AXI_RDATA, + S_AXI_RRESP => S_AXI_RRESP, + S_AXI_RVALID => S_AXI_RVALID, + S_AXI_RREADY => S_AXI_RREADY, + -- SURF AXI-Lite Interface + axilClk => fpgaAxilClk, + axilRst => fpgaAxilRst, + axilReadMaster => fpgaAxilReadMaster, + axilReadSlave => fpgaAxilReadSlave, + axilWriteMaster => fpgaAxilWriteMaster, + axilWriteSlave => fpgaAxilWriteSlave); + +-- U_ClkRst_2 : entity surf.ClkRst +-- generic map ( +-- CLK_PERIOD_G => 8.0 ns, +-- CLK_DELAY_G => 3.2 ns) +-- port map ( +-- clkP => fpgaAxilClk, -- [out] +-- rst => fpgaAxilRst); -- [out] + +-- process is +-- variable wrData : slv(31 downto 0); +-- variable rdData : slv(31 downto 0); +-- begin +-- wait for 10 us; +-- wait until fpgaAxilClk = '1'; +-- wait until fpgaAxilClk = '1'; +-- wait until fpgaAxilClk = '1'; + +-- wrData := X"12345678"; +-- axiLiteBusSimWrite( +-- fpgaAxilClk, +-- fpgaAxilWriteMaster, +-- fpgaAxilWriteSlave, +-- X"00000000", +-- wrData); + +-- axiLiteBusSimRead( +-- fpgaAxilClk, +-- fpgaAxilReadMaster, +-- fpgaAxilReadSlave, +-- X"00000000", +-- rdData); + +-- assert (wrData = rdData) report "Data Mismatch" severity error; + +-- wrData := X"9abcdef0"; +-- axiLiteBusSimWrite( +-- fpgaAxilClk, +-- fpgaAxilWriteMaster, +-- fpgaAxilWriteSlave, +-- X"00000004", +-- wrData); + +-- axiLiteBusSimRead( +-- fpgaAxilClk, +-- fpgaAxilReadMaster, +-- fpgaAxilReadSlave, +-- X"00000004", +-- rdData); + +-- assert (wrData = rdData) report "Data Mismatch" severity error; + + +-- wrData := X"deadbeef"; +-- axiLiteBusSimWrite( +-- fpgaAxilClk, +-- fpgaAxilWriteMaster, +-- fpgaAxilWriteSlave, +-- X"00100008", +-- wrData); + +-- axiLiteBusSimRead( +-- fpgaAxilClk, +-- fpgaAxilReadMaster, +-- fpgaAxilReadSlave, +-- X"00100008", +-- rdData); + +-- assert (wrData = rdData) report "Data Mismatch" severity error; + + + +-- wait until fpgaAxilClk = '1'; +-- wait; - end process; +-- end process; ------------------------------------------------------------------------------------------------- diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index f800327396..b6f370465b 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -98,17 +98,18 @@ async def run_test_words(dut): await tb.cycle_reset() - for offset in range(0, 0x100, 4): + for offset in range(4, 8, 4): addr = offset tb.log.info( f'addr={hex(addr)}' ) - test_data = bytearray([x % 256 for x in range(4)]) + test_data = addr.to_bytes(length=4, byteorder='little') + test_data_disp = int.from_bytes(test_data, 'little', signed=False) event = tb.axil_master.init_write(addr, test_data) await event.wait() - event = tb.axil_master.init_read(addr, length) + event = tb.axil_master.init_read(addr, 4) await event.wait() assert event.data.data == test_data - tb.log.info( f'wr_data={hex(test_data)}, rd_data={hex(event.data.data)}') + tb.log.info( f'wr_data={test_data}, rd_data={event.data.data}') await RisingEdge(dut.S_AXI_ACLK) await RisingEdge(dut.S_AXI_ACLK) From 36e4490642c5e7b7de55a3d3b260e3fd7de1662c Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 20:37:17 -0700 Subject: [PATCH 25/43] Cleanup --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 79 +-------- .../saci/sim/SaciAxiLiteMasterTbWrapper.vhd | 165 ++++++++++++++++++ tests/test_SaciAxiLiteMasterTb.py | 28 +-- 3 files changed, 182 insertions(+), 90 deletions(-) create mode 100644 protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index e6bc68e517..0e278bb8a5 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -112,83 +112,6 @@ begin axilWriteMaster => fpgaAxilWriteMaster, axilWriteSlave => fpgaAxilWriteSlave); --- U_ClkRst_2 : entity surf.ClkRst --- generic map ( --- CLK_PERIOD_G => 8.0 ns, --- CLK_DELAY_G => 3.2 ns) --- port map ( --- clkP => fpgaAxilClk, -- [out] --- rst => fpgaAxilRst); -- [out] - --- process is --- variable wrData : slv(31 downto 0); --- variable rdData : slv(31 downto 0); --- begin --- wait for 10 us; --- wait until fpgaAxilClk = '1'; --- wait until fpgaAxilClk = '1'; --- wait until fpgaAxilClk = '1'; - --- wrData := X"12345678"; --- axiLiteBusSimWrite( --- fpgaAxilClk, --- fpgaAxilWriteMaster, --- fpgaAxilWriteSlave, --- X"00000000", --- wrData); - --- axiLiteBusSimRead( --- fpgaAxilClk, --- fpgaAxilReadMaster, --- fpgaAxilReadSlave, --- X"00000000", --- rdData); - --- assert (wrData = rdData) report "Data Mismatch" severity error; - --- wrData := X"9abcdef0"; --- axiLiteBusSimWrite( --- fpgaAxilClk, --- fpgaAxilWriteMaster, --- fpgaAxilWriteSlave, --- X"00000004", --- wrData); - --- axiLiteBusSimRead( --- fpgaAxilClk, --- fpgaAxilReadMaster, --- fpgaAxilReadSlave, --- X"00000004", --- rdData); - --- assert (wrData = rdData) report "Data Mismatch" severity error; - - --- wrData := X"deadbeef"; --- axiLiteBusSimWrite( --- fpgaAxilClk, --- fpgaAxilWriteMaster, --- fpgaAxilWriteSlave, --- X"00100008", --- wrData); - --- axiLiteBusSimRead( --- fpgaAxilClk, --- fpgaAxilReadMaster, --- fpgaAxilReadSlave, --- X"00100008", --- rdData); - --- assert (wrData = rdData) report "Data Mismatch" severity error; - - - --- wait until fpgaAxilClk = '1'; --- wait; - --- end process; - - ------------------------------------------------------------------------------------------------- -- FPGA Side ------------------------------------------------------------------------------------------------- @@ -197,7 +120,7 @@ begin TPD_G => 1 ns, AXIL_CLK_PERIOD_G => 8.0e-9, AXIL_TIMEOUT_G => 1.0e-3, - SACI_CLK_PERIOD_G => 1.0e-6, + SACI_CLK_PERIOD_G => 0.1e-7, SACI_CLK_FREERUN_G => false, SACI_NUM_CHIPS_G => 1, SACI_RSP_BUSSED_G => false) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd new file mode 100644 index 0000000000..e972f038f1 --- /dev/null +++ b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd @@ -0,0 +1,165 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: surf.AxiLiteCrossbar cocoTB testbed +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- + +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiLitePkg.all; + +entity SaciAxiLiteMasterTb is + port ( + -- AXI-Lite Interface + S_AXI_ACLK : in std_logic; + S_AXI_ARESETN : in std_logic; + S_AXI_AWADDR : in std_logic_vector(31 downto 0); + S_AXI_AWPROT : in std_logic_vector(2 downto 0); + S_AXI_AWVALID : in std_logic; + S_AXI_AWREADY : out std_logic; + S_AXI_WDATA : in std_logic_vector(31 downto 0); + S_AXI_WSTRB : in std_logic_vector(3 downto 0); + S_AXI_WVALID : in std_logic; + S_AXI_WREADY : out std_logic; + S_AXI_BRESP : out std_logic_vector(1 downto 0); + S_AXI_BVALID : out std_logic; + S_AXI_BREADY : in std_logic; + S_AXI_ARADDR : in std_logic_vector(31 downto 0); + S_AXI_ARPROT : in std_logic_vector(2 downto 0); + S_AXI_ARVALID : in std_logic; + S_AXI_ARREADY : out std_logic; + S_AXI_RDATA : out std_logic_vector(31 downto 0); + S_AXI_RRESP : out std_logic_vector(1 downto 0); + S_AXI_RVALID : out std_logic; + S_AXI_RREADY : in std_logic); +end SaciAxiLiteMasterTb; + +architecture mapping of SaciAxiLiteMasterTb is + + signal axilClk : sl; + signal axilRstL : sl; + + signal axilReadMaster : AxiLiteReadMasterType; + signal axilReadSlave : AxiLiteReadSlaveType; + signal axilWriteMaster : AxiLiteWriteMasterType; + signal axilWriteSlave : AxiLiteWriteSlaveType; + + +begin + + U_SaciAxiLiteMasterTb_1 : entity surf.SaciAxiLiteMasterTb + port map ( + S_AXI_ACLK => axilClk, -- [in] + S_AXI_ARESETN => axilRstL, -- [in] + S_AXI_AWADDR => axilWriteMaster.awaddr, -- [in] + S_AXI_AWPROT => axilWriteMaster.awprot, -- [in] + S_AXI_AWVALID => axilWriteMaster.awvalid, -- [in] + S_AXI_AWREADY => axilWriteSlave.AWREADY, -- [out] + S_AXI_WDATA => axilWriteMaster.WDATA, -- [in] + S_AXI_WSTRB => axilWriteMaster.WSTRB, -- [in] + S_AXI_WVALID => axilWriteMaster.WVALID, -- [in] + S_AXI_WREADY => axilWriteSlave.WREADY, -- [out] + S_AXI_BRESP => axilWriteSlave.BRESP, -- [out] + S_AXI_BVALID => axilWriteSlave.BVALID, -- [out] + S_AXI_BREADY => axilReadMaster.BREADY, -- [in] + S_AXI_ARADDR => axilReadMaster.ARADDR, -- [in] + S_AXI_ARPROT => axilReadMaster.ARPROT, -- [in] + S_AXI_ARVALID => axilReadMaster.ARVALID, -- [in] + S_AXI_ARREADY => axilReadSlave.ARREADY, -- [out] + S_AXI_RDATA => axilReadSlave.RDATA, -- [out] + S_AXI_RRESP => axilReadSlave.RRESP, -- [out] + S_AXI_RVALID => axilReadSlave.RVALID, -- [out] + S_AXI_RREADY => axilReadMaster.RREADY); -- [in] + + U_ClkRst_2 : entity surf.ClkRst + generic map ( + CLK_PERIOD_G => 8.0 ns, + CLK_DELAY_G => 3.2 ns) + port map ( + clkP => axilClk, -- [out] + rstL => axilRstL); -- [out] + + process is + variable wrData : slv(31 downto 0); + variable rdData : slv(31 downto 0); + begin + wait for 10 us; + wait until fpgaAxilClk = '1'; + wait until fpgaAxilClk = '1'; + wait until fpgaAxilClk = '1'; + + wrData := X"12345678"; + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00000000", + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00000000", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + wrData := X"9abcdef0"; + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00000004", + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00000004", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + + wrData := X"deadbeef"; + axiLiteBusSimWrite( + fpgaAxilClk, + fpgaAxilWriteMaster, + fpgaAxilWriteSlave, + X"00100008", + wrData); + + axiLiteBusSimRead( + fpgaAxilClk, + fpgaAxilReadMaster, + fpgaAxilReadSlave, + X"00100008", + rdData); + + assert (wrData = rdData) report "Data Mismatch" severity error; + + + + wait until fpgaAxilClk = '1'; + wait; + + end process; + + + +end mapping; diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index b6f370465b..3d772997c0 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -98,18 +98,21 @@ async def run_test_words(dut): await tb.cycle_reset() - for offset in range(4, 8, 4): - addr = offset - tb.log.info( f'addr={hex(addr)}' ) - - test_data = addr.to_bytes(length=4, byteorder='little') - test_data_disp = int.from_bytes(test_data, 'little', signed=False) - event = tb.axil_master.init_write(addr, test_data) - await event.wait() - event = tb.axil_master.init_read(addr, 4) - await event.wait() - assert event.data.data == test_data - tb.log.info( f'wr_data={test_data}, rd_data={event.data.data}') + # Wait for internal reset to fall + await Timer(10, 'us') + + for offsetHigh in range(0, 0x100000, 0x100): + for offsetLow in range(0, 0x10, 4): + addr = offsetHigh | offsetLow + + test_data = addr.to_bytes(length=4, byteorder='little') + test_data_disp = int.from_bytes(test_data, 'little', signed=False) + event = tb.axil_master.init_write(addr, test_data) + await event.wait() + event = tb.axil_master.init_read(addr, 4) + await event.wait() + assert event.data.data == test_data + tb.log.info( f'addr={hex(addr)}, wr_data={test_data}, rd_data={event.data.data}') await RisingEdge(dut.S_AXI_ACLK) await RisingEdge(dut.S_AXI_ACLK) @@ -156,6 +159,7 @@ def cycle_pause(): if cocotb.SIM_NAME: + ################# # run_test_bytes ################# From e649813498936f4f2c7e319ad865428906727927 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 20:41:10 -0700 Subject: [PATCH 26/43] Cleanup --- .../saci/sim/SaciAxiLiteMasterTbWrapper.vhd | 27 ++----------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd index e972f038f1..716ec51c69 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd @@ -21,31 +21,8 @@ library surf; use surf.StdRtlPkg.all; use surf.AxiLitePkg.all; -entity SaciAxiLiteMasterTb is - port ( - -- AXI-Lite Interface - S_AXI_ACLK : in std_logic; - S_AXI_ARESETN : in std_logic; - S_AXI_AWADDR : in std_logic_vector(31 downto 0); - S_AXI_AWPROT : in std_logic_vector(2 downto 0); - S_AXI_AWVALID : in std_logic; - S_AXI_AWREADY : out std_logic; - S_AXI_WDATA : in std_logic_vector(31 downto 0); - S_AXI_WSTRB : in std_logic_vector(3 downto 0); - S_AXI_WVALID : in std_logic; - S_AXI_WREADY : out std_logic; - S_AXI_BRESP : out std_logic_vector(1 downto 0); - S_AXI_BVALID : out std_logic; - S_AXI_BREADY : in std_logic; - S_AXI_ARADDR : in std_logic_vector(31 downto 0); - S_AXI_ARPROT : in std_logic_vector(2 downto 0); - S_AXI_ARVALID : in std_logic; - S_AXI_ARREADY : out std_logic; - S_AXI_RDATA : out std_logic_vector(31 downto 0); - S_AXI_RRESP : out std_logic_vector(1 downto 0); - S_AXI_RVALID : out std_logic; - S_AXI_RREADY : in std_logic); -end SaciAxiLiteMasterTb; +entity SaciAxiLiteMasterTbWrapper is +end SaciAxiLiteMasterTbWrapper; architecture mapping of SaciAxiLiteMasterTb is From 9bb039ab5fa721e24fd58f984f8fa37ca3bef99d Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 20:42:14 -0700 Subject: [PATCH 27/43] Cleanup --- protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd index 716ec51c69..3214767def 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd @@ -24,7 +24,7 @@ use surf.AxiLitePkg.all; entity SaciAxiLiteMasterTbWrapper is end SaciAxiLiteMasterTbWrapper; -architecture mapping of SaciAxiLiteMasterTb is +architecture mapping of SaciAxiLiteMasterTbWrapper is signal axilClk : sl; signal axilRstL : sl; From 16d97e8bc45c5d4090dfe7664facfa2312938779 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:05:54 -0700 Subject: [PATCH 28/43] Add assert to SaciMaster2 to catch impossible SACI_CLK_PERIOD_G --- protocols/saci/rtl/SaciMaster2.vhd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/protocols/saci/rtl/SaciMaster2.vhd b/protocols/saci/rtl/SaciMaster2.vhd index 684a827235..854c091ecb 100644 --- a/protocols/saci/rtl/SaciMaster2.vhd +++ b/protocols/saci/rtl/SaciMaster2.vhd @@ -105,6 +105,8 @@ architecture rtl of SaciMaster2 is begin + assert (SACI_CLK_HALF_PERIOD_C >= 2) report "SACI_CLK_PERIOD_G is too fast for SYS_CLK_PERIOD_G" severity failure; + ------------------------------------------------------------------------------------------------- -- Synchronize saciRsp to sysClk ------------------------------------------------------------------------------------------------- From 1465a5b069c287716f1f270f7d1cf352b042571a Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:06:27 -0700 Subject: [PATCH 29/43] Faster SACI clock --- protocols/saci/sim/SaciAxiLiteMasterTb.vhd | 2 +- .../saci/sim/SaciAxiLiteMasterTbWrapper.vhd | 58 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd index 0e278bb8a5..124e240027 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTb.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTb.vhd @@ -120,7 +120,7 @@ begin TPD_G => 1 ns, AXIL_CLK_PERIOD_G => 8.0e-9, AXIL_TIMEOUT_G => 1.0e-3, - SACI_CLK_PERIOD_G => 0.1e-7, + SACI_CLK_PERIOD_G => 50.0e-9, SACI_CLK_FREERUN_G => false, SACI_NUM_CHIPS_G => 1, SACI_RSP_BUSSED_G => false) diff --git a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd index 3214767def..0bdce368df 100644 --- a/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd +++ b/protocols/saci/sim/SaciAxiLiteMasterTbWrapper.vhd @@ -44,14 +44,14 @@ begin S_AXI_AWADDR => axilWriteMaster.awaddr, -- [in] S_AXI_AWPROT => axilWriteMaster.awprot, -- [in] S_AXI_AWVALID => axilWriteMaster.awvalid, -- [in] - S_AXI_AWREADY => axilWriteSlave.AWREADY, -- [out] - S_AXI_WDATA => axilWriteMaster.WDATA, -- [in] - S_AXI_WSTRB => axilWriteMaster.WSTRB, -- [in] - S_AXI_WVALID => axilWriteMaster.WVALID, -- [in] + S_AXI_AWREADY => axilWriteSlave.awready, -- [out] + S_AXI_WDATA => axilWriteMaster.wdata, -- [in] + S_AXI_WSTRB => axilWriteMaster.wstrb, -- [in] + S_AXI_WVALID => axilWriteMaster.wvalid, -- [in] S_AXI_WREADY => axilWriteSlave.WREADY, -- [out] S_AXI_BRESP => axilWriteSlave.BRESP, -- [out] S_AXI_BVALID => axilWriteSlave.BVALID, -- [out] - S_AXI_BREADY => axilReadMaster.BREADY, -- [in] + S_AXI_BREADY => axilWriteMaster.BREADY, -- [in] S_AXI_ARADDR => axilReadMaster.ARADDR, -- [in] S_AXI_ARPROT => axilReadMaster.ARPROT, -- [in] S_AXI_ARVALID => axilReadMaster.ARVALID, -- [in] @@ -66,30 +66,30 @@ begin CLK_PERIOD_G => 8.0 ns, CLK_DELAY_G => 3.2 ns) port map ( - clkP => axilClk, -- [out] - rstL => axilRstL); -- [out] + clkP => axilClk, -- [out] + rstL => axilRstL); -- [out] process is variable wrData : slv(31 downto 0); variable rdData : slv(31 downto 0); begin wait for 10 us; - wait until fpgaAxilClk = '1'; - wait until fpgaAxilClk = '1'; - wait until fpgaAxilClk = '1'; + wait until axilClk = '1'; + wait until axilClk = '1'; + wait until axilClk = '1'; wrData := X"12345678"; axiLiteBusSimWrite( - fpgaAxilClk, - fpgaAxilWriteMaster, - fpgaAxilWriteSlave, + axilClk, + axilWriteMaster, + axilWriteSlave, X"00000000", wrData); axiLiteBusSimRead( - fpgaAxilClk, - fpgaAxilReadMaster, - fpgaAxilReadSlave, + axilClk, + axilReadMaster, + axilReadSlave, X"00000000", rdData); @@ -97,16 +97,16 @@ begin wrData := X"9abcdef0"; axiLiteBusSimWrite( - fpgaAxilClk, - fpgaAxilWriteMaster, - fpgaAxilWriteSlave, + axilClk, + axilWriteMaster, + axilWriteSlave, X"00000004", wrData); axiLiteBusSimRead( - fpgaAxilClk, - fpgaAxilReadMaster, - fpgaAxilReadSlave, + axilClk, + axilReadMaster, + axilReadSlave, X"00000004", rdData); @@ -115,16 +115,16 @@ begin wrData := X"deadbeef"; axiLiteBusSimWrite( - fpgaAxilClk, - fpgaAxilWriteMaster, - fpgaAxilWriteSlave, + axilClk, + axilWriteMaster, + axilWriteSlave, X"00100008", wrData); axiLiteBusSimRead( - fpgaAxilClk, - fpgaAxilReadMaster, - fpgaAxilReadSlave, + axilClk, + axilReadMaster, + axilReadSlave, X"00100008", rdData); @@ -132,7 +132,7 @@ begin - wait until fpgaAxilClk = '1'; + wait until axilClk = '1'; wait; end process; From 5422fbbe75aba48cb56238aaf77f42b9c60035c5 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:26:13 -0700 Subject: [PATCH 30/43] Cleanup --- tests/test_SaciAxiLiteMasterTb.py | 83 +++---------------------------- 1 file changed, 6 insertions(+), 77 deletions(-) diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index 3d772997c0..d49451b31b 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -65,30 +65,6 @@ async def cycle_reset(self): await RisingEdge(self.dut.S_AXI_ACLK) await RisingEdge(self.dut.S_AXI_ACLK) -async def run_test_bytes(dut, data_in=None, idle_inserter=None, backpressure_inserter=None): - - tb = TB(dut) - - byte_lanes = tb.axil_master.write_if.byte_lanes - - await tb.cycle_reset() - - tb.set_idle_generator(idle_inserter) - tb.set_backpressure_generator(backpressure_inserter) - - for length in range(1, byte_lanes*2): - for memDev in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: - for offset in range(byte_lanes): - addr = offset+memDev - tb.log.info( f'length={length},addr={hex(addr)}' ) - test_data = bytearray([x % 256 for x in range(length)]) - await tb.axil_master.write(addr, test_data) - data = await tb.axil_master.read(addr, length) - assert data.data == test_data - - await RisingEdge(dut.S_AXI_ACLK) - await RisingEdge(dut.S_AXI_ACLK) - async def run_test_words(dut): @@ -101,9 +77,12 @@ async def run_test_words(dut): # Wait for internal reset to fall await Timer(10, 'us') - for offsetHigh in range(0, 0x100000, 0x100): - for offsetLow in range(0, 0x10, 4): - addr = offsetHigh | offsetLow + for offsetHigh in range(17): + for offsetLow in range(0, 0xF, 4): + high = 0 + if offsetHigh != 0: + high = (1 << (offsetHigh+3)) + addr = high | offsetLow test_data = addr.to_bytes(length=4, byteorder='little') test_data_disp = int.from_bytes(test_data, 'little', signed=False) @@ -117,41 +96,6 @@ async def run_test_words(dut): await RisingEdge(dut.S_AXI_ACLK) await RisingEdge(dut.S_AXI_ACLK) -async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None): - - tb = TB(dut) - - await tb.cycle_reset() - - tb.set_idle_generator(idle_inserter) - tb.set_backpressure_generator(backpressure_inserter) - - async def worker(master, offset, aperture, count=16): - for k in range(count): - length = random.randint(1, min(32, aperture)) - addr = offset+random.randint(0, aperture-length) - test_data = bytearray([x % 256 for x in range(length)]) - - await Timer(random.randint(1, 100), 'ns') - - await master.write(addr, test_data) - - await Timer(random.randint(1, 100), 'ns') - - data = await master.read(addr, length) - assert data.data == test_data - - workers = [] - - for k in [0x0000_0000]: #,0x0010_2000,0x0016_0000]: - workers.append(cocotb.start_soon(worker(tb.axil_master, k, 0x1000, count=16))) - - while workers: - await workers.pop(0).join() - - await RisingEdge(dut.S_AXI_ACLK) - await RisingEdge(dut.S_AXI_ACLK) - def cycle_pause(): return itertools.cycle([1, 1, 1, 0]) @@ -159,27 +103,12 @@ def cycle_pause(): if cocotb.SIM_NAME: - - ################# - # run_test_bytes - ################# - #factory = TestFactory(run_test_bytes) - #factory.add_option("idle_inserter", [None, cycle_pause]) - #factory.add_option("backpressure_inserter", [None, cycle_pause]) - #factory.generate_tests() - ################# # run_test_words ################# factory = TestFactory(run_test_words) factory.generate_tests() - ################# - # run_stress_test - ################# - #factory = TestFactory(run_stress_test) - #factory.generate_tests() - tests_dir = os.path.dirname(__file__) tests_module = 'SaciAxiLiteMasterTb' From 10c470bfb48a5fb51c294d933149a273f6516b67 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:28:27 -0700 Subject: [PATCH 31/43] Linting --- tests/test_SaciAxiLiteMasterTb.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index d49451b31b..119c861f0f 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -85,13 +85,11 @@ async def run_test_words(dut): addr = high | offsetLow test_data = addr.to_bytes(length=4, byteorder='little') - test_data_disp = int.from_bytes(test_data, 'little', signed=False) event = tb.axil_master.init_write(addr, test_data) await event.wait() event = tb.axil_master.init_read(addr, 4) await event.wait() assert event.data.data == test_data - tb.log.info( f'addr={hex(addr)}, wr_data={test_data}, rd_data={event.data.data}') await RisingEdge(dut.S_AXI_ACLK) await RisingEdge(dut.S_AXI_ACLK) From 0d02aeee54611d3c9674c94737ec4426de6960c2 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:33:43 -0700 Subject: [PATCH 32/43] Documentation --- protocols/saci/rtl/SaciAxiLiteMaster.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/protocols/saci/rtl/SaciAxiLiteMaster.vhd b/protocols/saci/rtl/SaciAxiLiteMaster.vhd index abe0e364b5..a0893d8688 100644 --- a/protocols/saci/rtl/SaciAxiLiteMaster.vhd +++ b/protocols/saci/rtl/SaciAxiLiteMaster.vhd @@ -3,7 +3,7 @@ ------------------------------------------------------------------------------- -- Company : SLAC National Accelerator Laboratory ------------------------------------------------------------------------------- --- Description: New and improved version of the AxiLiteSaciMaster. +-- Description: AXI-Lite master bridge for SACI bus slave ------------------------------------------------------------------------------- -- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the From b9898ffebf1f9930d3e750ff592396002e4d7f01 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:35:33 -0700 Subject: [PATCH 33/43] Whitespace cleanup --- tests/test_SaciAxiLiteMasterTb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index 119c861f0f..89926f7493 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -76,7 +76,7 @@ async def run_test_words(dut): # Wait for internal reset to fall await Timer(10, 'us') - + for offsetHigh in range(17): for offsetLow in range(0, 0xF, 4): high = 0 From ef5f2a41889ce584332ef315f57d85a6a286e783 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:40:07 -0700 Subject: [PATCH 34/43] Update AxiStreamTrailerAppend.vhd Documentation --- axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd index 273a9a2042..6f7c26f401 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerAppend.vhd @@ -2,7 +2,7 @@ -- Company : SLAC National Accelerator Laboratory ------------------------------------------------------------------------------- -- Description: --- Append slv and the end and AXI-Stream package +-- Append transactions from a stream to transactions from another. ------------------------------------------------------------------------------- -- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the From e199cc1eaf4895f19d87cde4e7cd5bd15fa05e64 Mon Sep 17 00:00:00 2001 From: Benjamin Reese Date: Thu, 5 Sep 2024 21:47:58 -0700 Subject: [PATCH 35/43] Linting --- tests/test_SaciAxiLiteMasterTb.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index 89926f7493..da3b811d33 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -22,7 +22,6 @@ import os import itertools import logging -import random class TB: def __init__(self, dut): @@ -70,8 +69,6 @@ async def run_test_words(dut): tb = TB(dut) - byte_lanes = tb.axil_master.write_if.byte_lanes - await tb.cycle_reset() # Wait for internal reset to fall From 8c3d08712a688249050ab3c37ba4f23ce6829328 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 07:31:18 -0700 Subject: [PATCH 36/43] Update test_SaciAxiLiteMasterTb.py --- tests/test_SaciAxiLiteMasterTb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_SaciAxiLiteMasterTb.py b/tests/test_SaciAxiLiteMasterTb.py index da3b811d33..66812e6d5d 100644 --- a/tests/test_SaciAxiLiteMasterTb.py +++ b/tests/test_SaciAxiLiteMasterTb.py @@ -156,5 +156,5 @@ def test_SaciAxiLiteMasterTb(parameters): ######################################################################## # Dump waveform to file ($ gtkwave sim_build/path/To/{tests_module}.ghw) ######################################################################## - sim_args =[f'--wave={tests_module}.ghw'], + # sim_args =[f'--wave={tests_module}.ghw'], ) From c6a90d40e551eb3a257504381f196a01e7553960 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 08:20:49 -0700 Subject: [PATCH 37/43] copying src from FilMarini:surf:roce fork --- axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd diff --git a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd new file mode 100644 index 0000000000..bea105773f --- /dev/null +++ b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd @@ -0,0 +1,175 @@ +------------------------------------------------------------------------------- +-- Company : SLAC National Accelerator Laboratory +------------------------------------------------------------------------------- +-- Description: +-- Block to compact AXI-Streams if tKeep bits are not contiguous +------------------------------------------------------------------------------- +-- This file is part of 'SLAC Firmware Standard Library'. +-- It is subject to the license terms in the LICENSE.txt file found in the +-- top-level directory of this distribution and at: +-- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html. +-- No part of 'SLAC Firmware Standard Library', including this file, +-- may be copied, modified, propagated, or distributed except according to +-- the terms contained in the LICENSE.txt file. +------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_unsigned.all; +use ieee.std_logic_arith.all; + +library surf; +use surf.StdRtlPkg.all; +use surf.AxiStreamPkg.all; + +entity AxiStreamTrailerRemove is + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + BYTES_TO_RM_G : integer := 4; + AXI_CONFIG_G : AxiStreamConfigType + ); + port ( + axisClk : in sl; + axisRst : in sl; + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType + ); +end entity AxiStreamTrailerRemove; + +architecture rtl of AxiStreamTrailerRemove is + + constant BYTES_C : positive := AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + regularTLast : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + obMaster => axiStreamMasterInit(AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + regularTLast => true + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; + signal axisMasterToPipe : AxiStreamMasterType; + signal axisSlaveToPipe : AxiStreamSlaveType; + signal axisMasterPipe : AxiStreamMasterType; + signal axisSlavePipe : AxiStreamSlaveType; + +begin -- architecture rtl + + -- Make sure data widths are appropriate + assert (BYTES_C >= BYTES_TO_RM_G) + report "Axi-Stream data widths must be greater or equal than trailer" severity failure; + + -- Connect Pipe + axisMasterToPipe <= sAxisMaster; + + -- Generate a delayed copy of incoming stream + AxiStreamPipeline_2 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => 1) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => axisMasterToPipe, + -- sSideBand => sSideBand, + sAxisSlave => axisSlaveToPipe, + mAxisMaster => axisMasterPipe, + -- mSideBand => mSideBand, + mAxisSlave => axisSlavePipe); + + comb : process (pipeAxisSlave, r, sAxisMaster, axisMasterPipe, axisSlaveToPipe) is + variable v : RegType; + variable ibM : AxiStreamMasterType; + variable count : integer range 0 to AXI_CONFIG_G.TDATA_BYTES_C; + variable toRm : integer range 0 to BYTES_TO_RM_G; + begin -- process comb + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + + -- Accept input data + if v.obMaster.tValid = '0' and axisSlaveToPipe.tReady = '1' then + -- Get inbound data + ibM := axisMasterPipe; + v.ibSlave.tReady := '1'; + + if ibM.tValid = '1' and r.regularTLast then + v.obMaster := ibM; + if sAxisMaster.tLast = '1' then + count := getTKeep(sAxisMaster.tKeep, AXI_CONFIG_G); + if count <= BYTES_TO_RM_G then + v.regularTLast := false; + toRm := BYTES_TO_RM_G - count; + v.obMaster.tLast := '1'; + count := getTKeep(ibM.tKeep, AXI_CONFIG_G); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep((count - toRm)-1 downto 0) := (others => '1'); + end if; + end if; + if ibM.tLast = '1' then + count := getTKeep(ibM.tKeep, AXI_CONFIG_G); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep((count - BYTES_TO_RM_G)-1 downto 0) := (others => '1'); + end if; + end if; + end if; + + sAxisSlave <= v.ibSlave; + axisSlavePipe <= pipeAxisSlave; + pipeAxisMaster <= r.obMaster; + + rin <= v; + + end process comb; + + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if (RST_ASYNC_G = false) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); + +end architecture rtl; From 12133e1f371b51c2f1c8c69a16e411f3907b6e54 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 08:22:29 -0700 Subject: [PATCH 38/43] emacs VHDL beautify --- axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd | 277 +++++++++--------- 1 file changed, 138 insertions(+), 139 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd index bea105773f..245b5a90a7 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd @@ -12,6 +12,7 @@ -- may be copied, modified, propagated, or distributed except according to -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- + library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; @@ -22,154 +23,152 @@ use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; entity AxiStreamTrailerRemove is - generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - PIPE_STAGES_G : natural := 0; - BYTES_TO_RM_G : integer := 4; - AXI_CONFIG_G : AxiStreamConfigType - ); - port ( - axisClk : in sl; - axisRst : in sl; - sAxisMaster : in AxiStreamMasterType; - sAxisSlave : out AxiStreamSlaveType; - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType - ); + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + BYTES_TO_RM_G : integer := 4; + AXI_CONFIG_G : AxiStreamConfigType); + port ( + axisClk : in sl; + axisRst : in sl; + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamTrailerRemove; architecture rtl of AxiStreamTrailerRemove is - constant BYTES_C : positive := AXI_CONFIG_G.TDATA_BYTES_C; - - type RegType is record - obMaster : AxiStreamMasterType; - ibSlave : AxiStreamSlaveType; - regularTLast : boolean; - end record RegType; - - constant REG_INIT_C : RegType := ( - obMaster => axiStreamMasterInit(AXI_CONFIG_G), - ibSlave => AXI_STREAM_SLAVE_INIT_C, - regularTLast => true - ); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal pipeAxisMaster : AxiStreamMasterType; - signal pipeAxisSlave : AxiStreamSlaveType; - signal axisMasterToPipe : AxiStreamMasterType; - signal axisSlaveToPipe : AxiStreamSlaveType; - signal axisMasterPipe : AxiStreamMasterType; - signal axisSlavePipe : AxiStreamSlaveType; - -begin -- architecture rtl - - -- Make sure data widths are appropriate - assert (BYTES_C >= BYTES_TO_RM_G) - report "Axi-Stream data widths must be greater or equal than trailer" severity failure; - - -- Connect Pipe - axisMasterToPipe <= sAxisMaster; - - -- Generate a delayed copy of incoming stream - AxiStreamPipeline_2 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => 1) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => axisMasterToPipe, - -- sSideBand => sSideBand, - sAxisSlave => axisSlaveToPipe, - mAxisMaster => axisMasterPipe, - -- mSideBand => mSideBand, - mAxisSlave => axisSlavePipe); - - comb : process (pipeAxisSlave, r, sAxisMaster, axisMasterPipe, axisSlaveToPipe) is - variable v : RegType; - variable ibM : AxiStreamMasterType; - variable count : integer range 0 to AXI_CONFIG_G.TDATA_BYTES_C; - variable toRm : integer range 0 to BYTES_TO_RM_G; - begin -- process comb - v := r; - - -- Init ready - v.ibSlave.tReady := '0'; - - -- Choose ready source and clear valid - if (pipeAxisSlave.tReady = '1') then - v.obMaster.tValid := '0'; - end if; - - -- Accept input data - if v.obMaster.tValid = '0' and axisSlaveToPipe.tReady = '1' then - -- Get inbound data - ibM := axisMasterPipe; - v.ibSlave.tReady := '1'; - - if ibM.tValid = '1' and r.regularTLast then - v.obMaster := ibM; - if sAxisMaster.tLast = '1' then - count := getTKeep(sAxisMaster.tKeep, AXI_CONFIG_G); - if count <= BYTES_TO_RM_G then - v.regularTLast := false; - toRm := BYTES_TO_RM_G - count; - v.obMaster.tLast := '1'; - count := getTKeep(ibM.tKeep, AXI_CONFIG_G); - v.obMaster.tKeep := (others => '0'); - v.obMaster.tKeep((count - toRm)-1 downto 0) := (others => '1'); - end if; - end if; - if ibM.tLast = '1' then - count := getTKeep(ibM.tKeep, AXI_CONFIG_G); - v.obMaster.tKeep := (others => '0'); - v.obMaster.tKeep((count - BYTES_TO_RM_G)-1 downto 0) := (others => '1'); - end if; + constant BYTES_C : positive := AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + regularTLast : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + obMaster => axiStreamMasterInit(AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + regularTLast => true); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; + signal axisMasterToPipe : AxiStreamMasterType; + signal axisSlaveToPipe : AxiStreamSlaveType; + signal axisMasterPipe : AxiStreamMasterType; + signal axisSlavePipe : AxiStreamSlaveType; + +begin + + -- Make sure data widths are appropriate + assert (BYTES_C >= BYTES_TO_RM_G) + report "Axi-Stream data widths must be greater or equal than trailer" severity failure; + + -- Connect Pipe + axisMasterToPipe <= sAxisMaster; + + -- Generate a delayed copy of incoming stream + AxiStreamPipeline_2 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => 1) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => axisMasterToPipe, + -- sSideBand => sSideBand, + sAxisSlave => axisSlaveToPipe, + mAxisMaster => axisMasterPipe, + -- mSideBand => mSideBand, + mAxisSlave => axisSlavePipe); + + comb : process (axisMasterPipe, axisSlaveToPipe, pipeAxisSlave, r, + sAxisMaster) is + variable v : RegType; + variable ibM : AxiStreamMasterType; + variable count : integer range 0 to AXI_CONFIG_G.TDATA_BYTES_C; + variable toRm : integer range 0 to BYTES_TO_RM_G; + begin -- process comb + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + + -- Accept input data + if v.obMaster.tValid = '0' and axisSlaveToPipe.tReady = '1' then + -- Get inbound data + ibM := axisMasterPipe; + v.ibSlave.tReady := '1'; + + if ibM.tValid = '1' and r.regularTLast then + v.obMaster := ibM; + if sAxisMaster.tLast = '1' then + count := getTKeep(sAxisMaster.tKeep, AXI_CONFIG_G); + if count <= BYTES_TO_RM_G then + v.regularTLast := false; + toRm := BYTES_TO_RM_G - count; + v.obMaster.tLast := '1'; + count := getTKeep(ibM.tKeep, AXI_CONFIG_G); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep((count - toRm)-1 downto 0) := (others => '1'); + end if; + end if; + if ibM.tLast = '1' then + count := getTKeep(ibM.tKeep, AXI_CONFIG_G); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep((count - BYTES_TO_RM_G)-1 downto 0) := (others => '1'); + end if; + end if; end if; - end if; - sAxisSlave <= v.ibSlave; - axisSlavePipe <= pipeAxisSlave; - pipeAxisMaster <= r.obMaster; + sAxisSlave <= v.ibSlave; + axisSlavePipe <= pipeAxisSlave; + pipeAxisMaster <= r.obMaster; - rin <= v; + rin <= v; - end process comb; + end process comb; - seq : process (axisClk, axisRst) is - begin - if (RST_ASYNC_G) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + elsif (rising_edge(axisClk)) then + if (RST_ASYNC_G = false) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; + else + r <= rin after TPD_G; + end if; end if; - end if; - end process seq; - - -- Optional output pipeline registers to ease timing - AxiStreamPipeline_1 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => PIPE_STAGES_G) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, - sAxisSlave => pipeAxisSlave, - mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, - mAxisSlave => mAxisSlave); + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); end architecture rtl; From 0a444760d609bbea1a7c51944a4b189fe217f379 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 08:25:24 -0700 Subject: [PATCH 39/43] switch to standard reset convention --- axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd index 245b5a90a7..b916da6bf5 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd @@ -30,10 +30,13 @@ entity AxiStreamTrailerRemove is BYTES_TO_RM_G : integer := 4; AXI_CONFIG_G : AxiStreamConfigType); port ( + -- Clock and Reset axisClk : in sl; axisRst : in sl; + -- Inbound AXI Stream sAxisMaster : in AxiStreamMasterType; sAxisSlave : out AxiStreamSlaveType; + -- Inbound AXI Stream mAxisMaster : out AxiStreamMasterType; mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamTrailerRemove; @@ -89,7 +92,7 @@ begin -- mSideBand => mSideBand, mAxisSlave => axisSlavePipe); - comb : process (axisMasterPipe, axisSlaveToPipe, pipeAxisSlave, r, + comb : process (axisMasterPipe, axisRst, axisSlaveToPipe, pipeAxisSlave, r, sAxisMaster) is variable v : RegType; variable ibM : AxiStreamMasterType; @@ -133,10 +136,17 @@ begin end if; end if; + -- Outputs sAxisSlave <= v.ibSlave; axisSlavePipe <= pipeAxisSlave; pipeAxisMaster <= r.obMaster; + -- Reset + if (RST_ASYNC_G = false and axisRst = '1') then + v := REG_INIT_C; + end if; + + -- Register the variable for next clock cycle rin <= v; end process comb; @@ -145,12 +155,8 @@ begin begin if (RST_ASYNC_G) and (axisRst = '1') then r <= REG_INIT_C after TPD_G; - elsif (rising_edge(axisClk)) then - if (RST_ASYNC_G = false) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; - else - r <= rin after TPD_G; - end if; + elsif rising_edge(axisClk) then + r <= rin after TPD_G; end if; end process seq; @@ -159,16 +165,13 @@ begin generic map ( TPD_G => TPD_G, RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, PIPE_STAGES_G => PIPE_STAGES_G) port map ( axisClk => axisClk, axisRst => axisRst, sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, sAxisSlave => pipeAxisSlave, mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, mAxisSlave => mAxisSlave); end architecture rtl; From 0928e260ceda7b977d2af5a2539cae3ded0da872 Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 08:27:41 -0700 Subject: [PATCH 40/43] updating Description --- axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd index b916da6bf5..f6c29e6595 100644 --- a/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd +++ b/axi/axi-stream/rtl/AxiStreamTrailerRemove.vhd @@ -2,7 +2,7 @@ -- Company : SLAC National Accelerator Laboratory ------------------------------------------------------------------------------- -- Description: --- Block to compact AXI-Streams if tKeep bits are not contiguous +-- Removes bytes from end of a AXI stream frame ------------------------------------------------------------------------------- -- This file is part of 'SLAC Firmware Standard Library'. -- It is subject to the license terms in the LICENSE.txt file found in the From 058f525aa10d05a5c3f3aa50d7543e548e8a0c8e Mon Sep 17 00:00:00 2001 From: Larry Ruckman Date: Fri, 6 Sep 2024 08:32:05 -0700 Subject: [PATCH 41/43] adding future support for RoCEv2 iCRC --- ethernet/UdpEngine/rtl/UdpEngineRx.vhd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ethernet/UdpEngine/rtl/UdpEngineRx.vhd b/ethernet/UdpEngine/rtl/UdpEngineRx.vhd index 5bb594e4b8..fc5269c60b 100644 --- a/ethernet/UdpEngine/rtl/UdpEngineRx.vhd +++ b/ethernet/UdpEngine/rtl/UdpEngineRx.vhd @@ -263,6 +263,10 @@ begin v.byteCnt(7 downto 0) := rxMaster.tData(79 downto 72); -- Remove the 8 byte UDP header v.byteCnt := v.byteCnt - 8; + -- Remove the RoCEv2 iCRC + if rxMaster.tData(63 downto 48) = x"B712" then + v.byteCnt := v.byteCnt - 4; + end if; -- Track the leftovers v.tData(31 downto 0) := rxMaster.tData(127 downto 96); -- Set the flag From 9a26176dd4c4a8538b4c4bfe9e66cd4744c795f0 Mon Sep 17 00:00:00 2001 From: FilMarini Date: Sat, 7 Sep 2024 12:39:08 +0200 Subject: [PATCH 42/43] applied patch to AxiStreamCompact --- axi/axi-stream/rtl/AxiStreamCompact.vhd | 417 ++++++++++++------------ 1 file changed, 209 insertions(+), 208 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamCompact.vhd b/axi/axi-stream/rtl/AxiStreamCompact.vhd index c71c6223a1..f2f8a907e9 100644 --- a/axi/axi-stream/rtl/AxiStreamCompact.vhd +++ b/axi/axi-stream/rtl/AxiStreamCompact.vhd @@ -12,219 +12,218 @@ -- may be copied, modified, propagated, or distributed except according to -- the terms contained in the LICENSE.txt file. ------------------------------------------------------------------------------- - library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -- use ieee.std_logic_arith.all; use ieee.numeric_std.all; + library surf; use surf.StdRtlPkg.all; use surf.AxiStreamPkg.all; entity AxiStreamCompact is - generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - PIPE_STAGES_G : natural := 0; - SLAVE_AXI_CONFIG_G : AxiStreamConfigType; - MASTER_AXI_CONFIG_G : AxiStreamConfigType); - port ( + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + SLAVE_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_AXI_CONFIG_G : AxiStreamConfigType); + port ( -- Clock and Reset - axisClk : in sl; - axisRst : in sl; - -- Slave Port - sAxisMaster : in AxiStreamMasterType; - sAxisSlave : out AxiStreamSlaveType; - -- Master Port - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType); + axisClk : in sl; + axisRst : in sl; + -- Slave Port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Master Port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamCompact; architecture rtl of AxiStreamCompact is - function getTKeepMin ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in 0 to axisConfig.TDATA_BYTES_C-1 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMin; - - function getTKeepMax ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMax; - - constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; - constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; - - type RegType is record - -- count : slv(bitSize(MST_BYTES_C)-1 downto 0); - count : natural; - obMaster : AxiStreamMasterType; - ibSlave : AxiStreamSlaveType; - tLastDet : boolean; - tLastOnNext : boolean; - tUserSet : boolean; - fullBus : boolean; - end record RegType; - - constant REG_INIT_C : RegType := ( - -- count => (others => '0'), - count => 0, - obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), - ibSlave => AXI_STREAM_SLAVE_INIT_C, - tLastDet => false, - tLastOnNext => false, - tUserSet => false, - fullBus => false - ); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal pipeAxisMaster : AxiStreamMasterType; - signal pipeAxisSlave : AxiStreamSlaveType; + function getTKeepMin ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in 0 to axisConfig.TDATA_BYTES_C-1 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMin; + + function getTKeepMax ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMax; + + constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; + constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + count : natural; + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + tLastDet : boolean; + tLastOnNext : boolean; + tUserSet : boolean; + fullBus : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + count => 0, + obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + tLastDet => false, + tLastOnNext => false, + tUserSet => false, + fullBus => false + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; begin -- architecture rtl - -- Make sure data widths are the same - assert (MST_BYTES_C >= SLV_BYTES_C) - report "Master data widths must be greater or equal than slave" severity failure; + -- Make sure data widths are the same + assert (MST_BYTES_C >= SLV_BYTES_C) + report "Master data widths must be greater or equal than slave" severity failure; comb : process (axisRst, pipeAxisSlave, r, sAxisMaster) is - variable v : RegType; - variable tKeepMin : natural; - variable tKeepWidth : natural; - variable tDataWidth : natural; - variable tDataMin : natural; - variable tDataCount : natural; - variable tDataVar : slv(sAxisMaster.tData'range); - begin -- process - -- Latch current value - v := r; - - -- Init ready - v.ibSlave.tReady := '0'; - v.fullBus := false; - v.tLastDet := false; - v.tLastOnNext := false; - - -- Choose ready source and clear valid - if (pipeAxisSlave.tReady = '1') then - v.obMaster.tValid := '0'; - end if; - - -- Accept input data - if v.obMaster.tValid = '0' and not r.tLastOnNext then - - -- Ready to accept - v.ibSlave.tReady := '1'; - - -- Input data is valid - if sAxisMaster.tValid = '1' then - - -- get tKeet boundaries - tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); - tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); - tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); - - -- Checks - -- -- Overflow - if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then - v.fullBus := true; - end if; - -- -- tLast - v.tLastDet := false; - -- v.tLastDet := r.tLastOnNext; - if sAxisMaster.tLast = '1' then - v.tLastDet := true; - if tKeepWidth + r.count > MST_BYTES_C then - v.tLastDet := false; - v.tLastOnNext := true; - end if; - end if; - - -- Gen bus - -- Shift if bus was full - if r.fullBus and not r.tLastOnNext then - v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); - end if; - ---- Remove initial bits - tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); - v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); - v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); - v.obMaster.tKeep := (others => '0'); - v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); - if not r.tUserSet then - v.obMaster.tUser := sAxisMaster.tUser; - v.tUserSet := true; - end if; - - -- Update counter - v.count := r.count + tKeepWidth; - - end if; - end if; - - -- Bus is full - if v.fullBus or v.tLastDet or r.tLastOnNext then - -- Set tValid - v.obMaster.tValid := '1'; - -- Update bit counter and shift data - if v.fullBus then + variable v : RegType; + variable tKeepMin : natural; + variable tKeepWidth : natural; + variable tDataWidth : natural; + variable tDataMin : natural; + variable tDataCount : natural; + variable tDataVar : slv(sAxisMaster.tData'range); + begin -- process + -- Latch current value + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + v.tLastDet := false; + v.tLastOnNext := false; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + + -- Accept input data + if v.obMaster.tValid = '0' and not r.tLastOnNext then + + -- Ready to accept + v.ibSlave.tReady := '1'; + + -- Input data is valid + if sAxisMaster.tValid = '1' then + + -- Reset full flags + v.fullBus := false; + + -- get tKeet boundaries + tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); + tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); + tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); + + -- Checks + -- -- Overflow + if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then + v.fullBus := true; + end if; + -- -- tLast + v.tLastDet := false; + if sAxisMaster.tLast = '1' then + v.tLastDet := true; + if tKeepWidth + r.count > MST_BYTES_C then + v.tLastDet := false; + v.tLastOnNext := true; + end if; + end if; + + -- Gen bus + -- Shift if bus was full + if r.fullBus and not r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + end if; + ---- Remove initial bits + tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); + v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); + v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); + if not r.tUserSet then + v.obMaster.tUser := sAxisMaster.tUser; + v.tUserSet := true; + end if; + + -- Update counter + v.count := r.count + tKeepWidth; + + -- Bus is full + if v.fullBus or v.tLastDet or r.tLastOnNext then + -- Set tValid + v.obMaster.tValid := '1'; + -- Update bit counter and shift data + if v.fullBus then v.count := r.count + tKeepWidth - MST_BYTES_C; - else + else v.count := 0; - end if; - -- Set tLast - if v.tLastDet and not v.tLastOnNext then + end if; + -- Set tLast + if v.tLastDet and not v.tLastOnNext then v.obMaster.tLast := '1'; - else + else v.obMaster.tLast := '0'; - end if; - -- Set tData in case of forced tLast - if r.tLastOnNext then + end if; + -- Set tData in case of forced tLast + if r.tLastOnNext then v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); v.obMaster.tLast := '1'; - end if; - v.tUserSet := false; + end if; + v.tUserSet := false; + end if; + end if; + end if; + - -- Outputs - sAxisSlave <= v.ibSlave; - pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); - pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); - pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); - pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); - pipeAxisMaster.tValid <= r.obMaster.tValid; - pipeAxisMaster.tUser <= r.obMaster.tUser; - pipeAxisMaster.tLast <= r.obMaster.tLast; + sAxisSlave <= v.ibSlave; + pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); + pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); + pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); + pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); + pipeAxisMaster.tValid <= r.obMaster.tValid; + pipeAxisMaster.tUser <= r.obMaster.tUser; + pipeAxisMaster.tLast <= r.obMaster.tLast; -- Reset if (RST_ASYNC_G = false and axisRst = '1') then @@ -232,34 +231,36 @@ begin -- architecture rtl end if; -- Register the variable for next clock cycle - rin <= v; + rin <= v; - end process comb; - seq : process (axisClk, axisRst) is - begin - if (RST_ASYNC_G) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; + end process comb; + + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; elsif rising_edge(axisClk) then - r <= rin after TPD_G; - end if; - end process seq; - - -- Optional output pipeline registers to ease timing - AxiStreamPipeline_1 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => PIPE_STAGES_G) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, - sAxisSlave => pipeAxisSlave, - mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, - mAxisSlave => mAxisSlave); + r <= rin after TPD_G; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); + end architecture rtl; From 645e23ae93f69622dcb395d292d95deb16f726ce Mon Sep 17 00:00:00 2001 From: FilMarini Date: Mon, 9 Sep 2024 09:56:00 +0200 Subject: [PATCH 43/43] applied SLAC emacs beautify --- axi/axi-stream/rtl/AxiStreamCompact.vhd | 422 ++++++++++++------------ 1 file changed, 211 insertions(+), 211 deletions(-) diff --git a/axi/axi-stream/rtl/AxiStreamCompact.vhd b/axi/axi-stream/rtl/AxiStreamCompact.vhd index f2f8a907e9..c1b020e8c7 100644 --- a/axi/axi-stream/rtl/AxiStreamCompact.vhd +++ b/axi/axi-stream/rtl/AxiStreamCompact.vhd @@ -25,205 +25,205 @@ use surf.AxiStreamPkg.all; entity AxiStreamCompact is - generic ( - TPD_G : time := 1 ns; - RST_ASYNC_G : boolean := false; - PIPE_STAGES_G : natural := 0; - SLAVE_AXI_CONFIG_G : AxiStreamConfigType; - MASTER_AXI_CONFIG_G : AxiStreamConfigType); - port ( + generic ( + TPD_G : time := 1 ns; + RST_ASYNC_G : boolean := false; + PIPE_STAGES_G : natural := 0; + SLAVE_AXI_CONFIG_G : AxiStreamConfigType; + MASTER_AXI_CONFIG_G : AxiStreamConfigType); + port ( -- Clock and Reset - axisClk : in sl; - axisRst : in sl; - -- Slave Port - sAxisMaster : in AxiStreamMasterType; - sAxisSlave : out AxiStreamSlaveType; - -- Master Port - mAxisMaster : out AxiStreamMasterType; - mAxisSlave : in AxiStreamSlaveType); + axisClk : in sl; + axisRst : in sl; + -- Slave Port + sAxisMaster : in AxiStreamMasterType; + sAxisSlave : out AxiStreamSlaveType; + -- Master Port + mAxisMaster : out AxiStreamMasterType; + mAxisSlave : in AxiStreamSlaveType); end entity AxiStreamCompact; architecture rtl of AxiStreamCompact is - function getTKeepMin ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in 0 to axisConfig.TDATA_BYTES_C-1 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMin; - - function getTKeepMax ( - tKeep : slv; - axisConfig : AxiStreamConfigType - ) - return natural is - variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); - variable i : natural; - begin -- function getTKeepRange - tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); - for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop - if tKeepFull(i) = '1' then - return i; - end if; - end loop; -- i - end function getTKeepMax; - - constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; - constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; - - type RegType is record - count : natural; - obMaster : AxiStreamMasterType; - ibSlave : AxiStreamSlaveType; - tLastDet : boolean; - tLastOnNext : boolean; - tUserSet : boolean; - fullBus : boolean; - end record RegType; - - constant REG_INIT_C : RegType := ( - count => 0, - obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), - ibSlave => AXI_STREAM_SLAVE_INIT_C, - tLastDet => false, - tLastOnNext => false, - tUserSet => false, - fullBus => false - ); - - signal r : RegType := REG_INIT_C; - signal rin : RegType; - - signal pipeAxisMaster : AxiStreamMasterType; - signal pipeAxisSlave : AxiStreamSlaveType; + function getTKeepMin ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in 0 to axisConfig.TDATA_BYTES_C-1 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMin; + + function getTKeepMax ( + tKeep : slv; + axisConfig : AxiStreamConfigType + ) + return natural is + variable tKeepFull : slv(AXI_STREAM_MAX_TKEEP_WIDTH_C-1 downto 0); + variable i : natural; + begin -- function getTKeepRange + tKeepFull := resize(tKeep, AXI_STREAM_MAX_TKEEP_WIDTH_C); + for i in axisConfig.TDATA_BYTES_C-1 downto 0 loop + if tKeepFull(i) = '1' then + return i; + end if; + end loop; -- i + end function getTKeepMax; + + constant SLV_BYTES_C : positive := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C; + constant MST_BYTES_C : positive := MASTER_AXI_CONFIG_G.TDATA_BYTES_C; + + type RegType is record + count : natural; + obMaster : AxiStreamMasterType; + ibSlave : AxiStreamSlaveType; + tLastDet : boolean; + tLastOnNext : boolean; + tUserSet : boolean; + fullBus : boolean; + end record RegType; + + constant REG_INIT_C : RegType := ( + count => 0, + obMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G), + ibSlave => AXI_STREAM_SLAVE_INIT_C, + tLastDet => false, + tLastOnNext => false, + tUserSet => false, + fullBus => false + ); + + signal r : RegType := REG_INIT_C; + signal rin : RegType; + + signal pipeAxisMaster : AxiStreamMasterType; + signal pipeAxisSlave : AxiStreamSlaveType; begin -- architecture rtl - -- Make sure data widths are the same - assert (MST_BYTES_C >= SLV_BYTES_C) - report "Master data widths must be greater or equal than slave" severity failure; + -- Make sure data widths are the same + assert (MST_BYTES_C >= SLV_BYTES_C) + report "Master data widths must be greater or equal than slave" severity failure; comb : process (axisRst, pipeAxisSlave, r, sAxisMaster) is - variable v : RegType; - variable tKeepMin : natural; - variable tKeepWidth : natural; - variable tDataWidth : natural; - variable tDataMin : natural; - variable tDataCount : natural; - variable tDataVar : slv(sAxisMaster.tData'range); - begin -- process - -- Latch current value - v := r; - - -- Init ready - v.ibSlave.tReady := '0'; - v.tLastDet := false; - v.tLastOnNext := false; - - -- Choose ready source and clear valid - if (pipeAxisSlave.tReady = '1') then - v.obMaster.tValid := '0'; - end if; - - -- Accept input data - if v.obMaster.tValid = '0' and not r.tLastOnNext then - - -- Ready to accept - v.ibSlave.tReady := '1'; - - -- Input data is valid - if sAxisMaster.tValid = '1' then - - -- Reset full flags - v.fullBus := false; - - -- get tKeet boundaries - tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); - tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); - tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); - tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); - - -- Checks - -- -- Overflow - if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then - v.fullBus := true; - end if; - -- -- tLast - v.tLastDet := false; - if sAxisMaster.tLast = '1' then - v.tLastDet := true; - if tKeepWidth + r.count > MST_BYTES_C then - v.tLastDet := false; - v.tLastOnNext := true; - end if; - end if; - - -- Gen bus - -- Shift if bus was full - if r.fullBus and not r.tLastOnNext then - v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); - end if; - ---- Remove initial bits - tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); - v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); - v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); - v.obMaster.tKeep := (others => '0'); - v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); - if not r.tUserSet then - v.obMaster.tUser := sAxisMaster.tUser; - v.tUserSet := true; - end if; - - -- Update counter - v.count := r.count + tKeepWidth; - - -- Bus is full - if v.fullBus or v.tLastDet or r.tLastOnNext then - -- Set tValid - v.obMaster.tValid := '1'; - -- Update bit counter and shift data - if v.fullBus then - v.count := r.count + tKeepWidth - MST_BYTES_C; - else - v.count := 0; - end if; - -- Set tLast - if v.tLastDet and not v.tLastOnNext then - v.obMaster.tLast := '1'; - else - v.obMaster.tLast := '0'; - end if; - -- Set tData in case of forced tLast - if r.tLastOnNext then - v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); - v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); - v.obMaster.tLast := '1'; - end if; - v.tUserSet := false; - end if; + variable v : RegType; + variable tKeepMin : natural; + variable tKeepWidth : natural; + variable tDataWidth : natural; + variable tDataMin : natural; + variable tDataCount : natural; + variable tDataVar : slv(sAxisMaster.tData'range); + begin -- process + -- Latch current value + v := r; + + -- Init ready + v.ibSlave.tReady := '0'; + v.tLastDet := false; + v.tLastOnNext := false; + + -- Choose ready source and clear valid + if (pipeAxisSlave.tReady = '1') then + v.obMaster.tValid := '0'; + end if; + -- Accept input data + if v.obMaster.tValid = '0' and not r.tLastOnNext then + + -- Ready to accept + v.ibSlave.tReady := '1'; + + -- Input data is valid + if sAxisMaster.tValid = '1' then + + -- Reset full flags + v.fullBus := false; + + -- get tKeet boundaries + tKeepMin := getTKeepMin(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tKeepWidth := getTKeep(sAxisMaster.tKeep, SLAVE_AXI_CONFIG_G); + tDataWidth := to_integer(shift_left(to_unsigned(tKeepWidth, SLV_BYTES_C), 3)); + tDataCount := to_integer(shift_left(to_unsigned(r.count, SLV_BYTES_C), 3)); + tDataMin := to_integer(shift_left(to_unsigned(tKeepMin, SLV_BYTES_C), 3)); + + -- Checks + -- -- Overflow + if tKeepWidth + r.count >= MASTER_AXI_CONFIG_G.TDATA_BYTES_C then + v.fullBus := true; + end if; + -- -- tLast + v.tLastDet := false; + if sAxisMaster.tLast = '1' then + v.tLastDet := true; + if tKeepWidth + r.count > MST_BYTES_C then + v.tLastDet := false; + v.tLastOnNext := true; + end if; + end if; + + -- Gen bus + -- Shift if bus was full + if r.fullBus and not r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + end if; + ---- Remove initial bits + tDataVar := std_logic_vector(shift_right(unsigned(sAxisMaster.tData), tDataMin)); + v.obMaster.tData(v.obMaster.tData'length-1 downto tDataCount+tDataWidth) := (others => '0'); + v.obMaster.tData(tDataCount+tDataWidth-1 downto tDataCount) := tDataVar(tDataWidth-1 downto 0); + v.obMaster.tKeep := (others => '0'); + v.obMaster.tKeep(r.count+tKeepWidth-1 downto 0) := (others => '1'); + if not r.tUserSet then + v.obMaster.tUser := sAxisMaster.tUser; + v.tUserSet := true; + end if; + + -- Update counter + v.count := r.count + tKeepWidth; + + -- Bus is full + if v.fullBus or v.tLastDet or r.tLastOnNext then + -- Set tValid + v.obMaster.tValid := '1'; + -- Update bit counter and shift data + if v.fullBus then + v.count := r.count + tKeepWidth - MST_BYTES_C; + else + v.count := 0; + end if; + -- Set tLast + if v.tLastDet and not v.tLastOnNext then + v.obMaster.tLast := '1'; + else + v.obMaster.tLast := '0'; + end if; + -- Set tData in case of forced tLast + if r.tLastOnNext then + v.obMaster.tData := std_logic_vector(shift_right(unsigned(r.obMaster.tData), MST_BYTES_C*8)); + v.obMaster.tKeep := std_logic_vector(shift_right(unsigned(r.obMaster.tKeep), MST_BYTES_C)); + v.obMaster.tLast := '1'; + end if; + v.tUserSet := false; + end if; + + end if; end if; - end if; - sAxisSlave <= v.ibSlave; - pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); - pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); - pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); - pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); - pipeAxisMaster.tValid <= r.obMaster.tValid; - pipeAxisMaster.tUser <= r.obMaster.tUser; - pipeAxisMaster.tLast <= r.obMaster.tLast; + sAxisSlave <= v.ibSlave; + pipeAxisMaster.tData(pipeAxisMaster.tData'length-1 downto MST_BYTES_C*8) <= (others => '0'); + pipeAxisMaster.tData((MST_BYTES_C*8)-1 downto 0) <= r.obMaster.tData((MST_BYTES_C*8)-1 downto 0); + pipeAxisMaster.tKeep(pipeAxisMaster.tKeep'length-1 downto MST_BYTES_C) <= (others => '0'); + pipeAxisMaster.tKeep((MST_BYTES_C)-1 downto 0) <= r.obMaster.tKeep((MST_BYTES_C)-1 downto 0); + pipeAxisMaster.tValid <= r.obMaster.tValid; + pipeAxisMaster.tUser <= r.obMaster.tUser; + pipeAxisMaster.tLast <= r.obMaster.tLast; -- Reset if (RST_ASYNC_G = false and axisRst = '1') then @@ -231,36 +231,36 @@ begin -- architecture rtl end if; -- Register the variable for next clock cycle - rin <= v; + rin <= v; - end process comb; + end process comb; - seq : process (axisClk, axisRst) is - begin - if (RST_ASYNC_G) and (axisRst = '1') then - r <= REG_INIT_C after TPD_G; + seq : process (axisClk, axisRst) is + begin + if (RST_ASYNC_G) and (axisRst = '1') then + r <= REG_INIT_C after TPD_G; elsif rising_edge(axisClk) then - r <= rin after TPD_G; - end if; - end process seq; - - -- Optional output pipeline registers to ease timing - AxiStreamPipeline_1 : entity surf.AxiStreamPipeline - generic map ( - TPD_G => TPD_G, - RST_ASYNC_G => RST_ASYNC_G, - -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, - PIPE_STAGES_G => PIPE_STAGES_G) - port map ( - axisClk => axisClk, - axisRst => axisRst, - sAxisMaster => pipeAxisMaster, - -- sSideBand => pipeSideBand, - sAxisSlave => pipeAxisSlave, - mAxisMaster => mAxisMaster, - -- mSideBand => mSideBand, - mAxisSlave => mAxisSlave); + r <= rin after TPD_G; + end if; + end process seq; + + -- Optional output pipeline registers to ease timing + AxiStreamPipeline_1 : entity surf.AxiStreamPipeline + generic map ( + TPD_G => TPD_G, + RST_ASYNC_G => RST_ASYNC_G, + -- SIDE_BAND_WIDTH_G => SIDE_BAND_WIDTH_G, + PIPE_STAGES_G => PIPE_STAGES_G) + port map ( + axisClk => axisClk, + axisRst => axisRst, + sAxisMaster => pipeAxisMaster, + -- sSideBand => pipeSideBand, + sAxisSlave => pipeAxisSlave, + mAxisMaster => mAxisMaster, + -- mSideBand => mSideBand, + mAxisSlave => mAxisSlave); end architecture rtl;