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机制触发重传,因此调试时看到“链路训练成功但读写失败”,问题通常不在物理层,而在事务层或配置空间。
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