diff --git a/axi/axi4/rtl/AxiPkg.vhd b/axi/axi4/rtl/AxiPkg.vhd index 528c6bfeb5..42bb8e0e7f 100644 --- a/axi/axi4/rtl/AxiPkg.vhd +++ b/axi/axi4/rtl/AxiPkg.vhd @@ -261,8 +261,29 @@ package AxiPkg is totalBytes : slv; address : slv) return slv; - - -- Caclulate the byte count for a read request + + type AxiLenType is record + valid : slv(1 downto 0); + max : natural; -- valid(0) + req : natural; -- valid(0) + value : slv(7 downto 0);-- valid(1) + end record AxiLenType; + constant AXI_LEN_INIT_C : AxiLenType := ( + valid => "00", + value => (others => '0'), + max => 0, + req => 0); + procedure getAxiLenProc ( + -- Input + axiConfig : in AxiConfigType; + burstBytes : in integer range 1 to 4096 := 4096; + totalBytes : in slv; + address : in slv; + -- Pipelined signals + r : in AxiLenType; + v : inout AxiLenType); + + -- Calculate the byte count for a read request function getAxiReadBytes ( axiConfig : AxiConfigType; axiRead : AxiReadMasterType) @@ -369,6 +390,52 @@ package body AxiPkg is return getAxiLen(axiConfig, min); end function getAxiLen; + + -- getAxiLenProc is functionally the same as getAxiLen() + -- but breaks apart the two comparator operations in getAxiLen() + -- into two separate clock cycles (instead of one), which helps + -- with meeting timing by breaking apart this long combinatorial chain + procedure getAxiLenProc ( + -- Input + axiConfig : in AxiConfigType; + burstBytes : in integer range 1 to 4096 := 4096; + totalBytes : in slv; + address : in slv; + -- Pipelined signals + r : in AxiLenType; + v : inout AxiLenType) is + variable min : natural; + begin + + -------------------- + -- First Clock cycle + -------------------- + + -- Update valid flag for max/req + v.valid(0) := '1'; + + -- Check for 4kB boundary + v.max := 4096 - conv_integer(unsigned(address(11 downto 0))); + + if (totalBytes < burstBytes) then + v.req := conv_integer(totalBytes); + else + v.req := burstBytes; + end if; + + --------------------- + -- Second Clock cycle + --------------------- + + -- Update valid flag for value + v.valid(1) := r.valid(0); + + min := minimum(r.req, r.max); + + -- Return the AXI Length value + v.value := getAxiLen(axiConfig, min); + + end procedure; -- Calculate the byte count for a read request function getAxiReadBytes ( diff --git a/axi/dma/rtl/AxiStreamDmaV2Read.vhd b/axi/dma/rtl/AxiStreamDmaV2Read.vhd index c999fe7449..e58323cf5c 100644 --- a/axi/dma/rtl/AxiStreamDmaV2Read.vhd +++ b/axi/dma/rtl/AxiStreamDmaV2Read.vhd @@ -87,6 +87,7 @@ architecture rtl of AxiStreamDmaV2Read is dmaRdDescRet : AxiReadDmaDescRetType; first : sl; leftovers : sl; + axiLen : AxiLenType; rMaster : AxiReadMasterType; sMaster : AxiStreamMasterType; reqState : ReqStateType; @@ -105,6 +106,7 @@ architecture rtl of AxiStreamDmaV2Read is dmaRdDescRet => AXI_READ_DMA_DESC_RET_INIT_C, first => '0', leftovers => '0', + axiLen => AXI_LEN_INIT_C, rMaster => axiReadMasterInit(AXI_CONFIG_G, "01", "0000"), sMaster => axiStreamMasterInit(AXIS_CONFIG_G), reqState => IDLE_S, @@ -237,12 +239,14 @@ begin end if; ---------------------------------------------------------------------- when ADDR_S => + -- Determine transfer size aligned to 4k boundaries + getAxiLenProc(AXI_CONFIG_G, BURST_BYTES_G, r.reqSize, r.dmaRdDescReq.address,r.axiLen,v.axiLen); -- Check if ready to make memory request - if (r.rMaster.arvalid = '0') then + if (r.rMaster.arvalid = '0') and (v.axiLen.valid = "11") then -- Set the memory address v.rMaster.araddr(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0) := r.dmaRdDescReq.address(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0); - -- Determine transfer size aligned to 4k boundaries - v.rMaster.arlen := getAxiLen(AXI_CONFIG_G, BURST_BYTES_G, r.reqSize, r.dmaRdDescReq.address); + -- Latch AXI arlen value + v.rMaster.arlen := v.axiLen.value; -- Check for the following: -- 1) There is enough room in the FIFO for a burst -- 2) pending flag @@ -250,6 +254,7 @@ begin if (pause = '0') and (r.pending = false) and (notReqDone = '1') then -- Set the flag v.rMaster.arvalid := '1'; + v.axiLen.valid := "00"; -- Next state v.state := MOVE_S; v.reqState := NEXT_S; diff --git a/axi/dma/rtl/AxiStreamDmaV2Write.vhd b/axi/dma/rtl/AxiStreamDmaV2Write.vhd index cda42c7601..5a082ad025 100644 --- a/axi/dma/rtl/AxiStreamDmaV2Write.vhd +++ b/axi/dma/rtl/AxiStreamDmaV2Write.vhd @@ -83,6 +83,7 @@ architecture rtl of AxiStreamDmaV2Write is ackCount : slv(31 downto 0); stCount : slv(15 downto 0); awlen : slv(AXI_CONFIG_G.LEN_BITS_C-1 downto 0); + axiLen : AxiLenType; wMaster : AxiWriteMasterType; slave : AxiStreamSlaveType; state : StateType; @@ -100,6 +101,7 @@ architecture rtl of AxiStreamDmaV2Write is ackCount => (others => '0'), stCount => (others => '0'), awlen => (others => '0'), + axiLen => AXI_LEN_INIT_C, wMaster => axiWriteMasterInit(AXI_CONFIG_G, '1', "01", "0000"), slave => AXI_STREAM_SLAVE_INIT_C, state => RESET_S, @@ -263,19 +265,21 @@ begin v.stCount := (others=>'0'); v.continue := '0'; v.lastUser := (others=>'0'); + -- Determine transfer size aligned to 4k boundaries + getAxiLenProc(AXI_CONFIG_G,BURST_BYTES_G,r.dmaWrTrack.maxSize,r.dmaWrTrack.address,r.axiLen,v.axiLen); -- Address can be sent - if (v.wMaster.awvalid = '0') then + if (v.wMaster.awvalid = '0') and (v.axiLen.valid = "11") then -- Set the memory address v.wMaster.awaddr(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0) := r.dmaWrTrack.address(AXI_CONFIG_G.ADDR_WIDTH_C-1 downto 0); - -- Determine transfer size aligned to 4k boundaries - v.wMaster.awlen := getAxiLen(AXI_CONFIG_G,BURST_BYTES_G,r.dmaWrTrack.maxSize,r.dmaWrTrack.address); -- Latch AXI awlen value - v.awlen := v.wMaster.awlen(AXI_CONFIG_G.LEN_BITS_C-1 downto 0); + v.wMaster.awlen := v.axiLen.value; + v.awlen := v.axiLen.value(AXI_CONFIG_G.LEN_BITS_C-1 downto 0); -- Check if enough room if pause = '0' then -- Set the flag v.wMaster.awvalid := '1'; + v.axiLen.valid := "00"; -- Increment the counter v.reqCount := r.reqCount + 1; -- Next state diff --git a/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.dcp b/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.dcp index 74c0f93fe5..fa2046f045 100644 --- a/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.dcp +++ b/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.dcp @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:080a653c3311d64e54afa33654bbe9045c4084a6e0ab33a236f1492c1a748bd2 -size 979654 +oid sha256:53c4bd51276d972e622a82cb20d3f6e0cac93e83b82959f6880f2e91b481e1c3 +size 935137 diff --git a/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.xci b/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.xci index 75c29cec09..cfc3ee312d 100644 --- a/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.xci +++ b/ethernet/TenGigEthCore/gtx7/ip/TenGigEthGtx7Core.xci @@ -35,7 +35,7 @@ 156.25 0 Time_of_day - false + true false false BASE-R @@ -47,27 +47,28 @@ kintex7 xc7k325t - ffg676 - VERILOG + ffg900 + VHDL MIXED -2 - C + TRUE TRUE IP_Flow - 2 + 7 TRUE . . - 2015.3 + 2016.4 OUT_OF_CONTEXT + diff --git a/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7.vhd b/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7.vhd index e6edc2833a..59cf3df828 100644 --- a/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7.vhd +++ b/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7.vhd @@ -2,7 +2,7 @@ -- File : TenGigEthGtx7.vhd -- Company : SLAC National Accelerator Laboratory -- Created : 2015-02-12 --- Last update: 2018-01-08 +-- Last update: 2018-07-30 ------------------------------------------------------------------------------- -- Description: 10GBASE-R Ethernet for Gtx7 ------------------------------------------------------------------------------- @@ -26,11 +26,11 @@ use work.EthMacPkg.all; entity TenGigEthGtx7 is generic ( - TPD_G : time := 1 ns; + TPD_G : time := 1 ns; -- AXI-Lite Configurations - EN_AXI_REG_G : boolean := false; + EN_AXI_REG_G : boolean := false; -- AXI Streaming Configurations - AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); + AXIS_CONFIG_G : AxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C); port ( -- Local Configurations localMac : in slv(47 downto 0) := MAC_ADDR_INIT_C; @@ -53,10 +53,16 @@ entity TenGigEthGtx7 is txFault : in sl := '0'; txDisable : out sl; -- Misc. Signals - extRst : in sl; + extRst : in sl := '0'; phyClk : in sl; phyRst : in sl; phyReady : out sl; + -- Transceiver Debug Interface + gtTxPreCursor : in slv(4 downto 0) := "00000"; + gtTxPostCursor : in slv(4 downto 0) := "00000"; + gtTxDiffCtrl : in slv(3 downto 0) := "1110"; + gtRxPolarity : in sl := '0'; + gtTxPolarity : in sl := '0'; -- Quad PLL Ports qplllock : in sl; qplloutclk : in sl; @@ -66,7 +72,7 @@ entity TenGigEthGtx7 is gtTxP : out sl; gtTxN : out sl; gtRxP : in sl; - gtRxN : in sl); + gtRxN : in sl); end TenGigEthGtx7; architecture mapping of TenGigEthGtx7 is @@ -119,7 +125,28 @@ architecture mapping of TenGigEthGtx7 is drp_drdy_i : in std_logic; drp_drpdo_i : in std_logic_vector(15 downto 0); tx_disable : out std_logic; - pma_pmd_type : in std_logic_vector(2 downto 0)); + pma_pmd_type : in std_logic_vector(2 downto 0); + gt0_eyescanreset : in std_logic; + gt0_eyescandataerror : out std_logic; + gt0_txbufstatus : out std_logic_vector(1 downto 0); + gt0_rxbufstatus : out std_logic_vector(2 downto 0); + gt0_eyescantrigger : in std_logic; + gt0_rxcdrhold : in std_logic; + gt0_txprbsforceerr : in std_logic; + gt0_txpolarity : in std_logic; + gt0_rxpolarity : in std_logic; + gt0_rxprbserr : out std_logic; + gt0_txpmareset : in std_logic; + gt0_rxpmareset : in std_logic; + gt0_txresetdone : out std_logic; + gt0_rxresetdone : out std_logic; + gt0_rxdfelpmreset : in std_logic; + gt0_rxlpmen : in std_logic; + gt0_dmonitorout : out std_logic_vector(7 downto 0); + gt0_rxrate : in std_logic_vector(2 downto 0); + gt0_txprecursor : in std_logic_vector(4 downto 0); + gt0_txpostcursor : in std_logic_vector(4 downto 0); + gt0_txdiffctrl : in std_logic_vector(3 downto 0)); end component; signal mAxiReadMaster : AxiLiteReadMasterType; @@ -155,7 +182,7 @@ architecture mapping of TenGigEthGtx7 is signal macRxAxisCtrl : AxiStreamCtrlType; signal macTxAxisMaster : AxiStreamMasterType; signal macTxAxisSlave : AxiStreamSlaveType; - + begin phyReady <= status.phyReady; @@ -182,7 +209,7 @@ begin mAxiReadMaster => mAxiReadMaster, mAxiReadSlave => mAxiReadSlave, mAxiWriteMaster => mAxiWriteMaster, - mAxiWriteSlave => mAxiWriteSlave); + mAxiWriteSlave => mAxiWriteSlave); txDisable <= status.txDisable; @@ -199,7 +226,7 @@ begin -- Output dataOut(0) => status.sigDet, dataOut(1) => status.txFault, - dataOut(2) => status.txUsrRdy); + dataOut(2) => status.txUsrRdy); -------------------- -- Ethernet MAC core @@ -227,7 +254,7 @@ begin xgmiiRxd => phyRxd, xgmiiRxc => phyRxc, xgmiiTxd => phyTxd, - xgmiiTxc => phyTxc); + xgmiiTxc => phyTxc); ----------------- -- 10GBASE-R core @@ -288,7 +315,29 @@ begin drp_daddr_i => drpAddr, drp_di_i => drpDi, drp_drdy_i => drpRdy, - drp_drpdo_i => drpDo); + drp_drpdo_i => drpDo, + -- Transceiver Debug Interface + gt0_eyescanreset => '0', + gt0_eyescandataerror => open, + gt0_txbufstatus => open, + gt0_rxbufstatus => open, + gt0_eyescantrigger => '0', + gt0_rxcdrhold => '0', + gt0_txprbsforceerr => '0', + gt0_txpolarity => gtTxPolarity, + gt0_rxpolarity => gtRxPolarity, + gt0_rxprbserr => open, + gt0_txpmareset => '0', + gt0_rxpmareset => '0', + gt0_txresetdone => open, + gt0_rxresetdone => open, + gt0_rxdfelpmreset => '0', + gt0_rxlpmen => '0', + gt0_dmonitorout => open, + gt0_rxrate => (others => '0'), + gt0_txprecursor => gtTxPreCursor, + gt0_txpostcursor => gtTxPostCursor, + gt0_txdiffctrl => gtTxDiffCtrl); ------------------------------------- -- 10GBASE-R's Reset Module @@ -310,7 +359,7 @@ begin rstCntDone => status.rstCntDone, -- Quad PLL Ports qplllock => status.qplllock, - qpllRst => qpllRst); + qpllRst => qpllRst); ------------------------------- -- Configuration Vector Mapping @@ -331,8 +380,8 @@ begin -------------------------------- U_TenGigEthReg : entity work.TenGigEthReg generic map ( - TPD_G => TPD_G, - EN_AXI_REG_G => EN_AXI_REG_G) + TPD_G => TPD_G, + EN_AXI_REG_G => EN_AXI_REG_G) port map ( -- Local Configurations localMac => localMac, @@ -346,6 +395,6 @@ begin axiWriteSlave => mAxiWriteSlave, -- Configuration and Status Interface config => config, - status => status); + status => status); end mapping; diff --git a/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7Wrapper.vhd b/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7Wrapper.vhd index 13ae3746bf..1056a02287 100644 --- a/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7Wrapper.vhd +++ b/ethernet/TenGigEthCore/gtx7/rtl/TenGigEthGtx7Wrapper.vhd @@ -59,10 +59,16 @@ entity TenGigEthGtx7Wrapper is txFault : in slv(NUM_LANE_G-1 downto 0) := (others => '0'); txDisable : out slv(NUM_LANE_G-1 downto 0); -- Misc. Signals - extRst : in sl; + extRst : in sl := '0'; phyClk : out sl; phyRst : out sl; phyReady : out slv(NUM_LANE_G-1 downto 0); + -- Transceiver Debug Interface + gtTxPreCursor : in slv(4 downto 0) := "00000"; + gtTxPostCursor : in slv(4 downto 0) := "00000"; + gtTxDiffCtrl : in slv(3 downto 0) := "1110"; + gtRxPolarity : in sl := '0'; + gtTxPolarity : in sl := '0'; -- MGT Clock Port (156.25 MHz or 312.5 MHz) gtRefClk : in sl := '0'; -- 156.25 MHz only gtClkP : in sl := '1'; @@ -158,6 +164,12 @@ begin phyClk => phyClock, phyRst => phyReset, phyReady => phyReady(i), + -- Transceiver Debug Interface + gtTxPreCursor => gtTxPreCursor, + gtTxPostCursor => gtTxPostCursor, + gtTxDiffCtrl => gtTxDiffCtrl, + gtRxPolarity => gtRxPolarity, + gtTxPolarity => gtTxPolarity, -- Quad PLL Ports qplllock => qplllock, qplloutclk => qplloutclk, diff --git a/ethernet/TenGigEthCore/gtx7/ruckus.tcl b/ethernet/TenGigEthCore/gtx7/ruckus.tcl index 449f2f99e8..74be665135 100644 --- a/ethernet/TenGigEthCore/gtx7/ruckus.tcl +++ b/ethernet/TenGigEthCore/gtx7/ruckus.tcl @@ -2,7 +2,7 @@ source -quiet $::env(RUCKUS_DIR)/vivado_proc.tcl # Load Source Code -if { $::env(VIVADO_VERSION) >= 2015.3 } { +if { $::env(VIVADO_VERSION) >= 2016.4 } { loadSource -dir "$::DIR_PATH/rtl" @@ -10,5 +10,5 @@ if { $::env(VIVADO_VERSION) >= 2015.3 } { loadSource -path "$::DIR_PATH/ip/TenGigEthGtx7Core.dcp" } else { - puts "\n\nWARNING: $::DIR_PATH requires Vivado 2015.3 (or later)\n\n" + puts "\n\nWARNING: $::DIR_PATH requires Vivado 2016.4 (or later)\n\n" } \ No newline at end of file diff --git a/ethernet/UdpEngine/rtl/UdpEngineDhcp.vhd b/ethernet/UdpEngine/rtl/UdpEngineDhcp.vhd index 526654e32b..a92c265314 100644 --- a/ethernet/UdpEngine/rtl/UdpEngineDhcp.vhd +++ b/ethernet/UdpEngine/rtl/UdpEngineDhcp.vhd @@ -2,7 +2,7 @@ -- File : UdpEngineDhcp.vhd -- Company : SLAC National Accelerator Laboratory -- Created : 2016-08-12 --- Last update: 2017-05-10 +-- Last update: 2018-08-02 ------------------------------------------------------------------------------- -- Description: DHCP Engine ------------------------------------------------------------------------------- @@ -34,9 +34,9 @@ entity UdpEngineDhcp is COMM_TIMEOUT_G : positive := 30); port ( -- Local Configurations - localMac : in slv(47 downto 0); -- big-Endian configuration - localIp : in slv(31 downto 0); -- big-Endian configuration - dhcpIp : out slv(31 downto 0); -- big-Endian configuration + localMac : in slv(47 downto 0); -- big-Endian configuration + localIp : in slv(31 downto 0); -- big-Endian configuration + dhcpIp : out slv(31 downto 0); -- big-Endian configuration -- Interface to DHCP Engine ibDhcpMaster : in AxiStreamMasterType; ibDhcpSlave : out AxiStreamSlaveType; @@ -130,8 +130,12 @@ architecture rtl of UdpEngineDhcp is signal txMaster : AxiStreamMasterType; signal txSlave : AxiStreamSlaveType; - -- attribute dont_touch : string; - -- attribute dont_touch of r : signal is "TRUE"; + -- attribute dont_touch : string; + -- attribute dont_touch of r : signal is "TRUE"; + -- attribute dont_touch of rxMaster : signal is "TRUE"; + -- attribute dont_touch of rxSlave : signal is "TRUE"; + -- attribute dont_touch of txMaster : signal is "TRUE"; + -- attribute dont_touch of txSlave : signal is "TRUE"; begin @@ -238,8 +242,8 @@ begin v.rxSlave.tReady := '1'; -- Check for SOF with no EOF if (ssiGetUserSof(DHCP_CONFIG_C, rxMaster) = '1') and (rxMaster.tLast = '0') then - -- Check for valid DHCP server OP/HTYPE/HLEN/HOPS - if rxMaster.tData(31 downto 0) = SERVER_HDR_C then + -- Check for valid DHCP server OP/HTYPE/HLEN (ignore HOPS field) + if rxMaster.tData(23 downto 0) = SERVER_HDR_C(23 downto 0) then -- Preset the counter v.cnt := 1; -- Next state @@ -274,6 +278,7 @@ begin -- OP/HTYPE/HLEN/HOPS when 0 => v.txMaster.tData(31 downto 0) := CLIENT_HDR_C; + v.txMaster.tKeep := x"000F"; ssiSetUserSof(DHCP_CONFIG_C, v.txMaster, '1'); -- XID when 1 => @@ -307,6 +312,7 @@ begin v.txMaster.tData(7 downto 0) := toSlv(53, 8); -- code = DHCP Message Type v.txMaster.tData(15 downto 8) := x"01"; -- len = 1 byte v.txMaster.tData(23 downto 16) := x"01"; -- DHCP Discover = 0x1 + v.txMaster.tData(31 downto 24) := x"FF"; -- Endmark v.txMaster.tLast := '1'; -- Start the communication timer v.commCnt := COMM_TIMEOUT_C; @@ -322,7 +328,7 @@ begin -- Requested IP address[15:0] when 61 => v.txMaster.tData(7 downto 0) := toSlv(50, 8); -- code = Requested IP address - v.txMaster.tData(15 downto 8) := x"04"; -- len = 4 byte + v.txMaster.tData(15 downto 8) := x"04"; -- len = 4 byte v.txMaster.tData(31 downto 16) := r.yiaddr(15 downto 0); -- YIADDR[15:0] -- Requested IP address[32:16] when 62 => @@ -330,18 +336,21 @@ begin -- Server Identifier[15:0] when 63 => v.txMaster.tData(7 downto 0) := toSlv(54, 8); -- code = Server Identifier - v.txMaster.tData(15 downto 8) := x"04"; -- len = 4 byte + v.txMaster.tData(15 downto 8) := x"04"; -- len = 4 byte v.txMaster.tData(31 downto 16) := r.siaddr(15 downto 0); -- SIADDR[15:0] -- Server Identifier[32:16] when 64 => v.txMaster.tData(15 downto 0) := r.siaddr(31 downto 16); -- SIADDR[31:16] - v.txMaster.tLast := '1'; + when 65 => + v.txMaster.tData(7 downto 0) := x"FF"; -- Endmark + v.txMaster.tKeep := x"0001"; + v.txMaster.tLast := '1'; -- Start the communication timer - v.commCnt := COMM_TIMEOUT_C; + v.commCnt := COMM_TIMEOUT_C; -- Reset the counter - v.cnt := 0; + v.cnt := 0; -- Next state - v.state := IDLE_S; + v.state := IDLE_S; when others => null; end case; @@ -446,7 +455,7 @@ begin v.decode := CODE_S; end if; -- Check the Code - if (r.opCode = 53) then -- Note: Assuming zero padding + if (r.opCode = 53) then -- Note: Assuming zero padding -- Check for DHCP Message Type if (r.len = 1) then @@ -524,9 +533,9 @@ begin end if; -- Next state v.state := IDLE_S; - ---------------------------------------------------------------------- + ---------------------------------------------------------------------- end case; - + -- Combinatorial outputs before the reset rxSlave <= v.rxSlave;