Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/surf_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ jobs:
- name: Parallel Regression Tests
run: |
make MODULES=$PWD import
python -m pytest --cov -v -n auto --dist=worksteal tests/axi tests/base tests/dsp tests/protocols
python -m pytest --cov -v -n auto --dist=worksteal tests/axi tests/base tests/dsp tests/protocols tests/ethernet/RoCEv2

- name: Code Coverage
run: |
Expand Down
2 changes: 1 addition & 1 deletion ethernet/RoCEv2/blue-rdma/mkAxisTransportLayer.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Generated by Bluespec Compiler, version 2023.01 (build 52adafa5)
//
// On Mon Apr 13 13:07:51 CEST 2026
// On Thu Jun 18 07:38:53 PDT 2026
//
// Method conflict info:
// Method: rawWorkReqIn_validData
Expand Down
11,527 changes: 8,030 additions & 3,497 deletions ethernet/RoCEv2/blue-rdma/mkQP.v

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethernet/RoCEv2/blue-rdma/mkTransportLayer.v
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Generated by Bluespec Compiler, version 2023.01 (build 52adafa5)
//
// On Mon Apr 13 13:07:37 CEST 2026
// On Thu Jun 18 07:38:46 PDT 2026
//
// Method conflict info:
// Method: workReqInput_put
Expand Down
901 changes: 901 additions & 0 deletions ethernet/RoCEv2/rtl/RoCEv2AxiStreamRdma.vhd

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ethernet/RoCEv2/rtl/RoCEv2Engine.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ begin
-- Transport-core reset = hard 'rst' OR the configurator-generated softRst
-- (active high). The softRst clears stale QP/PSN state on a software
-- reconnect without disturbing the rest of the engine or the RUDP/UDP link.
roceRstN <= not (rst or s_softRst) when (RST_POLARITY_G = '1')
else (rst and not s_softRst);
roceRstN <= not (rst or s_softRst) when (RST_POLARITY_G = '1') else
(rst and not s_softRst);
cnp_received <= s_cnp_received;

----------------------------------------------------------------------------
Expand Down
16 changes: 16 additions & 0 deletions ethernet/RoCEv2/rtl/RoceConfigurator.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,22 @@ begin
end if;
v.softRst := ite(v.softRstCnt /= 0, '1', '0');

-- Keep the metadata FSM in lockstep with the transport core across a
-- soft-reset. softRst (0xF50) resets the core but NOT this configurator
-- (the one-shot above must survive its own pulse). If the pulse lands
-- while an exchange is in flight, the core never answers the pre-reset
-- request and this FSM would stall forever in GET_RESPONSE_S, ignoring
-- the next SendMetaData -- RecvMetaData never returns to 1, wedging the
-- reconnect until an FPGA reload. Abort any in-flight exchange and hold
-- IDLE_S for the pulse so the configurator comes out of soft-reset clean
-- and resynced. The one-shot state (softRstReq/softRstCnt/softRst) is
-- intentionally left untouched.
if (v.softRst = '1') then
v.state := IDLE_S;
v.txMaster.tValid := '0';
v.metaDataIsReady := '0';
end if;

-- Outputs
axilWriteSlave <= r.axilWriteSlave;
axilReadSlave <= r.axilReadSlave;
Expand Down
250 changes: 250 additions & 0 deletions ethernet/RoCEv2/wrappers/RoCEv2AxiStreamRdmaWrapper.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
-------------------------------------------------------------------------------
-- Company : SLAC National Accelerator Laboratory
-------------------------------------------------------------------------------
-- Description: Cocotb-facing wrapper for RoCEv2AxiStreamRdma.
--
-- Flattens the VHDL record ports (AXI-Stream, RoCEv2 workReq/dmaReadReq/
-- dmaReadResp/workComp, AXI-Lite) into plain std_logic/std_logic_vector ports
-- so a cocotb testbench can drive/observe every channel. The DUT is wired
-- single-clock (roceClk = sAxisClk = clk, GEN_SYNC_FIFO_G=true) at the default
-- 32-byte RoCEv2 stream width. The AXI-Lite shim mirrors RoceConfiguratorWrapper.
-------------------------------------------------------------------------------
-- 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;

library surf;
use surf.StdRtlPkg.all;
use surf.AxiStreamPkg.all;
use surf.AxiLitePkg.all;
use surf.RoCEv2Pkg.all;

entity RoCEv2AxiStreamRdmaWrapper is
generic (
TPD_G : time := 1 ns);
port (
clk : in sl;
rst : in sl;
-- Inbound payload stream (TB AxiStreamSource drives; 32-byte beats)
S_AXIS_TVALID : in sl;
S_AXIS_TDATA : in slv(255 downto 0);
S_AXIS_TKEEP : in slv(31 downto 0);
S_AXIS_TLAST : in sl;
S_AXIS_TREADY : out sl;
-- workReq (module -> engine); TB observes + drives ready
M_WORKREQ_VALID : out sl;
M_WORKREQ_READY : in sl;
M_WORKREQ_ID : out slv(63 downto 0);
M_WORKREQ_OPCODE : out slv(3 downto 0);
M_WORKREQ_FLAGS : out slv(4 downto 0);
M_WORKREQ_RADDR : out slv(63 downto 0);
M_WORKREQ_RKEY : out slv(31 downto 0);
M_WORKREQ_LEN : out slv(31 downto 0);
M_WORKREQ_SQPN : out slv(23 downto 0);
M_WORKREQ_IMMDT : out slv(32 downto 0);
-- dmaReadReq (engine -> module); TB drives valid+fields, observes ready
S_DMAREADREQ_VALID : in sl;
S_DMAREADREQ_READY : out sl;
S_DMAREADREQ_INITIATOR : in slv(3 downto 0);
S_DMAREADREQ_SQPN : in slv(23 downto 0);
S_DMAREADREQ_WRID : in slv(63 downto 0);
S_DMAREADREQ_STARTADDR : in slv(63 downto 0);
S_DMAREADREQ_LEN : in slv(12 downto 0);
S_DMAREADREQ_MRIDX : in sl;
-- dmaReadResp (module -> engine); TB observes valid+data, drives ready
M_DMAREADRESP_VALID : out sl;
M_DMAREADRESP_READY : in sl;
M_DMAREADRESP_DATASTREAM : out slv(289 downto 0);
M_DMAREADRESP_ISRESPERR : out sl;
M_DMAREADRESP_WRID : out slv(63 downto 0);
M_DMAREADRESP_SQPN : out slv(23 downto 0);
M_DMAREADRESP_INITIATOR : out slv(3 downto 0);
-- workComp (engine -> module); TB drives valid+status, observes ready
S_WORKCOMP_VALID : in sl;
S_WORKCOMP_READY : out sl;
S_WORKCOMP_STATUS : in slv(4 downto 0);
S_WORKCOMP_ID : in slv(63 downto 0);
-- AXI-Lite (cocotbext-axi AxiLiteMaster drives the AXI4-Lite bus)
S_AXIL_AWADDR : in slv(31 downto 0);
S_AXIL_AWPROT : in slv(2 downto 0);
S_AXIL_AWVALID : in sl;
S_AXIL_AWREADY : out sl;
S_AXIL_WDATA : in slv(31 downto 0);
S_AXIL_WSTRB : in slv(3 downto 0);
S_AXIL_WVALID : in sl;
S_AXIL_WREADY : out sl;
S_AXIL_BRESP : out slv(1 downto 0);
S_AXIL_BVALID : out sl;
S_AXIL_BREADY : in sl;
S_AXIL_ARADDR : in slv(31 downto 0);
S_AXIL_ARPROT : in slv(2 downto 0);
S_AXIL_ARVALID : in sl;
S_AXIL_ARREADY : out sl;
S_AXIL_RDATA : out slv(31 downto 0);
S_AXIL_RRESP : out slv(1 downto 0);
S_AXIL_RVALID : out sl;
S_AXIL_RREADY : in sl);
end entity RoCEv2AxiStreamRdmaWrapper;

architecture rtl of RoCEv2AxiStreamRdmaWrapper is

signal axilClk : sl;
signal axilRst : sl;
signal axilReadMaster : AxiLiteReadMasterType := AXI_LITE_READ_MASTER_INIT_C;
signal axilReadSlave : AxiLiteReadSlaveType := AXI_LITE_READ_SLAVE_INIT_C;
signal axilWriteMaster : AxiLiteWriteMasterType := AXI_LITE_WRITE_MASTER_INIT_C;
signal axilWriteSlave : AxiLiteWriteSlaveType := AXI_LITE_WRITE_SLAVE_INIT_C;

signal sAxisMaster : AxiStreamMasterType := AXI_STREAM_MASTER_INIT_C;
signal sAxisSlave : AxiStreamSlaveType := AXI_STREAM_SLAVE_INIT_C;
signal dmaReadReqMaster : RoceDmaReadReqMasterType := ROCE_DMA_READ_REQ_MASTER_INIT_C;
signal dmaReadReqSlave : RoceDmaReadReqSlaveType := ROCE_DMA_READ_REQ_SLAVE_INIT_C;
signal dmaReadRespMaster : RoceDmaReadRespMasterType := ROCE_DMA_READ_RESP_MASTER_INIT_C;
signal dmaReadRespSlave : RoceDmaReadRespSlaveType := ROCE_DMA_READ_RESP_SLAVE_INIT_C;
signal workReqMaster : RoceWorkReqMasterType := ROCE_WORK_REQ_MASTER_INIT_C;
signal workReqSlave : RoceWorkReqSlaveType := ROCE_WORK_REQ_SLAVE_INIT_C;
signal workCompMaster : RoceWorkCompMasterType := ROCE_WORK_COMP_MASTER_INIT_C;
signal workCompSlave : RoceWorkCompSlaveType := ROCE_WORK_COMP_SLAVE_INIT_C;

begin

----------------------------------------------------------------------------
-- AXI-Lite shim (flat AXI4-Lite <-> AxiLite record)
----------------------------------------------------------------------------
U_ShimLayer : entity surf.SlaveAxiLiteIpIntegrator
generic map (
EN_ERROR_RESP => true,
FREQ_HZ => 156250000,
ADDR_WIDTH => 32)
port map (
S_AXI_ACLK => clk,
S_AXI_ARESETN => not rst,
S_AXI_AWADDR => S_AXIL_AWADDR,
S_AXI_AWPROT => S_AXIL_AWPROT,
S_AXI_AWVALID => S_AXIL_AWVALID,
S_AXI_AWREADY => S_AXIL_AWREADY,
S_AXI_WDATA => S_AXIL_WDATA,
S_AXI_WSTRB => S_AXIL_WSTRB,
S_AXI_WVALID => S_AXIL_WVALID,
S_AXI_WREADY => S_AXIL_WREADY,
S_AXI_BRESP => S_AXIL_BRESP,
S_AXI_BVALID => S_AXIL_BVALID,
S_AXI_BREADY => S_AXIL_BREADY,
S_AXI_ARADDR => S_AXIL_ARADDR,
S_AXI_ARPROT => S_AXIL_ARPROT,
S_AXI_ARVALID => S_AXIL_ARVALID,
S_AXI_ARREADY => S_AXIL_ARREADY,
S_AXI_RDATA => S_AXIL_RDATA,
S_AXI_RRESP => S_AXIL_RRESP,
S_AXI_RVALID => S_AXIL_RVALID,
S_AXI_RREADY => S_AXIL_RREADY,
axilClk => axilClk,
axilRst => axilRst,
axilReadMaster => axilReadMaster,
axilReadSlave => axilReadSlave,
axilWriteMaster => axilWriteMaster,
axilWriteSlave => axilWriteSlave);

----------------------------------------------------------------------------
-- Record <-> flat packing
----------------------------------------------------------------------------
-- Slave payload stream (TB drives)
sAxisComb : process (S_AXIS_TVALID, S_AXIS_TDATA, S_AXIS_TKEEP, S_AXIS_TLAST) is
variable v : AxiStreamMasterType;
begin
v := AXI_STREAM_MASTER_INIT_C;
v.tValid := S_AXIS_TVALID;
v.tData(255 downto 0) := S_AXIS_TDATA;
v.tKeep(31 downto 0) := S_AXIS_TKEEP;
v.tLast := S_AXIS_TLAST;
sAxisMaster <= v;
end process sAxisComb;
S_AXIS_TREADY <= sAxisSlave.tReady;

-- workReq (module -> engine)
M_WORKREQ_VALID <= workReqMaster.valid;
M_WORKREQ_ID <= workReqMaster.id;
M_WORKREQ_OPCODE <= workReqMaster.opCode;
M_WORKREQ_FLAGS <= workReqMaster.flags;
M_WORKREQ_RADDR <= workReqMaster.rAddr;
M_WORKREQ_RKEY <= workReqMaster.rKey;
M_WORKREQ_LEN <= workReqMaster.len;
M_WORKREQ_SQPN <= workReqMaster.sQpn;
M_WORKREQ_IMMDT <= workReqMaster.immDt;
workReqSlave.ready <= M_WORKREQ_READY;

-- dmaReadReq (engine -> module; TB drives)
dmaReadReqComb : process (S_DMAREADREQ_VALID, S_DMAREADREQ_INITIATOR, S_DMAREADREQ_SQPN,
S_DMAREADREQ_WRID, S_DMAREADREQ_STARTADDR, S_DMAREADREQ_LEN,
S_DMAREADREQ_MRIDX) is
variable v : RoceDmaReadReqMasterType;
begin
v := ROCE_DMA_READ_REQ_MASTER_INIT_C;
v.valid := S_DMAREADREQ_VALID;
v.initiator := S_DMAREADREQ_INITIATOR;
v.sQpn := S_DMAREADREQ_SQPN;
v.wrId := S_DMAREADREQ_WRID;
v.startAddr := S_DMAREADREQ_STARTADDR;
v.len := S_DMAREADREQ_LEN;
v.mrIdx := S_DMAREADREQ_MRIDX;
dmaReadReqMaster <= v;
end process dmaReadReqComb;
S_DMAREADREQ_READY <= dmaReadReqSlave.ready;

-- dmaReadResp (module -> engine)
M_DMAREADRESP_VALID <= dmaReadRespMaster.valid;
M_DMAREADRESP_DATASTREAM <= dmaReadRespMaster.dataStream;
M_DMAREADRESP_ISRESPERR <= dmaReadRespMaster.isRespErr;
M_DMAREADRESP_WRID <= dmaReadRespMaster.wrId;
M_DMAREADRESP_SQPN <= dmaReadRespMaster.sQpn;
M_DMAREADRESP_INITIATOR <= dmaReadRespMaster.initiator;
dmaReadRespSlave.ready <= M_DMAREADRESP_READY;

-- workComp (engine -> module; TB drives)
workCompComb : process (S_WORKCOMP_VALID, S_WORKCOMP_STATUS, S_WORKCOMP_ID) is
variable v : RoceWorkCompMasterType;
begin
v := ROCE_WORK_COMP_MASTER_INIT_C;
v.valid := S_WORKCOMP_VALID;
v.status := S_WORKCOMP_STATUS;
v.id := S_WORKCOMP_ID;
workCompMaster <= v;
end process workCompComb;
S_WORKCOMP_READY <= workCompSlave.ready;

----------------------------------------------------------------------------
-- DUT (single-clock: roceClk = sAxisClk = clk, GEN_SYNC_FIFO_G=true)
----------------------------------------------------------------------------
U_DUT : entity surf.RoCEv2AxiStreamRdma
generic map (
TPD_G => TPD_G,
GEN_SYNC_FIFO_G => true)
port map (
roceClk => clk,
roceRst => rst,
sAxisClk => clk,
sAxisRst => rst,
sAxisMaster => sAxisMaster,
sAxisSlave => sAxisSlave,
dmaReadReqMaster => dmaReadReqMaster,
dmaReadReqSlave => dmaReadReqSlave,
dmaReadRespMaster => dmaReadRespMaster,
dmaReadRespSlave => dmaReadRespSlave,
workReqMaster => workReqMaster,
workReqSlave => workReqSlave,
workCompMaster => workCompMaster,
workCompSlave => workCompSlave,
axilReadMaster => axilReadMaster,
axilReadSlave => axilReadSlave,
axilWriteMaster => axilWriteMaster,
axilWriteSlave => axilWriteSlave);

end architecture rtl;
Loading
Loading