FPGA 设计详细笔记XDMA PCIe AXI-Stream本笔记基于一系列实际问题整理主题包括PCIe 配置空间关键字段Vendor ID / Device ID / Class Code / BARVivado 里 XDMA / PCIe 参数在哪里配置XDMA AXI-Stream 是否会用到 BARBAR 控制寄存器典型地址分配示例目录一、PCIe 配置空间关键字段二、Vivado 里 XDMA / PCIe 参数配置位置三、XDMA AXI-Stream 与 BAR 的关系四、BAR 控制寄存器典型地址分配五、软件侧访问示例六、设计建议与易错点七、快速记忆卡一、PCIe 配置空间关键字段主机在枚举 PCIe 设备时会先读设备的配置空间Configuration Space用来判断这是谁的设备、是什么设备、加载什么驱动、需要多大地址空间。1.1 四个核心字段一句话理解字段含义作用Vendor ID厂家身份证表示设备是哪家公司的由 PCI-SIG 分配Device ID厂家内部产品型号表示该厂商的哪一款设备Class Code设备功能类别表示设备是干什么的网卡/显卡/存储/桥…BAR地址映射窗口主机分配给设备的可访问地址区间1.2 Vendor ID厂商 ID表示设备由谁生产由 PCI-SIG 统一分配。例如 Intel、AMD/Xilinx、NVIDIA 各有自己的 Vendor ID。驱动常用Vendor ID Device ID共同匹配设备。{PCI_DEVICE(0x10EE,0x903F)}// 0x10EE: Xilinx 的 Vendor ID// 0x903F: 某个具体 Device ID1.3 Device ID设备 ID表示某厂商定义的具体产品型号或功能编号。同一家厂商的不同设计/功能版本常用不同Device ID区分。与 Vendor ID 联合使用因为一家厂商可能有很多 PCIe 设备。1.4 Class Code设备类别代码说明设备从功能上属于哪一类而非属于哪家公司。操作系统据此判断是否使用通用类驱动。常见类别Base Class含义0x01Mass Storage Controller存储控制器0x02Network Controller网络控制器0x03Display Controller显示控制器0x06Bridge Device桥设备0x0CSerial Bus Controller串行总线控制器Class Code 通常分为Base ClassSub ClassProgramming Interface三段合称 Class Code。自定义 FPGA 加速卡常设为 Memory controller / Processing accelerator / Vendor-specific device多依赖专用驱动。1.5 BARBase Address Register基址寄存器本质PCIe 设备不直接拿固定地址而是通过 BAR 向主机“申请”一段地址窗口。主机枚举时分配地址之后 CPU 通过该地址访问设备内部寄存器或存储区。工作过程设备声明需要的 BAR 大小 ↓ 主机分配地址例如 BAR0 - 0xA000_0000 ~ 0xA000_FFFF ↓ 软件访问 *(volatile uint32_t *)(0xA0000000) ↓ 实际访问 对设备内部寄存器的访问BAR 常见类型Memory BAR最常见按内存方式读写I/O BAR老式设备较多现代 PCIe 较少用32-bit / 64-bit BAR表示映射地址空间宽度高性能设备常用 64-bit1.6 枚举流程中四者的关系第一步读 Vendor ID Device ID - 这是哪家的哪款设备 第二步读 Class Code - 它是干什么的 第三步读 BAR0/BAR1/BAR2... - 需要多大地址空间分配地址类比员工入职Vendor ID你是哪家公司的人Device ID你的工号/岗位编号Class Code你的岗位类别研发/财务/行政BAR公司分配给你的办公区域和工位1.7lspci中的体现03:00.0 Memory controller [0580]: Xilinx Corporation Device [10ee:903f]10eeVendor ID903fDevice ID0580Class Code 相关Region 0 / Region 2各 BAR 映射出的地址空间二、Vivado 里 XDMA / PCIe 参数配置位置绝大部分参数都在XDMA IP 的配置界面里设置。2.1 进入配置界面Block Design 方式最常见Flow Navigator - IP Integrator - Open Block Design - 双击 xdma_0 - Customize IP单独实例化方式IP Catalog - 搜索 XDMA - DMA/Bridge Subsystem for PCI Express - Add IP - Customize IP2.2 参数分布概览分页名称随版本略有差异配置内容PCIe IDs/PCIe ConfigurationVendor ID、Device ID、Revision ID、Subsystem ID、Class CodeBARs/PCIe BARsBAR 启用、大小、32/64-bit、类型PCIe: Link Capabilities/BasicGen1/2/3、Lane 宽度 x1/x4/x8DMA/AXIH2C/C2H 通道数、AXI-MM/AXI-Stream、数据位宽Interrupts/MSI/MSI-X用户中断、中断数量2.3 各字段配置要点Vendor ID / Device ID / Class CodePCIe IDs 页开发实验可暂用默认值正式产品应使用合法的自有 ID。不同卡 / 不同功能版本建议用不同 Device ID 便于驱动区分。BARBARs 页可配置启用哪个 BAR、大小、32/64-bit、类型。典型BAR0 给 XDMA/控制BAR2 给用户 AXI-Lite 寄存器。BAR 不是越大越好控制空间几十~几百 KB 通常够用。大数据走 DMA不要靠 BAR。PCIe 链路Gen3 x8Link Capabilities 页Maximum Link Speed Gen3 Link Width X8这里配的是“能力上限”。实际是否跑到 Gen3 x8还取决于器件、板卡走线、插槽电气宽度、主机 BIOS/Root Complex、信号质量。最终以协商结果为准。AXI-Stream / AXI-MM / DMADMA/AXI 页流传输启用 H2C/C2H AXI-Stream存储映射用 AXI Memory Mapped。H2C/C2H 通道数入门常用 1 H2C 1 C2H。AXI 数据位宽64/128/256-bit越宽吞吐越高但用户逻辑要跟得上。中断Interrupts 页是否启用用户中断、中断数量、MSI/MSI-X 能力。2.4 建议查看顺序1. 链路参数Gen3 / x8 2. 设备身份Vendor ID / Device ID / Class Code 3. BAR开几个、多大、用户寄存器挂哪个 4. DMA 接口模式Stream/MM、通道数、位宽 5. 中断MSI / 用户中断2.5 配置后的验证Vivado 侧检查 AXI-Stream 端口、BAR 接口、中断端口是否生成链路速率/lane 摘要是否正确。主机侧lspci-nnlspci-vv重点看Vendor ID/Device ID/ClassRegion 0 / Region 2BARLnkCap设备支持的最大链路能力LnkSta当前实际链路状态例如Speed 8GT/s, Width x8三、XDMA AXI-Stream 与 BAR 的关系结论XDMA AXI-Stream 通常仍会用到 BAR但 BAR 负责控制/状态访问不负责大数据流大数据走 H2C/C2H 的 AXI-Stream DMA 通道。3.1 数据面与控制面分工数据面大数据 H2C AXI-Stream PC - FPGA C2H AXI-Stream FPGA - PC 控制面小量配置/状态 BAR - AXI-Lite 控制寄存器 启动、模式、长度、状态、中断、错误计数3.2 为什么 Stream 还需要 BARAXI-Stream 只解决“数据怎么流动”不解决“设备怎么配置和管理”。诸如何时启动、工作模式、帧长、是否完成、是否出错、是否触发中断等信息更适合放在 BAR 对应的寄存器里而不是塞进 Stream 数据。3.3 典型结构PC |-- 通过 BAR 访问控制寄存器 |-- 通过 XDMA H2C/C2H 传大块数据 v ------------------------- | XDMA | | - BAR / AXI-Lite |---- 控制寄存器 | - H2C AXI-Stream |---- 用户逻辑 | - C2H AXI-Stream |---- 用户逻辑 -------------------------3.4 BAR 用得多 / 用得少的场景场景BAR 需求纯数据回环收到啥发回啥BAR 极少甚至几乎不用改配置启停控制、模式切换、帧长配置、FIFO 监控、错误统计、中断、参数下发BAR 必不可少一句话BAR 管控制AXI-Stream 管数据。四、BAR 控制寄存器典型地址分配前提约定BAR0 大小 64 KB先用前 4 KB寄存器宽度 32-bit按 4 字节对齐低地址放基础控制高地址放状态/统计4.1 基础寄存器表偏移寄存器名属性说明0x0000VERSIONRO版本号0x0004SCRATCHRW测试寄存器写入回读做连通性检查0x0008CTRLRW总控制0x000CSTATUSRO总状态0x0010IRQ_ENABLERW中断使能0x0014IRQ_STATUSRW1C中断状态写 1 清除0x0018DMA_CFGRWDMA/流通道控制参数0x001CPKT_LENRW单包/帧长度0x0020H2C_PKT_CNTROH2C 接收包计数0x0024C2H_PKT_CNTROC2H 发送包计数0x0028H2C_BYTE_CNT_LROH2C 字节计数低 32 位0x002CH2C_BYTE_CNT_HROH2C 字节计数高 32 位0x0030C2H_BYTE_CNT_LROC2H 字节计数低 32 位0x0034C2H_BYTE_CNT_HROC2H 字节计数高 32 位0x0038ERR_STATUSRO错误状态0x003CERR_CLEARWO错误清除0x0040H2C_FIFO_LEVELROH2C FIFO 水位0x0044C2H_FIFO_LEVELROC2H FIFO 水位0x0048STREAM_MODERW流模式配置0x004CTEST_MODERW测试/回环模式0x0050~0x005CUSER_PARAM0~3RW用户参数4.2 关键寄存器位定义CTRL 0x0008bit名称说明0start写 1 启动脉冲语义硬件自清零1stop写 1 停止2soft_reset写 1 软复位3loopback_enH2C-C2H 回环4c2h_en允许向主机发流5h2c_en允许接收主机流31:16reserved保留STATUS 0x000Cbit名称说明0busy正在运行1idle空闲2h2c_activeH2C 正在接收3c2h_activeC2H 正在发送4fifo_overflowFIFO 溢出5fifo_underflowFIFO 欠载6dma_done处理完成7error有错误31:8reserved保留IRQ_ENABLE 0x0010bit名称说明0done_irq_en完成中断使能1err_irq_en错误中断使能2h2c_irq_enH2C 事件中断使能3c2h_irq_enC2H 事件中断使能IRQ_STATUS 0x0014RW1Cbit名称说明0done_irq完成中断挂起1err_irq错误中断挂起2h2c_irqH2C 事件3c2h_irqC2H 事件write_reg(IRQ_STATUS,0x1);// 写 1 清 done_irq4.3 按功能分区的地址规划推荐地址范围功能0x0000 ~ 0x00FF基础识别、版本、全局控制0x0100 ~ 0x01FFH2C 通道控制与状态0x0200 ~ 0x02FFC2H 通道控制与状态0x0300 ~ 0x03FF中断与错误状态0x0400 ~ 0x04FF测试与回环模式0x0500 ~ 0x05FF用户算法参数0x0600 ~ 0x06FF统计计数器0x0700 ~ 0x07FF调试观测寄存器每个功能块预留0x100字节方便后续扩展。4.4 最小可用寄存器集合偏移名称用途0x0000VERSION识别版本0x0004SCRATCH测试读写0x0008CTRL启动/停止/复位0x000CSTATUS忙/空闲/错误0x0010PKT_LEN包长配置0x0014IRQ_STATUS中断状态0x0018ERR_STATUS错误状态足以支撑BAR 联通测试、启停控制、长度配置、状态读回、基本中断处理。五、软件侧访问示例假设 BAR0 映射到用户空间后基地址为bar0_base#defineREG_VERSION0x0000#defineREG_SCRATCH0x0004#defineREG_CTRL0x0008#defineREG_STATUS0x000C#defineREG_IRQ_STATUS0x0014#defineREG_PKT_LEN0x001C// 连通性自检write32(bar0_baseREG_SCRATCH,0xA5A5A5A5);assert(read32(bar0_baseREG_SCRATCH)0xA5A5A5A5);// 配包长write32(bar0_baseREG_PKT_LEN,4096);// 启动write32(bar0_baseREG_CTRL,0x1);// 轮询状态uint32_tstatusread32(bar0_baseREG_STATUS);// 清中断write32(bar0_baseREG_IRQ_STATUS,0x1);大数据传输不走以上寄存器而是通过 XDMA 提供的 H2C/C2H 设备节点如 Linux 下的/dev/xdma0_h2c_0、/dev/xdma0_c2h_0进行读写。六、设计建议与易错点寄存器设计寄存器按 4 字节对齐最符合 AXI-Lite 与软件访问习惯。控制位与状态位分开不要混在一个寄存器里否则调试很乱。中断状态用RW1C写 1 清除最常用好用。保留VERSION和SCRATCH联调时非常有用。统计计数器字节数/包数建议做成 64 位高速 DMA 下 32 位易回绕。地址不要排太满预留空洞便于扩展。BAR / DMA 分工控制面走 BAR数据面走 DMA不要用 BAR 搬大数据。BAR 大小够用即可过大没有必要。PCIe 链路Vivado 中配的 Gen3 x8 是“能力上限”实际链路以协商结果为准。上板后务必用lspci -vv查LnkSta确认真实速率和宽度。安全/规范正式产品使用合法的自有 Vendor ID避免直接沿用参考设计的商用 ID 量产。七、快速记忆卡Vendor ID 看厂家Device ID 看型号Class Code 看功能分类BAR 看地址映射窗口。XDMA AXI-Stream 里BAR 管控制AXI-Stream 管数据。Gen3 x8 在 Vivado 里配的是能力上限实际看lspci的 LnkSta 协商结果。BAR 寄存器布局低地址放版本/测试/控制中段放 H2C/C2H 状态与参数再放中断/错误/统计最后放用户参数与调试。本笔记可根据实际工程持续补充可进一步加入 Verilog AXI-Lite 从机实现、C 端用户态/驱动完整代码、AXI-Stream 回环工程的搭建步骤等内容。