01、簡(jiǎn)介
blue-ethernet項(xiàng)目使用Bluespec SystemVerilog(BSV)硬件描述語言實(shí)現(xiàn)了一系列在FPGA上加速網(wǎng)絡(luò)數(shù)據(jù)包處理的硬件模塊。具體來說,其提供了用于生成和解析Ethernet/IP/UDP網(wǎng)絡(luò)報(bào)文的硬件模塊。此外,還提供了一個(gè)具有非阻塞高速緩存的APR報(bào)文處理單元,用于自動(dòng)解析設(shè)備的物理MAC地址。
除了構(gòu)建標(biāo)準(zhǔn)的UDP/IP/Ethernet協(xié)議棧,blue-ethernet還增加了對(duì)RoCE(RDMA over Converged Ethernet)協(xié)議的支持,具體包括:
1)在UDP/IP報(bào)文處理流程中集成 ICRC校驗(yàn)碼的生成和驗(yàn)證功能;
2)提供對(duì)Priority Flow Control(PFC)協(xié)議的支持,實(shí)現(xiàn)無損網(wǎng)絡(luò)傳輸。
最后,本項(xiàng)目還實(shí)現(xiàn)了與 Xilinx 100G以太網(wǎng)子系統(tǒng)(CMAC)進(jìn)行交互的單元。
02、文件目錄概覽
本項(xiàng)目關(guān)鍵目錄的介紹如下:
├── lib # 外部庫
│ ├── blue-crc # 高性能CRC硬件實(shí)現(xiàn)
│ └── blue-wrapper # BSV接口封裝模塊
├── scripts # 腳本
├── src # 設(shè)計(jì)源文件
│ └── includes
├── syn # 綜合腳本
└── test # 測(cè)試源文件
├── bluesim # 基于bluesim的測(cè)試源文件
├── cocotb # 基于python的測(cè)試源文件
└── vivado # 和CMAC IP進(jìn)行聯(lián)合仿真的測(cè)試文件
以下是部分源文件的介紹:
./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、組件
本節(jié)將詳細(xì)介紹blue-ethernet實(shí)現(xiàn)的一些重要組件,包括其功能、接口定義和硬件架構(gòu)等內(nèi)容。
數(shù)據(jù)流處理模塊
硬件網(wǎng)絡(luò)報(bào)文處理本質(zhì)上是對(duì)數(shù)據(jù)流的各種操作。報(bào)文生成模塊實(shí)際上是將報(bào)頭數(shù)據(jù)流插入發(fā)送內(nèi)容數(shù)據(jù)流的頭部,以生成完整的報(bào)文數(shù)據(jù)流。相反,解析模塊則是從報(bào)文數(shù)據(jù)流中提取出報(bào)頭數(shù)據(jù)流和發(fā)送信息數(shù)據(jù)流。為報(bào)文添加校驗(yàn)和,則是先將報(bào)文數(shù)據(jù)流傳入CRC計(jì)算單元,然后將輸出的CRC校驗(yàn)值附加到報(bào)文流的尾部。這里提到的數(shù)據(jù)流,其對(duì)應(yīng)的硬件實(shí)體是由valid-ready握手信號(hào)控制的一組數(shù)據(jù)信號(hào)。在基于valid-ready握手的交互協(xié)議下,valid信號(hào)表示主端(Source)發(fā)起了數(shù)據(jù)傳輸請(qǐng)求,ready信號(hào)則表示從端(Sink)準(zhǔn)備好接收來自主端的數(shù)據(jù)。只有當(dāng)valid和ready同時(shí)為高電平時(shí),即主從雙方同時(shí)準(zhǔn)備好后,才成功完成一次傳輸。如果需要傳輸?shù)臄?shù)據(jù)量大于一次傳輸?shù)娜萘?,則需要對(duì)數(shù)據(jù)進(jìn)行分段,并通過多次握手傳遞。在對(duì)數(shù)據(jù)流的處理中最棘手以及最容易出錯(cuò)的部分是多個(gè)數(shù)據(jù)流交互時(shí)如何處理不同流的valid-ready控制信號(hào)。在BSV中,控制信號(hào)的處理由編譯器實(shí)現(xiàn),在語法層面上是不可見的,這更有助于設(shè)計(jì)人員專注于不同數(shù)據(jù)流之間的交互邏輯,而不用處理底層復(fù)雜的控制信號(hào)。
blue-ethernet提供的用于數(shù)據(jù)流處理的模塊包括:
- DataStream結(jié)構(gòu)體定義了blue-ethernet中基本的數(shù)據(jù)流格式,其包括256位數(shù)據(jù)信號(hào)、32位字節(jié)使能信號(hào)和兩個(gè)布爾信號(hào)isFirst和isLast,分別表示本次傳輸是否是數(shù)據(jù)包的最早/后一幀。
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數(shù)據(jù)流附加到dataStreamIn數(shù)據(jù)流的頭部。通過設(shè)置swapDataStream和swapAppendData參數(shù),可以分別轉(zhuǎn)換這兩個(gè)數(shù)據(jù)流的字節(jié)序。該模塊可用于合并報(bào)頭流和發(fā)送數(shù)據(jù)流,生成完整的報(bào)文流。
module mkAppendDataStreamHead#(
IsSwapEndian swapDataStream,
IsSwapEndian swapAppendData,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(dType) appendDataIn
)(PipeOut#(DataStream));
- mkAppendDataStreamTail模塊將appendDataIn數(shù)據(jù)流附加到dataStreamIn數(shù)據(jù)流的尾部。在合并前,它還需要接收一個(gè)攜帶數(shù)據(jù)流長度的輸入信號(hào)streamLengthIn。
module mkAppendDataStreamTail#(
IsSwapEndian swapDataStream,
IsSwapEndian swapAppendData,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(dType) appendDataIn,
PipeOut#(Bit#(streamLenWidth)) streamLengthIn
)(PipeOut#(DataStream));
- mkExtractDataStreamHead模塊提取出數(shù)據(jù)流dataStreamIn的頭部并通過extractDataOut輸出,dataStreamOut接口輸出剩余部分的數(shù)據(jù)。
interface ExtractDataStream#(type dType);
interface PipeOut#(dType) extractDataOut;
interface PipeOut#(DataStream) dataStreamOut;
endinterface
module mkExtractDataStreamHead#(
PipeOut#(DataStream) dataStreamIn
)(ExtractDataStream#(dType));
- mkAxiStream512ToDataStream模塊將512位AXI-Stream總線接口轉(zhuǎn)換為blue-ethernet中定義的256位數(shù)據(jù)傳輸格式DataStream。
- mkDataStreamToAxiStream512模塊將256位DataStream數(shù)據(jù)轉(zhuǎn)換為512位AXI-Stream總線。
UdpIpLayer
UdpIpLayer包中的定義的模塊用于生成和解析基于UDP/IP協(xié)議的報(bào)文:
- UdpIpMetaData結(jié)構(gòu)體封裝了每次生成UDP和IP報(bào)文時(shí)需要?jiǎng)討B(tài)更新的信息,具體包括:
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結(jié)構(gòu)體封裝了UDP/IP報(bào)文的某些字段,包括源MAC/IP地址、子網(wǎng)掩碼和網(wǎng)關(guān),這些字段在一段時(shí)間內(nèi)都是固定的,通過一次統(tǒng)一的配置即可,而不需要每次生成報(bào)文時(shí)都動(dòng)態(tài)地更新。
typedef struct {
EthMacAddr macAddr; # Source MAC address
IpAddr ipAddr; # Source IP address
IpNetMask netMask; # IP netmask
IpGateWay gateWay; # IP gateway
} UdpConfig;
- mkUdpIpStream模塊負(fù)責(zé)生成完整的UDP/IP報(bào)文流。實(shí)例化該模塊時(shí)需要指定一個(gè)報(bào)頭生成函數(shù)genHeader,該函數(shù)的輸入包括UdpIpMetaData和UdpConfig結(jié)構(gòu)體以及IpID字段,輸出完整的UDP/IP報(bào)頭。在模塊開始工作前,需要先通過udpConfig接口配置源MAC/IP地址等靜態(tài)信息。每次生成報(bào)文的詳細(xì)流程如下: 1)從udpIpMetaDataIn接口獲得報(bào)頭信息并通過genHeader函數(shù)生成完整的報(bào)頭數(shù)據(jù)流;2)計(jì)算IP報(bào)頭的校驗(yàn)和并更新到報(bào)頭流中;3) 將報(bào)頭流插入到發(fā)送信息數(shù)據(jù)流dataStreamIn的頭部后輸出完整報(bào)文流。
module mkUdpIpStream#(
UdpConfig udpConfig,
PipeOut#(DataStream) dataStreamIn,
PipeOut#(UdpIpMetaData) udpIpMetaDataIn,
function UdpIpHeader genHeader(UdpIpMetaData meta, UdpConfig udpConfig, IpID ipId)
)(PipeOut#(DataStream));
- mkUdpIpMetaDataAndDataStream模塊負(fù)責(zé)解析UDP/IP報(bào)文流。該模塊的具體工作流程為:1)從報(bào)文流udpIpStreamIn中提取出報(bào)頭流和信息數(shù)據(jù)流;2) 檢查報(bào)頭的地址信息以及IP校驗(yàn)和是否匹配; 3)若校驗(yàn)出錯(cuò),丟棄提取出的報(bào)頭和信息流;4)若校驗(yàn)通過, 則由dataStreamOut輸出信息數(shù)據(jù)流,并根據(jù)extractMetaData函數(shù)從報(bào)頭結(jié)構(gòu)體中提取出相關(guān)報(bào)頭信息后通過udpIpMetaDataOut接口輸出。在模塊開始工作前,同樣需要先通過udpConfig接口配置源MAC/IP地址等靜態(tài)信息。
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的基礎(chǔ)上提供了對(duì)RoCE(RDMA over Converged Ethernet)協(xié)議的支持。為支持RoCE協(xié)議,需要在報(bào)文生成和解析模塊中分別添加生成和檢查RoCE數(shù)據(jù)包ICRC校驗(yàn)和的功能。RoCE數(shù)據(jù)包的格式定義如下,和標(biāo)準(zhǔn)的UDP/IP協(xié)議相比,RoCE協(xié)議需要額外計(jì)算整個(gè)IP報(bào)文的CRC校驗(yàn)和并附加到尾部。
功能模塊詳解:
- mkUdpIpStreamForRdma模塊提供與mkUdpIpStream相同的接口和功能。主要區(qū)別在于,它在輸出報(bào)文流的尾部附加了額外的ICRC校驗(yàn)和,以生成符合RoCE協(xié)議的UDP/IP報(bào)文。為實(shí)現(xiàn)這一功能,該模塊在mkUdpIpStream的基礎(chǔ)上又集成了另外三個(gè)組件:(1) mkUdpIpStreamForICrcGen生成用于計(jì)算ICRC的報(bào)文流;(2) mkCrcStream模塊由blue-crc提供,用于計(jì)算CRC校驗(yàn)和;(3) mkAppendDataStreamTail將CRC校驗(yàn)和附加到原UDP/IP報(bào)文流的尾部;
- mkUdpIpMetaDataAndDataStreamForRdma模塊在mkUdpIpMetaDataAndDataStream的基礎(chǔ)上提供了校驗(yàn)RoCE協(xié)議定義的ICRC的功能。為實(shí)現(xiàn)這一附加功能,輸入報(bào)文流需要經(jīng)過mkUdpIpStreamForICrcChk模塊生成用于ICRC計(jì)算的報(bào)文流,然后傳遞到mkCrcStream模塊進(jìn)行ICRC校驗(yàn)和的計(jì)算。如果驗(yàn)證失敗,mkUdpIpMetaDataAndDataStream模塊提取出的信息流和報(bào)頭流將被丟棄。如果驗(yàn)證通過,提取出的信息流還需要通過mkRemoveICrcFromDataStream模塊,移除尾部附加的ICRC后輸出。
MacLayer
MacLayer中提供的模塊用于生成和解析鏈路層的Ethernet報(bào)文: 生成以太網(wǎng)數(shù)據(jù)包需要的報(bào)頭信息被定義在MacMetaData結(jié)構(gòu)體中,包括目標(biāo)物理地址macAddr和報(bào)文類型ethType:
typedef struct {
EthMacAddr macAddr; # Destination MAC address
EthType ethType; # Type of Ethernet frame
} MacMetaData deriving(Bits, Eq, FShow);
需要注意的是,在目前的實(shí)現(xiàn)中,MacLayer處理的Ethernet報(bào)文只包括下圖中紅色矩形框內(nèi)的字段。其他字段由Xilinx提供的CMAC模塊處理。
- mkMacStream模塊負(fù)責(zé)生成Ethernet報(bào)文流。其基于以太網(wǎng)報(bào)頭信息macMetaDataIn生成Ethernet報(bào)頭數(shù)據(jù)流(包括MAC destination/source和EtherType字段),然后將報(bào)頭流插入U(xiǎn)DP/IP報(bào)文流的頭部生成完整的Ethernet報(bào)文流。在生成報(bào)文前,需要通過udpConfig配置源MAC地址等信息。
module mkMacStream#(
PipeOut#(DataStream) udpIpStreamIn,
PipeOut#(MacMetaData) macMetaDataIn,
UdpConfig udpConfig
)(PipeOut#(DataStream));
- mkMacMetaDataAndUdpIpStream模塊從Ethernet報(bào)文流macStreamIn中提取出報(bào)頭流和UDP/IP報(bào)文流,進(jìn)行地址匹配的檢查后,從報(bào)頭流中提取出MacMetaData結(jié)構(gòu)體并從macMetaDataOut接口輸出,而UDP/IP報(bào)文流從udpIpStreamOut接口輸出。
interface MacMetaDataAndUdpIpStream;
interface PipeOut#(MacMetaData) macMetaDataOut;
interface PipeOut#(DataStream) udpIpStreamOut;
endinterface
module mkMacMetaDataAndUdpIpStream#(
PipeOut#(DataStream) macStreamIn,
UdpConfig udpConfig
)(MacMetaDataAndUdpIpStream);
ARP Processor
地址解析協(xié)議(ARP)用于解析給定IP地址對(duì)應(yīng)的MAC物理地址。在blue-ethernet中,mkArpProcessor模塊負(fù)責(zé)ARP協(xié)議的處理,其集成了ARP報(bào)文生成器、解析器以及緩存MAC地址信息的mkArpCache等模塊。
mkArpCache
mkArpCache模塊用于緩存解析得到的MAC物理地址。在ARP的應(yīng)用場(chǎng)景下,緩存地址為32-bit的IP地址,緩存數(shù)據(jù)為48-bit的MAC物理地址。mkArpCache存儲(chǔ)陣列的組織形式為4路組相聯(lián),每路包含64行,每行包括1-bit有效位、26-bit標(biāo)記位以及48-bit數(shù)據(jù)。在該默認(rèn)配置下存儲(chǔ)容量的總大小約為1.2KB,同時(shí)設(shè)計(jì)也支持改變行數(shù)和路數(shù)進(jìn)一步提升緩存空間。在此內(nèi)存陣列的基礎(chǔ)上,緩存還支持outstanding模式以及偽LRU(Least Frequently Used)行替換算法。
mkArpCache模塊的接口定義和結(jié)構(gòu)圖如下所示。ArpCache可以分成兩個(gè)子接口:cacheServer接口與Ethernet報(bào)文生成模塊進(jìn)行交互,接收并響應(yīng)其發(fā)起的MAC地址檢索請(qǐng)求;arpClient接口與ARP報(bào)文生成和解析模塊交互,處理緩存未命中的情況。mkArpCache模塊的工作流程如下:
當(dāng)收到Ethernet報(bào)文生成模塊檢索MAC地址的請(qǐng)求后,首先根據(jù)給定IP地址搜索緩存陣列,檢查所需的MAC地址是否已經(jīng)存儲(chǔ)在緩存陣列中。如果緩存命中,則將獲取的MAC地址發(fā)送到hitBuf。若未命中,則將IP地址發(fā)送到arpReqBuf以向外發(fā)起ARP請(qǐng)求。當(dāng)ARP響應(yīng)返回時(shí),將解析得到的MAC地址同時(shí)寫入cacheWrBuf和missHitBuf,更新緩存陣列內(nèi)的數(shù)據(jù),同時(shí)響應(yīng)Ethernet報(bào)文生成器檢索MAC地址的請(qǐng)求。
interface ArpCache;
interface Server#(CacheAddr, CacheData) cacheServer;
interface Client#(CacheAddr, ArpResp) arpClient;
endinterface
mkArpProcessor
mkArpProcessor集成了MAC地址信息緩存單元mkArpCache以及對(duì)ARP報(bào)文的解析和生成模塊。在處理ARP請(qǐng)求和響應(yīng)時(shí),mkArpProcessor既可作為請(qǐng)求端,在Cache Miss時(shí)發(fā)出ARP請(qǐng)求報(bào)文并接收從目標(biāo)設(shè)備返回的ARP響應(yīng)報(bào)文。同時(shí)也可作為被請(qǐng)求端,接收其他設(shè)備發(fā)出的ARP請(qǐng)求報(bào)文并將自己的MAC地址信息通過ARP響應(yīng)返回給請(qǐng)求端。
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報(bào)文流:
- mkGenericUdpIpEthRx模塊從UDP/IP/Ethernet報(bào)文數(shù)據(jù)流axiStreamIn中提取出Ethernet報(bào)頭信息流macMetaDataOut、UDP/IP報(bào)頭數(shù)據(jù)流udpIpMetaDataOut和有效信息數(shù)據(jù)流dataStreamOut。在開始接收并解析報(bào)文前,需要先通過udpConfig接口配置源IP/MAC地址等信息。模塊參數(shù)isSupportRdma指定是否提供對(duì)RoCE協(xié)議的支持。下圖展示了該模塊在開啟對(duì)RoCE協(xié)議的支持后對(duì)應(yīng)的電路結(jié)構(gòu)。如果禁用對(duì)RoCE協(xié)議的支持,整個(gè) 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中提供的組件對(duì)mkGenericUdpIpEthRx進(jìn)行封裝,目的是為了在生成的Verilog代碼里提供直接可用的接口。
UdpIpEthTx
UdpIpEthTx包提供的模塊用于生成并輸出UDP/IP/Ethernet報(bào)文流。
- mkGenericUdpIpEthTx模塊接收Ethernet報(bào)頭信息數(shù)據(jù)流macMetaDataOut、UDP/IP報(bào)頭信息數(shù)據(jù)流udpIpMetaDataOut,以及發(fā)送信息數(shù)據(jù)流dataStreamOut,生成完整的UDP/IP/Ethernet報(bào)文流并通過 axiStreamOut接口輸出。模塊的配置參數(shù)isSupportRdma指定在報(bào)文處理過程中是否支持RoCE協(xié)議。下圖展示了啟用對(duì)RoCE協(xié)議的支持后模塊的整體結(jié)構(gòu):
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倉庫提供的組件對(duì)mkGenericUdpIpEthTx模塊進(jìn)行封裝,以在生成的Verilog代碼中提供直接可用的接口。
UdpIpArpEthRxTx
UdpIpArpEthRxTx包中的模塊集成了生成和解析UDP/IP/Ethernet報(bào)文,以及處理ARP請(qǐng)求和響應(yīng)等功能,提供對(duì)UDP/IP/Ethernet協(xié)議棧完整的支持:
- mkGenericUdpIpArpEthRxTx模塊可劃分為兩個(gè)方向相反的數(shù)據(jù)流通路,分別是發(fā)送通路和接收通路。對(duì)于發(fā)送通路,其接收發(fā)送信息數(shù)據(jù)流dataStreamInTx和UDP/IP報(bào)頭流udpIpMetaDataIn,生成并輸出UDP/IP/Ethernet報(bào)文流axiStreamOutTx。對(duì)于接收通路,其工作方式正好相反,從UDP/IP/Ethernet報(bào)文流axiStreamInRx中提取出發(fā)送信息數(shù)據(jù)流dataStreamOutRx和UDP/IP報(bào)頭流udpIpMetaDataOutRx。模塊配置參數(shù)isSupportRdma指定該模塊是否支持RoCE協(xié)議。下圖展示了啟用對(duì)RoCE協(xié)議的支持后硬件電路的整體結(jié)構(gòu)。
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中提供的組件對(duì)mkGenericUdpIpArpEthRxTx進(jìn)行封裝,從而生成方便對(duì)接的Verilog接口。
PriorityFlowControl
PriorityFlowControl包中的模塊用于實(shí)現(xiàn)PFC協(xié)議,以確保無損網(wǎng)絡(luò)數(shù)據(jù)傳輸。
- mkPriorityFlowControlTx負(fù)責(zé)報(bào)文發(fā)送端的PFC控制,其接收八路發(fā)送數(shù)據(jù)流dataStreamInVec和八路報(bào)頭信息流udpIpMetaDataInVec,對(duì)這兩組八路數(shù)據(jù)流進(jìn)行仲裁后分別通過udpIpMetaDataOut和dataStreamOut接口輸出仲裁結(jié)果。仲裁采用Round Robin策略,給予八個(gè)通道相同的優(yōu)先級(jí)。同時(shí),該模塊還負(fù)責(zé)根據(jù)PFC報(bào)文中提供的流控信息flowControlReqVecIn,暫?;蚧謴?fù)每個(gè)通道的數(shù)據(jù)發(fā)送。
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負(fù)責(zé)報(bào)文接收端的PFC控制。其接收?qǐng)?bào)頭信息流udpIpMetaDataIn和發(fā)送信息數(shù)據(jù)流 dataStreamIn,然后根據(jù)報(bào)頭信息中包含的通道索引值分別路由至udpIpMetaDataOutVec和dataStreamOutVec中的某個(gè)輸出通道。此外,該模塊需要監(jiān)控每個(gè)通道的中間緩沖區(qū)中存儲(chǔ)的報(bào)文數(shù)量。當(dāng)某個(gè)通道緩沖區(qū)內(nèi)的報(bào)文數(shù)量達(dá)到閾值pfcThreshold時(shí),就會(huì)發(fā)送PFC報(bào)文至發(fā)送端以暫停該通道的報(bào)文傳輸。
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對(duì)blue-ethernet中的主要模塊mkGenericUdpIpArpEthRxTx進(jìn)行綜合和實(shí)現(xiàn)。結(jié)果表明,電路的工作頻率可達(dá) 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、入門教程
本節(jié)將介紹如何開始使用此項(xiàng)目。在進(jìn)行其他步驟前,首先需要參照根目錄下的setup.sh腳本配置開發(fā)環(huán)境。以下列出了開發(fā)環(huán)境依賴的軟件包:
- Bluespec 編譯器
- Docker
- Vivado
- Python 軟件包:cocotb、cocotb-test、netifaces、scapy、cocotbext-axi
- 硬件模擬器:iverilog/verilator 環(huán)境配置好后,將blue-ethernet倉庫克隆到某一目錄。這里我們將該目錄統(tǒng)一稱為BLUE_ETH:
git clone --recursive https://github.com/wengwz/blue-ethernet.git $(BLUE_ETH)
仿真測(cè)試
blue-ethernet提供了三種不同級(jí)別的測(cè)試平臺(tái):
- 子模塊級(jí):該級(jí)別測(cè)試平臺(tái)代碼位于$(BLUE_ETH)/test/bluesim,主要提供了一些重要子模塊的功能驗(yàn)證,如ArpCache、CompletionBuf 和 AppendDataStreamTail。要運(yùn)行仿真,可參考以下命令:
# Specify TARGET to the name of target component
cd $(BLUE_ETH)/test/bluesim
make TARGET=ArpCache
- 系統(tǒng)級(jí):該級(jí)別測(cè)試平臺(tái)的代碼位于$BLUE_ETH/test/cocotb,基于Cocotb使用Python實(shí)現(xiàn)。模塊UdpIpEthRx和UdpIpEthTx的功能驗(yàn)證使用scapy構(gòu)建參考模型。模塊UdpIpArpEthRxTx在docker構(gòu)建的虛擬網(wǎng)絡(luò)上進(jìn)行測(cè)試。
# 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進(jìn)行聯(lián)合仿真:在Vivado中與CMAC IP聯(lián)合仿真的腳本位于目錄$(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
綜合與物理實(shí)現(xiàn)在Vivado下運(yùn)行綜合和物理實(shí)現(xiàn)的腳本位于目錄$(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設(shè)計(jì)可生成Verilog代碼并集成到其他項(xiàng)目中。本倉庫已經(jīng)基于blue-wrapper提供的組件對(duì)mkRawUdpIpArpEthRxTx、mkRawUdpIpEthRx/Tx等模塊進(jìn)行封裝,以在生成的Verilog中提供方便的接口。對(duì)于其他模塊,您也可以根據(jù)需要對(duì)它們進(jìn)行封裝。若要生成 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用戶:對(duì)于使用BSV的設(shè)計(jì)人員來說,可以更加方便地將blue-ethernet倉庫中提供的模塊集成到自己的項(xiàng)目中。只需在代碼中導(dǎo)入使用到的包,并在編譯選項(xiàng)中添加本倉庫源文件夾的路徑即可:
bsc -p +:$(BLUE_ETH)/src:$(BLUE_ETH)/src/includes ...
-
FPGA設(shè)計(jì)
+關(guān)注
關(guān)注
9文章
428瀏覽量
26532 -
以太網(wǎng)
+關(guān)注
關(guān)注
40文章
5427瀏覽量
171841 -
UDP協(xié)議
+關(guān)注
關(guān)注
0文章
69瀏覽量
12699 -
CRC校驗(yàn)
+關(guān)注
關(guān)注
0文章
84瀏覽量
15211 -
生成器
+關(guān)注
關(guān)注
7文章
316瀏覽量
21037
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論