Dieses Repo implementiert eine Sammlung von Ethernet-bezogenen Komponenten in Bluespec SystemVerilog (BSV) für eine leistungsstarke Paketverarbeitung auf FPGA. Insbesondere stellt dieses Repo Module zum Generieren und Parsen von UDP/IP/Ethernet-Paketen bereit. Eine ARP-Verarbeitungseinheit mit nicht blockierendem Cache zum Speichern von Adressinformationen ist ebenfalls vorhanden, um die MAC-Adressauflösung automatisch durchzuführen. Neben dem Aufbau eines Standard-UDP/IP/Ethernet-Stacks bietet blue-ethernet auch Unterstützung für RoCE (RDMA over Converged Ethernet): 1) Integration der Generierung und Verifizierung von ICRC (Invariant Cyclic Redundancy) in die UDP/IP-Paketverarbeitung; 2) Bereitstellung von Modulen zur Handhabung von PFC (Priority Flow Control), um die verlustfreie Netzwerkübertragung zu realisieren. Und schließlich werden auch Schnittstellenkonvertierungsmodule für den Paketgenerator und Parser bereitgestellt, um mit dem Xilinx 100G Ethernet Subsystem (CMAC) zu interagieren.
Einige wichtige Verzeichnisse dieses Repos sind unten aufgeführt:
├── lib # external libraries/repos
│ ├── blue-crc # high-performance CRC hardware implementation
│ └── blue-wrapper # BSV wrappers for generating ready-to-use Verilog interface
├── scripts # scripts used to build project
├── src # design source files
│ └── includes # files containing some commonly-used BSV types and modules
├── syn # scripts for vivado synthesis and implementation
└── test # source files for verification
├── bluesim # testbenches based on bluesim
├── cocotb # python testbenches based on cocotb
└── vivado # co-simulation with cmac using vivado
Hier ist eine Liste einiger wichtiger Quelldateien:
./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
│ └── EthUtils.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
Dieser Abschnitt enthält detaillierte Beschreibungen einiger wichtiger in blue-ethernet implementierter Komponenten, einschließlich ihrer Funktionalität, Schnittstelle und Hardwarearchitektur.
Was Ethernet-bezogene Hardwarekomponenten bewirken, ist im Grunde eine Reihe von Stream-Manipulationen. Der Paketgenerator ist dafür verantwortlich, den Header-Stream in den Kopf des Nutzlast-Streams einzufügen, um einen vollständigen Paketstream zu generieren. Im Gegenteil, der Parser extrahiert den Header-Stream und den Payload-Stream aus dem Paketstream. Um die Prüfsumme für ein Paket hinzuzufügen, wird der Paketstrom an den CRC-Rechner übergeben und dann wird der ausgegebene CRC-Wert an das Ende des Paketstroms angehängt.
Die Hardware-Entität, die dem hier erwähnten Stream entspricht, ist eigentlich eine Gruppe von Datensignalen, die durch das Valid-Ready-Steuersignalpaar geschützt werden. Das gültige Signal zeigt an, dass die Quellkomponente Daten übertragen möchte. Und „ready“ zeigt an, dass die Senke bereit ist, Daten von der Quelle zu empfangen. Eine Übertragung zwischen Quelle und Senke erfolgt nur dann erfolgreich, wenn sowohl „Valid“ als auch „Ready“ hoch sind. Wenn die zu übertragende Datenmenge größer ist als die Größe einer Übertragung, müssen die Daten fragmentiert und in einer Reihe von Übertragungen übertragen werden.
Der schwierigste und fehleranfälligste Teil der Stream-Verarbeitung besteht darin, wie mit den gültigen Steuersignalen verschiedener Streams umgegangen wird. In BSV wird die Manipulation von Steuersignalen vom Compiler implementiert und ist auf der grammatikalischen Ebene unsichtbar, was Designern hilft, sich auf die Logik der Stream-Verarbeitung zu konzentrieren.
Datensignale, die zum Übertragen von Paketströmen zwischen verschiedenen Komponenten verwendet werden, sind in der DataStream- Struktur gekapselt, die ein 256-Bit-Datensignal, ein 32-Bit-Byte-Aktivierungssignal und zwei boolesche Signale umfasst, die angeben, ob diese Übertragung die letzte oder erste eines Paketstroms ist.
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 ) ;
module mkAppendDataStreamHead # (
IsSwapEndian swapDataStream ,
IsSwapEndian swapAppendData ,
FifoOut # ( DataStream ) dataStreamIn ,
FifoOut # ( dType ) appendDataIn
)( FifoOut # ( DataStream )) ;
module mkAppendDataStreamTail # (
IsSwapEndian swapDataStream ,
IsSwapEndian swapAppendData ,
FifoOut # ( DataStream ) dataStreamIn ,
FifoOut # ( dType ) appendDataIn ,
FifoOut # ( Bit # ( streamLenWidth )) streamLengthIn
)( FifoOut # ( DataStream )) ;
interface ExtractDataStream # ( type dType ) ;
interface FifoOut # ( dType ) extractDataOut ;
interface FifoOut # ( DataStream ) dataStreamOut ;
endinterface
module mkExtractDataStreamHead # (
FifoOut # ( DataStream ) dataStreamIn
)( ExtractDataStream # ( dType )) ;
Module im UdpIpLayer -Paket sind zum Generieren und Parsen von UDP/IP-Paketen implementiert.
Der Paketgenerator nimmt UdpIpMetaData auf, das UDP/IP-Header-Informationen und den Nutzdatenstrom enthält, und gibt den vollständigen UDP/IP-Paketstrom aus. Der Paketparser funktioniert umgekehrt, indem er UdpIpMetaData und den Nutzlaststrom aus dem UDP/IP-Paketstrom extrahiert.
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 ;
In der UdpIpMetaData -Struktur gekapselte Signale decken nicht alle im UDP/IP-Header definierten Felder ab. Einige Felder des Headers sind für ein bestimmtes Netzwerkgerät festgelegt, in der UdpConfig- Struktur gekapselt und müssen vor dem Senden oder Empfangen von Paketen konfiguriert werden. Und einige andere Felder sind konstant und in Hardwarekomponenten fest codiert.
typedef struct {
EthMacAddr macAddr ; # Source MAC address
IpAddr ipAddr ; # Source IP address
IpNetMask netMask ; # IP netmask
IpGateWay gateWay ; # IP gateway
} UdpConfig ;
module mkUdpIpStream # (
UdpConfig udpConfig ,
FifoOut # ( DataStream ) dataStreamIn ,
FifoOut # ( UdpIpMetaData ) udpIpMetaDataIn ,
function UdpIpHeader genHeader ( UdpIpMetaData meta , UdpConfig udpConfig , IpID ipId )
)( FifoOut # ( DataStream )) ;
interface UdpIpMetaDataAndDataStream ;
interface FifoOut # ( UdpIpMetaData ) udpIpMetaDataOut ;
interface FifoOut # ( DataStream ) dataStreamOut ;
endinterface
module mkUdpIpMetaDataAndDataStream # (
UdpConfig udpConfig ,
FifoOut # ( DataStream ) udpIpStreamIn ,
function UdpIpMetaData extractMetaData ( UdpIpHeader hdr )
)( UdpIpMetaDataAndDataStream ) ;
Module im UdpIpLayerForRdma -Paket werden basierend auf UdpIpLayer mit Unterstützung für RoCE (RDMA over Converged Ethernet) implementiert. Die zur Unterstützung von RoCE hinzugefügte zusätzliche Funktionalität ist die Generierung und Überprüfung von ICRC (Invariante CRC), die für RoCE-Pakete erforderlich ist. Das Format des RoCE-Pakets ist wie folgt definiert:
Module im MacLayer -Paket sind zum Generieren und Parsen von Ethernet-Paketen implementiert. Der Generator fügt einen Ethernet-Header in den Kopf des UDP/IP-Paketstroms ein, um einen Ethernet-Paketstrom zu erzeugen. Der Parser extrahiert den Ethernet-Header und den UDP/IP-Paketstrom aus dem Ethernet-Paketstrom.
Die zum Generieren eines Ethernet-Pakets verwendeten Header-Informationen werden in der MacMetaData- Struktur definiert.
typedef struct {
EthMacAddr macAddr ; # Destination MAC address
EthType ethType ; # Type of Ethernet frame
} MacMetaData deriving ( Bits , Eq , FShow ) ;
Zu beachten ist, dass das im MacLayer verarbeitete Ethernet-Paket nur die Felder abdeckt, die im roten Rechteck in der folgenden Abbildung dargestellt sind. Andere Felder müssen von Xilinx CMAC IP verarbeitet werden.
module mkMacStream # (
FifoOut # ( DataStream ) udpIpStreamIn ,
FifoOut # ( MacMetaData ) macMetaDataIn ,
UdpConfig udpConfig
)( FifoOut # ( DataStream )) ;
interface MacMetaDataAndUdpIpStream ;
interface FifoOut # ( MacMetaData ) macMetaDataOut ;
interface FifoOut # ( DataStream ) udpIpStreamOut ;
endinterface
module mkMacMetaDataAndUdpIpStream # (
FifoOut # ( DataStream ) macStreamIn ,
UdpConfig udpConfig
)( MacMetaDataAndUdpIpStream ) ;
Das Address Resolution Protocol (ARP) wird zum Ermitteln der MAC-Adresse verwendet, die einer bestimmten IP-Adresse zugeordnet ist. In blue-ethernet ist das Modul mkArpProcessor für die ARP-Verarbeitung implementiert, das den ARP-Paketgenerator, den Parser und das mkArpCache- Modul zum Speichern von MAC-Adressen integriert.
Für den bei der ARP-Verarbeitung verwendeten Cache entspricht die 32-Bit-IP-Adresse der Cache-Adresse und die 48-Bit-MAC-Adresse den Cache-Daten. Die Standardanordnung des Speicherarrays für den ARP-Cache ist unten dargestellt. Dabei handelt es sich um eine satzassoziative 4-Wege-Struktur, jede Richtung enthält 64 Zeilen und jede Zeile enthält 1-Bit-Gültigkeit, 26-Bit-Tag und 48-Bit-Daten. Die Gesamtgröße dieser Standard-Array-Konfiguration beträgt etwa 1,2 KB. Es wird unterstützt, die Größe des Speicherarrays durch Festlegen der Anzahl der Zeilen und Wege zu ändern. Basierend auf diesem Speicherarray ist der Cache so konzipiert, dass er nicht blockiert, ausstehende Anforderungen (mehrere Anforderungen während des Flugs) unterstützt und einen Pseudo-LRU-Algorithmus zum Ersetzen der Cache-Zeile verwendet.
Die Schnittstellendefinition und das vereinfachte Strukturdiagramm des mkArpCache- Moduls sind unten dargestellt. Der ArpCache verfügt über zwei Unterschnittstellen: CacheServer verarbeitet Interaktionen mit Komponenten, die MAC-Adressauflösungsdienste anbieten; und arpClient verarbeitet die Interaktion mit mkArpProcessor, um eine ARP-Anfrage zu initiieren und die MAC-Adresse aus der ARP-Antwort abzurufen. Der grundlegende Arbeitsablauf des mkArpCache- Moduls ist wie folgt:
Wenn der Cache eine Leseanforderung erhält, durchsucht er zunächst das Speicherarray, um alle Tags und Daten abzurufen, die der angegebenen IP-Adresse entsprechen. Anschließend prüft es anhand der Tags, ob die von uns benötigten Daten im Cache gespeichert sind. Bei einem Cache-Treffer werden die abgerufenen Daten an hitBuf gesendet. Oder die IP-Adresse wird an arpReqBuf gesendet, um eine ARP-Anfrage zu initiieren. Und wenn die ARP-Antwort zurückkommt, werden die darin enthaltenen Daten und Adressinformationen sowohl in den CacheWrBuf als auch in den MissHitBuf geschrieben, um das Speicherarray zu aktualisieren und die Cache-Leseantwort zurückzugeben.
interface ArpCache ;
interface Server # ( CacheAddr , CacheData ) cacheServer ;
interface Client # ( CacheAddr , ArpResp ) arpClient ;
endinterface
Der schwierigste Teil der Cache-Implementierung besteht darin, die Funktion „Outstanding“ zu unterstützen, also die Unterstützung mehrerer Leseanforderungen während des Flugs. Das Problem, das durch den Status „Outstanding“ entsteht, besteht darin, dass die Antwortzeit für jede ARP-Anfrage im Flug unterschiedlich ist, was bedeutet, dass eine verspätete Anfrage möglicherweise zuerst ihre Antwort erhält. Daher ist ein Neuordnungsmechanismus erforderlich, um die Übereinstimmung zwischen der Anforderungsadresse und den Antwortdaten zu gewährleisten, wenn ein Cache-Fehler auftritt. Um eine Reaktion in der richtigen Reihenfolge zu realisieren, sind der Abschlusspuffer respCBuf und der inhaltsadressierbare Speicher missReqTab in den Datenfluss integriert. Der Abschlusspuffer funktioniert wie FIFO mit zusätzlicher Unterstützung für die Funktionalität der Reservierung. Vor dem eigentlichen Enqueue-Vorgang können wir zunächst einen Auftrag im Abschlusspuffer reservieren. Und der Vorgang zum Entfernen aus der Warteschlange folgt der reservierten Reihenfolge, unabhängig von der tatsächlichen Reihenfolge der Vorgänge zum Entfernen aus der Warteschlange. Für jede Leseanforderung wird in respCBuf eine Reihenfolge aus der Warteschlange umgekehrt, sobald sie empfangen wird. Und da die ARP-Anfrage die Bestellinformationen nicht übertragen kann, wird missReqTab zum Speichern dieser Informationen implementiert.
Das Modul kann sowohl als ARP-Client als auch als Server fungieren. Als Server muss der Prozessor eine ARP-Anfrage generieren, wenn die MAC-Adresse der Ziel-IP unbekannt ist, und dann auf die ARP-Antwort vom Zielgerät warten. Als Client empfängt der ARP-Prozessor ARP-Anfragen von anderen Geräten und sendet eine ARP-Antwort mit seiner eigenen MAC-Adresse zurück.
interface ArpProcessor ;
interface FifoOut # ( DataStream ) arpStreamOut ;
interface FifoOut # ( MacMetaData ) macMetaDataOut ;
interface Put # ( UdpConfig ) udpConfig ;
endinterface
module mkArpProcessor # (
FifoOut # ( DataStream ) arpStreamIn ,
FifoOut # ( UdpIpMetaData ) udpIpMetaDataIn
)( ArpProcessor ) ;
Module im UdpIpEthRx -Paket sind zum Empfangen und Parsen von UDP/IP/Ethernet-Paketen implementiert.
interface UdpIpEthRx ;
interface Put # ( UdpConfig ) udpConfig ;
interface Put # ( AxiStream512 ) axiStreamIn ;
interface FifoOut # ( MacMetaData ) macMetaDataOut ;
interface FifoOut # ( UdpIpMetaData ) udpIpMetaDataOut ;
interface FifoOut # ( DataStream ) dataStreamOut ;
endinterface
module mkGenericUdpIpEthRx # ( Bool isSupportRdma )( UdpIpEthRx )
Module im UdpIpEthTx -Paket sind für die Generierung und Übertragung von UDP/IP/Ethernet-Paketen implementiert.
interface UdpIpEthTx ;
interface Put # ( UdpConfig ) udpConfig ;
interface Put # ( UdpIpMetaData ) udpIpMetaDataIn ;
interface Put # ( MacMetaData ) macMetaDataIn ;
interface Put # ( DataStream ) dataStreamIn ;
interface AxiStream512FifoOut axiStreamOut ;
endinterface
module mkGenericUdpIpEthTx # ( Bool isSupportRdma )( UdpIpEthTx ) ;
Die im UdpIpArpEthRxTx -Paket bereitgestellten Module sind darauf ausgelegt, UDP/IP/Ethernet-Pakete zu empfangen und zu übertragen und gleichzeitig ARP-Anfragen und -Antworten zu verarbeiten.
Das Modul kann in zwei entgegengesetzte Stream-Pfade unterteilt werden, einschließlich Sendepfad und Empfangspfad:
Als Übertragungspfad werden dataStreamInTx mit Nutzlaststrom und udpIpMetaDataIn mit Header-Informationsstrom verwendet und axiStreamOutTx mit UDP/IP/Ethernet-Paketstrom generiert. Es ist nicht erforderlich, MacMetaData , das Ethernet-Header-Informationen enthält, als mkUdpIpEthTx -Modul bereitzustellen, da mkArpProcessor für die Verarbeitung der MAC-Adressauflösung und die Generierung von Ethernet-Header-Informationen verantwortlich ist.
Für den Empfangspfad funktioniert es umgekehrt, indem dataStreamOutRx mit dem Nutzlaststrom und udpIpMetaDataOutRx mit dem Header-Informationsstrom aus axiStreamInRx mit dem UDP/IP/Ethernet-Paketstrom extrahiert werden.
Der Ethernet-Paketgenerator und der Parser werden sowohl vom UDP/IP-Paket als auch vom ARP-Paket gemeinsam genutzt, sodass für die Stream-Arbitrierung und -Verteilung zusätzliche Mux und Demux im Sende- und Empfangspfad erforderlich sind. Der Modulparameter isSupportRdma gibt an, ob es die RoCE-Paketverarbeitung unterstützt oder nicht. Wenn die Unterstützung für RDMA deaktiviert ist, benötigen wir nur mkUdpIpStream und mkUdpIpMetaAndDataStream im Sende- bzw. Empfangspfad.
interface UdpIpArpEthRxTx ;
interface Put # ( UdpConfig ) udpConfig ;
// Tx
interface Put # ( UdpIpMetaData ) udpIpMetaDataInTx ;
interface Put # ( DataStream ) dataStreamInTx ;
interface AxiStream512FifoOut axiStreamOutTx ;
// Rx
interface Put # ( AxiStream512 ) axiStreamInRx ;
interface FifoOut # ( UdpIpMetaData ) udpIpMetaDataOutRx ;
interface FifoOut # ( DataStream ) dataStreamOutRx ;
endinterface
module mkGenericUdpIpArpEthRxTx # ( Bool isSupportRdma )( UdpIpArpEthRxTx ) ;
Das Modul umhüllt mkGenericUdpIpArpEthRxTx mithilfe der im Blue-Wrapper bereitgestellten Module, sodass eine gebrauchsfertige Verilog-Schnittstelle generiert wird.
Das Modul integriert sowohl das mkGenericUdpIpArpEthRxTx -Modul als auch das mkXilinxCmacTxWrapper -Modul. Es ist für die Interaktion mit Xilinx CMAC IP konzipiert, um UDP/IP/Ethernet-Pakete zu und von einem physischen Medium zu übertragen und zu empfangen.
Module im PriorityFlowControl- Paket sind implementiert, um einen Mechanismus zur Prioritätsflusskontrolle zu realisieren, um eine verlustfreie Netzwerkübertragung sicherzustellen.
interface PriorityFlowControlTx ;
interface Get # ( UdpIpMetaData ) udpIpMetaDataOut ;
interface Get # ( DataStream ) dataStreamOut ;
endinterface
module mkPriorityFlowControlTx # (
FifoOut # ( FlowControlReqVec ) flowControlReqVecIn ,
Vector # ( VIRTUAL_CHANNEL_NUM , DataStreamFifoOut ) dataStreamInVec ,
Vector # ( VIRTUAL_CHANNEL_NUM , UdpIpMetaDataFifoOut ) udpIpMetaDataInVec
)( PriorityFlowControlTx ) ;
interface PriorityFlowControlRx # (
numeric type bufPacketNum ,
numeric type maxPacketFrameNum ,
numeric type pfcThreshold
) ;
interface FifoOut # ( FlowControlReqVec ) flowControlReqVecOut ;
interface Vector # ( VIRTUAL_CHANNEL_NUM , Get # ( DataStream )) dataStreamOutVec ;
interface Vector # ( VIRTUAL_CHANNEL_NUM , Get # ( UdpIpMetaData )) udpIpMetaDataOutVec ;
endinterface
module mkPriorityFlowControlRx # (
DataStreamFifoOut dataStreamIn ,
UdpIpMetaDataFifoOut udpIpMetaDataIn
)( PriorityFlowControlRx # ( bufPacketNum , maxPacketFrameNum , pfcThreshold )) ;
mkGenericPfcUdpIpArpEthRxTx integriert mkPriorityFlowControlRx/Tx und mkGenericUdpIpArpEthRxTx, um die Funktionalität zum Generieren und Parsen von UDP/IP/Ethernet-Paketen bereitzustellen und gleichzeitig die Prioritätsflusskontrolle zu unterstützen. Für die Paketübertragung werden acht Kanäle mit Nutzdatenstrom und UDP/IP-Header-Informationen benötigt und ein UDP/IP/Ethernet-Paketstrom ausgegeben. Für den Paketempfang nimmt es einen UDP/IP/Ethernet-Paketstrom auf und leitet den extrahierten UDP/IP-Header und Nutzdatenstrom an einen von acht Ausgangskanälen weiter.
mkPfcUdpIpArpEthCmacRxTx integriert sowohl das mkGenericPfcUdpIpArpEthRxTx -Modul als auch das mkXilinxCmacTxWrapper -Modul. Es ist für die Interaktion mit Xilinx CMAC IP konzipiert, um UDP/IP/Ethernet-Pakete zu und von einem physischen Medium zu übertragen und zu empfangen.
Die Synthese und Implementierung des Hauptmoduls mkGenericUdpIpArpEthRxTx erfolgt auf Basis des Xilinx xcvu9p -Geräts unter Verwendung von Vivado. Und die Ergebnisse zeigen, dass die Schaltung die Arbeitsfrequenz von 500 MHz erreichen und einen Spitzendurchsatz von 128 Gbit/s liefern kann. Die Nutzung der Hardwareressourcen wird wie folgt aufgeführt:
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 |
+-------------------+------+-------+------------+-----------+-------+
In diesem Abschnitt wird erläutert, wie Sie mit diesem Projekt beginnen. Bevor Sie weitere Schritte ausführen, müssen Sie zunächst die Entwicklungsumgebung mithilfe des Skripts setup.sh einrichten. Hier ist eine Liste der Abhängigkeiten:
Klonen Sie dieses Repo nach dem Einrichten der Umgebung in ein bestimmtes Verzeichnis. Hier bezeichnen wir dieses Verzeichnis als BLUE_ETH:
git clone --recursive https://github.com/wengwz/blue-ethernet.git $( BLUE_ETH )
In blue-ethernet stehen drei verschiedene Stufen von Testbenches zur Verfügung:
# Specify TARGET to the name of target component
cd $( BLUE_ETH ) /test/bluesim
make TARGET=ArpCache
# 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
# 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
Skripte zur Ausführung der Synthese und Implementierung von Designs werden im Verzeichnis $(BLUE_ETH)/syn bereitgestellt.
# 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
# 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
bsc -p +: $( BLUE_ETH ) /src: $( BLUE_ETH ) /src/includes ...
Die Implementierung von blue-ethernet beinhaltet die Nutzung folgender externer Bibliotheken: