1. PCIe协议基础与Quartus开发环境搭建

PCIe(Peripheral Component Interconnect Express)是当前FPGA高速互连系统中最常见的主机接口。要在Quartus中开发一个可用的PCIe端点,第一步不是写RTL,而是把协议的分层结构、事务语义、配置空间和工具链环境同时建立起来。本章围绕这四件事展开,目标是让读者能够解释一条TLP从软件到链路的完整路径,并能在Quartus Prime中创建一个可综合、可约束、可下载的PCIe工程骨架。

1.1 PCIe分层架构:从软件请求到链路信号

PCIe采用与网络协议类似的分层模型,自上而下分为事务层(Transaction Layer)、数据链路层(Data Link Layer)和物理层(Physical Layer)。事务层负责把软件发出的读写请求转换为事务层包(TLP),并管理流量控制信用(Credit)和完成超时;数据链路层负责TLP的可靠传输,通过序列号、LCRC和ACK/NAK协议实现重传;物理层负责字节条带化、8b/10b或128b/130b编码、串并转换和差分信号发送。三者之间通过内部接口传递TLP、DLLP和有序集。

理解分层的关键在于分清“谁负责什么”。例如,一个Memory Write请求由事务层生成TLP,数据链路层为其附加序列号和LCRC,物理层将其编码后经差分对发出。接收端反向逐层剥离,最终由事务层把写数据交给目标BAR空间。若链路出现误码,物理层不会重传,而是由数据链路层的NAK机制触发重传,因此调试时看到“链路训练成功但读写失败”,问题通常不在物理层,而在事务层或配置空间。

PCIe 分层架构与 TLP 路径 主机软件 驱动 / 配置读写 事务层 TLP 生成 / Credit 完成超时管理 数据链路层 序列号 / LCRC ACK / NAK 重传 物理层 编码 / 串并转换 TLP 在发送路径上的封装变化 事务层输出 Header + Data(不含序列号与 LCRC) 数据链路层封装 Sequence Number + Header + Data + LCRC 物理层处理 加 Framing Token → 编码 → 串行差分输出 接收端反向剥离 物理层解码 → 链路层校验/去序列号 → 事务层解析 软件可见 链路可靠 电气信号 端到端

1.2 事务类型:四种基本请求与完成机制

PCIe事务层定义了四类基本事务:Memory Read、Memory Write、I/O Read/Write和Configuration Read/Write。其中Memory Read和Configuration Read属于非转发请求(Non-Posted),必须由目标返回Completion TLP;Memory Write和Configuration Write属于转发请求(Posted),不需要完成包。这一区别直接决定了FPGA端点的设计复杂度:如果实现的是Memory Write目标,只需接收并写入RAM;如果实现的是Memory Read目标,则必须在收到请求后生成带数据的Completion TLP,并正确填写Requester ID、Tag和Byte Count。

以一次64位Memory Read为例,主机发出请求TLP,Header中Length字段为1 DW,Tag为0x1A。FPGA端点收到后,从对应BAR地址读取4字节数据,构造Completion TLP,Header中Completion Status为SC(Successful Completion),Byte Count为4,Lower Address为0x0。主机收到后完成一次读事务。若FPGA未在超时时间内返回Completion,主机会触发Completion Timeout,表现为驱动读操作失败。因此,在Quartus工程中必须为读请求设计合理的响应延迟,通常建议在收到请求后的几十个时钟周期内返回,避免触发主机超时。

1.3 配置空间:端点与主机协商的窗口

PCIe配置空间为每个功能提供256字节的配置寄存器,其中前64字节是标准头部。Type 0头部用于端点设备,包含Vendor ID、Device ID、Command、Status、BAR0~BAR5、Subsystem ID等字段。主机在枚举阶段通过Configuration Read读取这些字段,确定设备类型、所需地址空间和中断方式,然后向BAR写入全1再读回,计算出每个BAR所需的地址范围,最后分配基地址。

在FPGA设计中,BAR的位宽和类型必须与硬件设计一致。例如,若FPGA内部实现了一个4KB的寄存器空间,BAR0应配置为32位Memory BAR,低12位固定为0,表示4KB对齐。若错误地声明为64位BAR,主机可能分配超出实际范围的地址,导致访问越界。Quartus的PCIe IP核在参数化时允许设置BAR数量和大小,生成后会在配置空间中体现,但用户仍需在RTL中实现对应的地址译码逻辑。

1.4 Quartus Prime安装与工程创建

Quartus Prime是Intel FPGA的官方开发工具,建议使用Pro Edition或Standard Edition,具体取决于目标器件。安装时需勾选目标器件系列(如Stratix 10、Arria 10或Cyclone 10 GX),并确保安装USB-Blaster驱动。安装完成后,首次启动需配置License文件,否则无法编译大型工程。

创建PCIe工程的基本流程如下:新建工程,选择目标器件和顶层文件;在IP Catalog中搜索“PCI Express”,根据需求选择Hard IP或Soft IP;配置链路宽度(x1/x4/x8)、参考时钟频率(100MHz)、BAR数量和大小;生成IP核后,Quartus会输出一个包含配置空间、TLP接口和物理层接口的HDL封装。此时需要将IP核的TLP接口连接到用户逻辑,并添加时序约束(SDC)和引脚约束(QSF)。

# 示例:Quartus 工程创建关键步骤
1. File → New Project Wizard
2. 选择器件:10AX115N3F40E2SG (Arria 10)
3. IP Catalog → Interface Protocols → PCI Express → Arria 10 Hard IP for PCI Express
4. 配置:Lane Width = x4, Reference Clock = 100 MHz, BAR0 = 64-bit Memory, 4 KB
5. Generate HDL → 得到 pcie_top.v 与 pcie_top.qsys
6. 添加 SDC 约束:derive_pll_clocks, derive_clock_uncertainty
7. 分配引脚:refclk0_p/n, perstn, tx/rx 差分对
8. 全编译 → 生成 .sof 文件 → 下载到 FPGA
建议在首次工程中先使用Intel提供的PCIe示例设计(Example Design),确认链路训练成功、配置空间可读、BAR可访问后,再替换为用户逻辑。这样可以把“协议问题”和“用户逻辑问题”分开定位。
注意:Quartus Prime Pro Edition与Standard Edition的PCIe IP核版本不同,Pro Edition支持更高速率和更多硬核特性,但License要求也更高。若使用Cyclone 10 GX,需确认所选器件是否包含PCIe硬核,否则只能使用Soft IP,资源占用会显著增加。