01、簡介
blue-ethernet項目使用Bluespec SystemVerilog(BSV)硬件描述語言實現了一系列在FPGA上加速網絡數據包處理的硬件模塊。具體來說,其提供了用于生成和解析Ethernet/IP/UDP網絡報文的硬件模塊。此外,還提供了一個具有非阻塞高速緩存的APR報文處理單元,用于自動解析設備的物理MAC地址。
除了構建標準的UDP/IP/Ethernet協議棧,blue-ethernet還增加了對RoCE(RDMA over Converged Ethernet)協議的支持,具體包括:
1)在UDP/IP報文處理流程中集成 ICRC校驗碼的生成和驗證功能;
2)提供對Priority Flow Control(PFC)協議的支持,實現無損網絡傳輸。
最后,本項目還實現了與 Xilinx 100G以太網子系統(CMAC)進行交互的單元。
02、文件目錄概覽
本項目關鍵目錄的介紹如下:
├── lib # 外部庫
│ ├── blue-crc # 高性能CRC硬件實現
│ └── blue-wrapper # BSV接口封裝模塊
├── scripts # 腳本
├── src # 設計源文件
│ └── includes
├── syn # 綜合腳本
└── test # 測試源文件
├── bluesim # 基于bluesim的測試源文件
├── cocotb # 基于python的測試源文件
└── vivado # 和CMAC IP進行聯合仿真的測試文件
以下是部分源文件的介紹:
./src
├── ArpCache.bsv # Cache implementation storing MAC addresses got from ARP
├── ArpProcessor.bsv # processing unit handling ARP requests and responses
├── includes
│ ├── CompletionBuf.bsv
│ ├── ContentAddressMem.bsv
│ ├── EthernetTypes.bsv # numeric and struct types about protocol definition
│ ├── PortConversion.bsv # interface conversion modules used to generate ready-to-use Verilog
│ ├── Ports.bsv # numeric and struct types about in/output ports of modules
│ ├── RFile.bsv
│ ├── StreamHandler.bsv # modules implemented for manipulating data stream
│ └── Utils.bsv # utility functions and modules
├── MacLayer.bsv # generator and parser for Ethernet packet
├── PfcUdpIpArpEthRxTx.bsv # generator and parser for UDP/IP/Ethernet packet with PFC
├── PriorityFlowControl.bsv # modules handling PFC
├── UdpIpArpEthRxTx.bsv # generator and parser for UDP/IP/Ethernet packet
├── UdpIpEthRx.bsv # parser for UDP/IP/Ethernet packet
├── UdpIpEthTx.bsv # generator for UDP/IP/Ethernet packet
├── UdpIpLayer.bsv # parser and generator for UDP/IP packet
├── UdpIpLayerForRdma.bsv # parser and generator for UDP/IP packet with support for RoCE
└── XilinxCmacRxTxWrapper.bsv # bridge modules between parser/generator and Xilinx CMAC
03、組件
本節將詳細介紹blue-ethernet實現的一些重要組件,包括其功能、接口定義和硬件架構等內容。
數據流處理模塊
硬件網絡報文處理本質上是對數據流的各種操作。報文生成模塊實際上是將報頭數據流插入發送內容數據流的頭部,以生成完整的報文數據流。相反,解析模塊則是從報文數據流中提取出報頭數據流和發送信息數據流。為報文添加校驗和,則是先將報文數據流傳入CRC計算單元,然后將輸出的CRC校驗值附加到報文流的尾部。這里提到的數據流,其對應的硬件實體是由valid-ready握手信號控制的一組數據信號。在基于valid-ready握手的交互協議下,valid信號表示主端(Source)發起了數據傳輸請求,ready信號則表示從端(Sink)準備好接收來自主端的數據。只有當valid和ready同時為高電平時,即主從雙方同時準備好后,才成功完成一次傳輸。如果需要傳輸的數據量大于一次傳輸的容量,則需要對數據進行分段,并通過多次握手傳遞。在對數據流的處理中最棘手以及最容易出錯的部分是多個數據流交互時如何處理不同流的valid-ready控制信號。在BSV中,控制信號的處理由編譯器實現,在語法層面上是不可見的,這更有助于設計人員專注于不同數據流之間的交互邏輯,而不用處理底層復雜的控制信號。
blue-ethernet提供的用于數據流處理的模塊包括:
- DataStream結構體定義了blue-ethernet中基本的數據流格式,其包括256位數據信號、32位字節使能信號和兩個布爾信號isFirst和isLast,分別表示本次傳輸是否是數據包的最早/后一幀。
typedef 256 DATA_BUS_WIDTH;
typedef TDiv#(DATA_BUS_WIDTH, 8) DATA_BUS_BYTE_WIDTH;
typedef Bit#(DATA_BUS_WIDTH) Data;
typedef Bit#(DATA_BUS_BYTE_WIDTH) ByteEn;
typedef struct {
Data data;
ByteEn byteEn;
Bool isFirst;
Bool isLast;
} DataStream deriving(Bits, Bounded, Eq, FShow);
- mkAppendDataStreamHead模塊將appendDataIn數據流附加到dataStreamIn數據流的頭部。通過設置swapDataStream和swapAppendData參數,可以分別轉換這兩個數據流的字節序。該模塊可用于合并報頭流和發送數據流,生成完整的報文流。
module mkAppendDataStreamHead#(
IsSwapEndian swapDataStream,
IsSwapEndian swapAppendData,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(dType) appendDataIn
)(PipeOut#(DataStream));
- mkAppendDataStreamTail模塊將appendDataIn數據流附加到dataStreamIn數據流的尾部。在合并前,它還需要接收一個攜帶數據流長度的輸入信號streamLengthIn。
module mkAppendDataStreamTail#(
IsSwapEndian swapDataStream,
IsSwapEndian swapAppendData,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(dType) appendDataIn,
PipeOut#(Bit#(streamLenWidth)) streamLengthIn
)(PipeOut#(DataStream));
- mkExtractDataStreamHead模塊提取出數據流dataStreamIn的頭部并通過extractDataOut輸出,dataStreamOut接口輸出剩余部分的數據。
interface ExtractDataStream#(type dType);
interface PipeOut#(dType) extractDataOut;
interface PipeOut#(DataStream) dataStreamOut;
endinterface
module mkExtractDataStreamHead#(
PipeOut#(DataStream) dataStreamIn
)(ExtractDataStream#(dType));
- mkAxiStream512ToDataStream模塊將512位AXI-Stream總線接口轉換為blue-ethernet中定義的256位數據傳輸格式DataStream。
- mkDataStreamToAxiStream512模塊將256位DataStream數據轉換為512位AXI-Stream總線。
UdpIpLayer
UdpIpLayer包中的定義的模塊用于生成和解析基于UDP/IP協議的報文:
- UdpIpMetaData結構體封裝了每次生成UDP和IP報文時需要動態更新的信息,具體包括:
typedef struct {
UdpLength dataLen; # The Length of payload data
IpAddr ipAddr; # Desitnation IP address
IpDscp ipDscp; # DSCP field used for PFC
IpEcn ipEcn; # ECN field
UdpPort dstPort; # Destination port number
UdpPort srcPort; # Source port number
} UdpIpMetaData;
- UdpConfig結構體封裝了UDP/IP報文的某些字段,包括源MAC/IP地址、子網掩碼和網關,這些字段在一段時間內都是固定的,通過一次統一的配置即可,而不需要每次生成報文時都動態地更新。
typedef struct {
EthMacAddr macAddr; # Source MAC address
IpAddr ipAddr; # Source IP address
IpNetMask netMask; # IP netmask
IpGateWay gateWay; # IP gateway
} UdpConfig;
- mkUdpIpStream模塊負責生成完整的UDP/IP報文流。實例化該模塊時需要指定一個報頭生成函數genHeader,該函數的輸入包括UdpIpMetaData和UdpConfig結構體以及IpID字段,輸出完整的UDP/IP報頭。在模塊開始工作前,需要先通過udpConfig接口配置源MAC/IP地址等靜態信息。每次生成報文的詳細流程如下: 1)從udpIpMetaDataIn接口獲得報頭信息并通過genHeader函數生成完整的報頭數據流;2)計算IP報頭的校驗和并更新到報頭流中;3) 將報頭流插入到發送信息數據流dataStreamIn的頭部后輸出完整報文流。
module mkUdpIpStream#(
UdpConfig udpConfig,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(UdpIpMetaData) udpIpMetaDataIn,
function UdpIpHeader genHeader(UdpIpMetaData meta, UdpConfig udpConfig, IpID ipId)
)(PipeOut#(DataStream));
- mkUdpIpMetaDataAndDataStream模塊負責解析UDP/IP報文流。該模塊的具體工作流程為:1)從報文流udpIpStreamIn中提取出報頭流和信息數據流;2) 檢查報頭的地址信息以及IP校驗和是否匹配; 3)若校驗出錯,丟棄提取出的報頭和信息流;4)若校驗通過, 則由dataStreamOut輸出信息數據流,并根據extractMetaData函數從報頭結構體中提取出相關報頭信息后通過udpIpMetaDataOut接口輸出。在模塊開始工作前,同樣需要先通過udpConfig接口配置源MAC/IP地址等靜態信息。
interface UdpIpMetaDataAndDataStream;
interface PipeOut#(UdpIpMetaData) udpIpMetaDataOut;
interface PipeOut#(DataStream) dataStreamOut;
endinterface
module mkUdpIpMetaDataAndDataStream#(
UdpConfig udpConfig,
PipeOut#(DataStream) udpIpStreamIn,
function UdpIpMetaData extractMetaData(UdpIpHeader hdr)
)(UdpIpMetaDataAndDataStream);
UdpIpLayerForRdma
UdpIpLayerForRdma包在UdpIpLayer的基礎上提供了對RoCE(RDMA over Converged Ethernet)協議的支持。為支持RoCE協議,需要在報文生成和解析模塊中分別添加生成和檢查RoCE數據包ICRC校驗和的功能。RoCE數據包的格式定義如下,和標準的UDP/IP協議相比,RoCE協議需要額外計算整個IP報文的CRC校驗和并附加到尾部。
功能模塊詳解:
- mkUdpIpStreamForRdma模塊提供與mkUdpIpStream相同的接口和功能。主要區別在于,它在輸出報文流的尾部附加了額外的ICRC校驗和,以生成符合RoCE協議的UDP/IP報文。為實現這一功能,該模塊在mkUdpIpStream的基礎上又集成了另外三個組件:(1) mkUdpIpStreamForICrcGen生成用于計算ICRC的報文流;(2) mkCrcStream模塊由blue-crc提供,用于計算CRC校驗和;(3) mkAppendDataStreamTail將CRC校驗和附加到原UDP/IP報文流的尾部;
- mkUdpIpMetaDataAndDataStreamForRdma模塊在mkUdpIpMetaDataAndDataStream的基礎上提供了校驗RoCE協議定義的ICRC的功能。為實現這一附加功能,輸入報文流需要經過mkUdpIpStreamForICrcChk模塊生成用于ICRC計算的報文流,然后傳遞到mkCrcStream模塊進行ICRC校驗和的計算。如果驗證失敗,mkUdpIpMetaDataAndDataStream模塊提取出的信息流和報頭流將被丟棄。如果驗證通過,提取出的信息流還需要通過mkRemoveICrcFromDataStream模塊,移除尾部附加的ICRC后輸出。
MacLayer
MacLayer中提供的模塊用于生成和解析鏈路層的Ethernet報文: 生成以太網數據包需要的報頭信息被定義在MacMetaData結構體中,包括目標物理地址macAddr和報文類型ethType:
typedef struct {
EthMacAddr macAddr; # Destination MAC address
EthType ethType; # Type of Ethernet frame
} MacMetaData deriving(Bits, Eq, FShow);
需要注意的是,在目前的實現中,MacLayer處理的Ethernet報文只包括下圖中紅色矩形框內的字段。其他字段由Xilinx提供的CMAC模塊處理。
- mkMacStream模塊負責生成Ethernet報文流。其基于以太網報頭信息macMetaDataIn生成Ethernet報頭數據流(包括MAC destination/source和EtherType字段),然后將報頭流插入UDP/IP報文流的頭部生成完整的Ethernet報文流。在生成報文前,需要通過udpConfig配置源MAC地址等信息。
module mkMacStream#(
PipeOut#(DataStream) udpIpStreamIn,
PipeOut#(MacMetaData) macMetaDataIn,
UdpConfig udpConfig
)(PipeOut#(DataStream));
- mkMacMetaDataAndUdpIpStream模塊從Ethernet報文流macStreamIn中提取出報頭流和UDP/IP報文流,進行地址匹配的檢查后,從報頭流中提取出MacMetaData結構體并從macMetaDataOut接口輸出,而UDP/IP報文流從udpIpStreamOut接口輸出。
interface MacMetaDataAndUdpIpStream;
interface PipeOut#(MacMetaData) macMetaDataOut;
interface PipeOut#(DataStream) udpIpStreamOut;
endinterface
module mkMacMetaDataAndUdpIpStream#(
PipeOut#(DataStream) macStreamIn,
UdpConfig udpConfig
)(MacMetaDataAndUdpIpStream);
ARP Processor
地址解析協議(ARP)用于解析給定IP地址對應的MAC物理地址。在blue-ethernet中,mkArpProcessor模塊負責ARP協議的處理,其集成了ARP報文生成器、解析器以及緩存MAC地址信息的mkArpCache等模塊。
mkArpCache
mkArpCache模塊用于緩存解析得到的MAC物理地址。在ARP的應用場景下,緩存地址為32-bit的IP地址,緩存數據為48-bit的MAC物理地址。mkArpCache存儲陣列的組織形式為4路組相聯,每路包含64行,每行包括1-bit有效位、26-bit標記位以及48-bit數據。在該默認配置下存儲容量的總大小約為1.2KB,同時設計也支持改變行數和路數進一步提升緩存空間。在此內存陣列的基礎上,緩存還支持outstanding模式以及偽LRU(Least Frequently Used)行替換算法。
mkArpCache模塊的接口定義和結構圖如下所示。ArpCache可以分成兩個子接口:cacheServer接口與Ethernet報文生成模塊進行交互,接收并響應其發起的MAC地址檢索請求;arpClient接口與ARP報文生成和解析模塊交互,處理緩存未命中的情況。mkArpCache模塊的工作流程如下:
當收到Ethernet報文生成模塊檢索MAC地址的請求后,首先根據給定IP地址搜索緩存陣列,檢查所需的MAC地址是否已經存儲在緩存陣列中。如果緩存命中,則將獲取的MAC地址發送到hitBuf。若未命中,則將IP地址發送到arpReqBuf以向外發起ARP請求。當ARP響應返回時,將解析得到的MAC地址同時寫入cacheWrBuf和missHitBuf,更新緩存陣列內的數據,同時響應Ethernet報文生成器檢索MAC地址的請求。
interface ArpCache;
interface Server#(CacheAddr, CacheData) cacheServer;
interface Client#(CacheAddr, ArpResp) arpClient;
endinterface
mkArpProcessor
mkArpProcessor集成了MAC地址信息緩存單元mkArpCache以及對ARP報文的解析和生成模塊。在處理ARP請求和響應時,mkArpProcessor既可作為請求端,在Cache Miss時發出ARP請求報文并接收從目標設備返回的ARP響應報文。同時也可作為被請求端,接收其他設備發出的ARP請求報文并將自己的MAC地址信息通過ARP響應返回給請求端。
interface ArpProcessor;
interface PipeOut#(DataStream) arpStreamOut;
interface PipeOut#(MacMetaData) macMetaDataOut;
interface Put#(UdpConfig) udpConfig;
endinterface
module mkArpProcessor#(
PipeOut#(DataStream) arpStreamIn,
PipeOut#(UdpIpMetaData) udpIpMetaDataIn
)(ArpProcessor);
UdpIpEthRx
UdpIpEthRx包提供的模塊用于接收并解析UDP/IP/Ethernet報文流:
- mkGenericUdpIpEthRx模塊從UDP/IP/Ethernet報文數據流axiStreamIn中提取出Ethernet報頭信息流macMetaDataOut、UDP/IP報頭數據流udpIpMetaDataOut和有效信息數據流dataStreamOut。在開始接收并解析報文前,需要先通過udpConfig接口配置源IP/MAC地址等信息。模塊參數isSupportRdma指定是否提供對RoCE協議的支持。下圖展示了該模塊在開啟對RoCE協議的支持后對應的電路結構。如果禁用對RoCE協議的支持,整個 mkUdpIpMetaDataAndDataStreamForRdma模塊將由mkUdpIpMetaDataAndDataStream所替代。
interface UdpIpEthRx;
interface Put#(UdpConfig) udpConfig;
interface Put#(AxiStream512) axiStreamIn;
interface PipeOut#(MacMetaData) macMetaDataOut;
interface PipeOut#(UdpIpMetaData) udpIpMetaDataOut;
interface PipeOut#(DataStream) dataStreamOut;
endinterface
module mkGenericUdpIpEthRx#(Bool isSupportRdma)(UdpIpEthRx)
- mkGenericRawUdpIpEthRx模塊使用blue-wrapper中提供的組件對mkGenericUdpIpEthRx進行封裝,目的是為了在生成的Verilog代碼里提供直接可用的接口。
UdpIpEthTx
UdpIpEthTx包提供的模塊用于生成并輸出UDP/IP/Ethernet報文流。
- mkGenericUdpIpEthTx模塊接收Ethernet報頭信息數據流macMetaDataOut、UDP/IP報頭信息數據流udpIpMetaDataOut,以及發送信息數據流dataStreamOut,生成完整的UDP/IP/Ethernet報文流并通過 axiStreamOut接口輸出。模塊的配置參數isSupportRdma指定在報文處理過程中是否支持RoCE協議。下圖展示了啟用對RoCE協議的支持后模塊的整體結構:
interface UdpIpEthTx;
interface Put#(UdpConfig) udpConfig;
interface Put#(UdpIpMetaData) udpIpMetaDataIn;
interface Put#(MacMetaData) macMetaDataIn;
interface Put#(DataStream) dataStreamIn;
interface AxiStream512PipeOut axiStreamOut;
endinterface
module mkGenericUdpIpEthTx#(Bool isSupportRdma)(UdpIpEthTx);
- mkGenericRawUdpIpEthTx基于blue-wrapper倉庫提供的組件對mkGenericUdpIpEthTx模塊進行封裝,以在生成的Verilog代碼中提供直接可用的接口。
UdpIpArpEthRxTx
UdpIpArpEthRxTx包中的模塊集成了生成和解析UDP/IP/Ethernet報文,以及處理ARP請求和響應等功能,提供對UDP/IP/Ethernet協議棧完整的支持:
- mkGenericUdpIpArpEthRxTx模塊可劃分為兩個方向相反的數據流通路,分別是發送通路和接收通路。對于發送通路,其接收發送信息數據流dataStreamInTx和UDP/IP報頭流udpIpMetaDataIn,生成并輸出UDP/IP/Ethernet報文流axiStreamOutTx。對于接收通路,其工作方式正好相反,從UDP/IP/Ethernet報文流axiStreamInRx中提取出發送信息數據流dataStreamOutRx和UDP/IP報頭流udpIpMetaDataOutRx。模塊配置參數isSupportRdma指定該模塊是否支持RoCE協議。下圖展示了啟用對RoCE協議的支持后硬件電路的整體結構。
interface UdpIpArpEthRxTx;
interface Put#(UdpConfig) udpConfig;
// Tx
interface Put#(UdpIpMetaData) udpIpMetaDataInTx;
interface Put#(DataStream) dataStreamInTx;
interface AxiStream512PipeOut axiStreamOutTx;
// Rx
interface Put#(AxiStream512) axiStreamInRx;
interface PipeOut#(UdpIpMetaData) udpIpMetaDataOutRx;
interface PipeOut#(DataStream) dataStreamOutRx;
endinterface
module mkGenericUdpIpArpEthRxTx#(Bool isSupportRdma)(UdpIpArpEthRxTx);
- mkGenericRawUdpIpArpEthRxTx模塊使用 blue-wrapper中提供的組件對mkGenericUdpIpArpEthRxTx進行封裝,從而生成方便對接的Verilog接口。
PriorityFlowControl
PriorityFlowControl包中的模塊用于實現PFC協議,以確保無損網絡數據傳輸。
- mkPriorityFlowControlTx負責報文發送端的PFC控制,其接收八路發送數據流dataStreamInVec和八路報頭信息流udpIpMetaDataInVec,對這兩組八路數據流進行仲裁后分別通過udpIpMetaDataOut和dataStreamOut接口輸出仲裁結果。仲裁采用Round Robin策略,給予八個通道相同的優先級。同時,該模塊還負責根據PFC報文中提供的流控信息flowControlReqVecIn,暫停或恢復每個通道的數據發送。
interface PriorityFlowControlTx;
interface Get#(UdpIpMetaData) udpIpMetaDataOut;
interface Get#(DataStream) dataStreamOut;
endinterface
module mkPriorityFlowControlTx#(
PipeOut#(FlowControlReqVec) flowControlReqVecIn,
Vector#(VIRTUAL_CHANNEL_NUM, DataStreamPipeOut) dataStreamInVec,
Vector#(VIRTUAL_CHANNEL_NUM, UdpIpMetaDataPipeOut) udpIpMetaDataInVec
)(PriorityFlowControlTx);
- mkPriorityFlowControlRx負責報文接收端的PFC控制。其接收報頭信息流udpIpMetaDataIn和發送信息數據流 dataStreamIn,然后根據報頭信息中包含的通道索引值分別路由至udpIpMetaDataOutVec和dataStreamOutVec中的某個輸出通道。此外,該模塊需要監控每個通道的中間緩沖區中存儲的報文數量。當某個通道緩沖區內的報文數量達到閾值pfcThreshold時,就會發送PFC報文至發送端以暫停該通道的報文傳輸。
interface PriorityFlowControlRx#(
numeric type bufPacketNum,
numeric type maxPacketFrameNum,
numeric type pfcThreshold
);
interface PipeOut#(FlowControlReqVec) flowControlReqVecOut;
interface Vector#(VIRTUAL_CHANNEL_NUM, Get#(DataStream)) dataStreamOutVec;
interface Vector#(VIRTUAL_CHANNEL_NUM, Get#(UdpIpMetaData)) udpIpMetaDataOutVec;
endinterface
module mkPriorityFlowControlRx#(
DataStreamPipeOut dataStreamIn,
UdpIpMetaDataPipeOut udpIpMetaDataIn
)(PriorityFlowControlRx#(bufPacketNum, maxPacketFrameNum, pfcThreshold));
04、性能和面積
基于Xilinx xcvu9p FPGA,使用Vivado對blue-ethernet中的主要模塊mkGenericUdpIpArpEthRxTx進行綜合和實現。結果表明,電路的工作頻率可達 500MHz,峰值吞吐量為 128Gbps。硬件資源使用情況如下:
CLB Logic
+----------------------------+-------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+----------------------------+-------+-------+------------+-----------+-------+
| CLB LUTs | 63886 | 0 | 0 | 1182240 | 5.40 |
| LUT as Logic | 41242 | 0 | 0 | 1182240 | 3.49 |
| LUT as Memory | 22644 | 0 | 0 | 591840 | 3.83 |
| LUT as Distributed RAM | 22644 | 0 | | | |
| LUT as Shift Register | 0 | 0 | | | |
| CLB Registers | 44099 | 0 | 0 | 2364480 | 1.87 |
| Register as Flip Flop | 44099 | 0 | 0 | 2364480 | 1.87 |
| Register as Latch | 0 | 0 | 0 | 2364480 | 0.00 |
| CARRY8 | 73 | 0 | 0 | 147780 | 0.05 |
| F7 Muxes | 194 | 0 | 0 | 591120 | 0.03 |
| F8 Muxes | 28 | 0 | 0 | 295560 | < 0.01 |
| F9 Muxes | 0 | 0 | 0 | 147780 | 0.00 |
+----------------------------+-------+-------+------------+-----------+-------+
BLOCKRAM
+-------------------+------+-------+------------+-----------+-------+
| Site Type | Used | Fixed | Prohibited | Available | Util% |
+-------------------+------+-------+------------+-----------+-------+
| Block RAM Tile | 4.5 | 0 | 0 | 2160 | 0.21 |
| RAMB36/FIFO* | 4 | 0 | 0 | 2160 | 0.19 |
| RAMB36E2 only | 4 | | | | |
| RAMB18 | 1 | 0 | 0 | 4320 | 0.02 |
| RAMB18E2 only | 1 | | | | |
| URAM | 0 | 0 | 0 | 960 | 0.00 |
+-------------------+------+-------+------------+-----------+-------+
05、入門教程
本節將介紹如何開始使用此項目。在進行其他步驟前,首先需要參照根目錄下的setup.sh腳本配置開發環境。以下列出了開發環境依賴的軟件包:
- Bluespec 編譯器
- Docker
- Vivado
- Python 軟件包:cocotb、cocotb-test、netifaces、scapy、cocotbext-axi
- 硬件模擬器:iverilog/verilator 環境配置好后,將blue-ethernet倉庫克隆到某一目錄。這里我們將該目錄統一稱為BLUE_ETH:
git clone --recursive https://github.com/wengwz/blue-ethernet.git $(BLUE_ETH)
仿真測試
blue-ethernet提供了三種不同級別的測試平臺:
- 子模塊級:該級別測試平臺代碼位于$(BLUE_ETH)/test/bluesim,主要提供了一些重要子模塊的功能驗證,如ArpCache、CompletionBuf 和 AppendDataStreamTail。要運行仿真,可參考以下命令:
# Specify TARGET to the name of target component
cd $(BLUE_ETH)/test/bluesim
make TARGET=ArpCache
- 系統級:該級別測試平臺的代碼位于$BLUE_ETH/test/cocotb,基于Cocotb使用Python實現。模塊UdpIpEthRx和UdpIpEthTx的功能驗證使用scapy構建參考模型。模塊UdpIpArpEthRxTx在docker構建的虛擬網絡上進行測試。
# Run tests of UdpIpEthRx/Tx
# Enable/Disable support for RDMA by setting SUPPORT_RDAM to True/False
cd $(BLUE_ETH)/test/cocotb
make cocotb TARGET=UdpIpEthTx SUPPORT_RDMA=TRUE
# Run simulation on virtual network
# Change NET_IFC in run_docker_net_test.sh to the name of your network card
cd $(BLUE_ETH)/test/cocotb
docker build -f ./build_docker/Dockerfile -t ethernet-test ./build_docker
./run_docker_net_test.sh
- 與CMAC進行聯合仿真:在Vivado中與CMAC IP聯合仿真的腳本位于目錄$(BLUE_ETH)/test/vivado。
# Available TARGET includes UdpIpArpEthCmacRxTx/PfcUdpIpArpEthCmacRxTx
# Enable/Disable support for RDMA by setting SUPPORT_RDAM to True/False
cd $(BLUE_ETH)/test/vivado
make sim TARGET=UdpIpArpEthCmacRxTx SUPPORT_RDMA=False
綜合與物理實現在Vivado下運行綜合和物理實現的腳本位于目錄$(BLUE_ETH)/syn。
# TARGET specifies the top module to be synthsized or implemented
# SUPPORT_RDMA specifies whether modules supports RoCE packet processing
# ONLYSYNTH decides whether or not run implemetation after synthesis
cd $(BLUE_ETH)/syn
make vivado TARGET=UdpIpArpEthRxTx SUPPORT_RDMA=False ONLYSYNTH=0
使用方法
- Verilog用戶:本倉庫提供的BSV設計可生成Verilog代碼并集成到其他項目中。本倉庫已經基于blue-wrapper提供的組件對mkRawUdpIpArpEthRxTx、mkRawUdpIpEthRx/Tx等模塊進行封裝,以在生成的Verilog中提供方便的接口。對于其他模塊,您也可以根據需要對它們進行封裝。若要生成 Verilog 代碼,可參考以下命令,生成的代碼位于目錄$(BLUE_ETH)/test/cocotb/verilog中。
# TARGET specifies the name of top module to be generated
# Specify SUPPORT_RDMA if needed
cd $(BLUE_ETH)/test/cocotb
make verilog TARGET=UdpIpEthTx SUPPORT_RDMA=TRUE
- BSV用戶:對于使用BSV的設計人員來說,可以更加方便地將blue-ethernet倉庫中提供的模塊集成到自己的項目中。只需在代碼中導入使用到的包,并在編譯選項中添加本倉庫源文件夾的路徑即可:
bsc -p +:$(BLUE_ETH)/src:$(BLUE_ETH)/src/includes ...
-
FPGA設計
+關注
關注
9文章
428瀏覽量
26561 -
以太網
+關注
關注
40文章
5452瀏覽量
172189 -
UDP協議
+關注
關注
0文章
69瀏覽量
12719 -
CRC校驗
+關注
關注
0文章
84瀏覽量
15244 -
生成器
+關注
關注
7文章
317瀏覽量
21062
發布評論請先 登錄
相關推薦
評論