芯片资讯
- 发布日期:2023-12-26 14:53 点击次数:148 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)进行交互的单元。
本项目关键目录的介绍如下:
├── 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 CMAC03、组件
本节将详细介绍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, 芯片交易网IC交易网 IpID ipId) )(PipeOut#(DataStream));mkUdpIpMetaDataAndDataStream模块负责解析UDP/IP报文流。该模块的具体工作流程为:1)从报文流udpIpStreamIn中提取出报头流和信息数据流;2) 检查报头的地址信息以及IP校验和是否匹配; 3)若校验出错, ATMEGA系列ATMEL芯片COM丢弃提取出的报头和信息流;4)若校验通过, CMOS图像传感器集成电路芯片 则由dataStreamOut输出信息数据流, 电子元器件PDF资料大全并根据extractMetaData函数从报头结构体中提取出相关报头信息后通过udpIpMetaDataOut接口输出。在模块开始工作前,EEPROM带电可擦可编程存储器芯片大全同样需要先通过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报文流的尾部;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模块处理。
module mkMacStream#( PipeOut#(DataStream) udpIpStreamIn, PipeOut#(MacMetaData) macMetaDataIn, UdpConfig udpConfig )(PipeOut#(DataStream));mkMacMetaDataAndUdpIpStream模块从Ethernet报文流macStreamIn中提取出报头流和UDP/IP报文流,进行地址匹配的检查后,CMOS图像传感器IC集成电路芯片从报头流中提取出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)
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);
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);
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);
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));
基于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 |05、入门教程
本节将介绍如何开始使用此项目。在进行其他步骤前,首先需要参照根目录下的setup.sh脚本配置开发环境。以下列出了开发环境依赖的软件包:
Bluespec 编译器DockerVivadoPython 软件包: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=TRUEBSV用户:对于使用BSV的设计人员来说,可以更加方便地将blue-ethernet仓库中提供的模块集成到自己的项目中。只需在代码中导入使用到的包,并在编译选项中添加本仓库源文件夹的路径即可:
bsc -p +:$(BLUE_ETH)/src:$(BLUE_ETH)/src/includes ...
- FPGA实现ISP常见2D去噪的方法2024-01-05
- FPGA加速语言模型如何重塑生成式人工智能2024-01-05
- 全球最大的FPGA——VP19022024-01-05
- 如何在FPGA上快速搭建以太网?2024-01-05
- 请问如何将C语言算法移植到FPGA上?2024-01-04
- Xilinx FPGA的GTx的参考时钟2024-01-03