4. Vivado中构建PCIe端点工程

在Zynq平台上构建PCIe端点(Endpoint,EP)工程,核心工作并不是写RTL,而是在Vivado的IP Integrator(IPI)中把Zynq PS、PCIe IP核以及必要的时钟、复位、AXI互连资源正确"拼装"起来,再通过Block Design的地址分配与约束完成综合、实现和比特流生成。本章以一个典型的Zynq-7000 + PCIe Gen2 x4端点设计为例,走通从新建工程到生成.bit的全过程,并说明每一步真正需要关注的参数与判断依据。

一、工程与器件选择

在Vivado中新建RTL工程,器件选择要与实际开发板一致。以Zynq-7000为例,常见器件为xc7z020clg484-1或xc7z045ffg900-2。器件型号决定了可用的GTX收发器数量、PCIe硬核位置以及PS端可用的HP/GP接口数量,选错器件会导致PCIe IP核无法例化或引脚约束失败。工程创建完成后,先不要急着添加源文件,直接进入IP Integrator创建Block Design。

二、添加并配置Zynq PS

在Block Design中首先添加ZYNQ7 Processing System。双击进入配置界面,重点处理以下几项:

  • PS-PL Configuration:使能至少一个AXI GP主接口(M_AXI_GP0),用于PS访问PCIe IP核的配置空间和BAR空间;若需要PCIe DMA向DDR搬运数据,还需使能一个S_AXI_HP从接口(如S_AXI_HP0),并设置其数据位宽为64位以匹配PCIe的高带宽。
  • Clock Configuration:使能FCLK_CLK0,频率设为100MHz,作为PCIe IP核的AXI-Lite配置时钟和用户逻辑时钟;若PCIe参考时钟由PS的FCLK提供,还需确认该时钟能否满足PCIe IP对参考时钟频率的要求(通常为100MHz)。
  • Interrupts:使能PL-PS中断端口,例如IRQ_F2P,用于把PCIe IP核产生的中断信号接入PS的GIC。
  • DDR配置:确认DDR型号与容量,因为PCIe DMA的目标缓冲区通常位于DDR中。

配置完成后,PS会导出M_AXI_GP0、S_AXI_HP0、FCLK_CLK0、IRQ_F2P等接口,供后续连接使用。

三、添加并配置PCIe IP核

添加AXI PCIe或PCIe Gen2IP核(不同Vivado版本名称略有差异,7系列常用7 Series Integrated Block for PCIe配合AXI桥接)。配置界面中需要重点设置的参数包括:

  • 链路宽度(Link Width):可选x1、x2、x4、x8。实际可用宽度受开发板PCIe金手指走线和FPGA GTX资源限制。示例中设为x4。
  • 链路速度(Link Speed):Gen1(2.5GT/s)或Gen2(5.0GT/s)。示例中设为Gen2,对应每通道约500MB/s的有效带宽,x4理论带宽约2GB/s。
  • 参考时钟频率:通常为100MHz,需与板上提供的差分参考时钟一致。
  • BAR配置:至少配置一个BAR,例如BAR0设为64位、可预取、大小4KB~1MB,用于映射用户寄存器或DMA控制寄存器;若需要大块数据缓冲,可再配置BAR1为32位、不可预取、大小16MB。
  • 中断:使能Legacy Interrupt或MSI/MSI-X。Zynq PS的GIC支持MSI,推荐使能MSI,中断数量设为1~4。
  • AXI接口:使能AXI-Lite主接口用于配置空间访问,使能AXI Memory Mapped接口用于BAR空间数据访问。

配置完成后,IP核会导出PCIe差分收发对、参考时钟输入、复位输出以及AXI接口。

四、连接与地址分配

在Block Design中完成以下连接:

  1. PS的M_AXI_GP0连接到PCIe IP的S_AXI(AXI-Lite配置接口),使PS能够读写PCIe配置空间和BAR。
  2. PCIe IP的M_AXI(Memory Mapped主接口)连接到PS的S_AXI_HP0,使PCIe设备能够通过DMA直接访问DDR。
  3. PS的FCLK_CLK0连接到PCIe IP的axi_aclk,FCLK_RESET0_N连接到axi_aresetn。
  4. PCIe IP的中断输出interrupt_out连接到PS的IRQ_F2P。
  5. PCIe IP的差分收发对pcie_7x_mgt导出为外部端口,参考时钟refclk导出为外部差分输入。

连接完成后,在Address Editor中为PCIe IP的AXI-Lite接口分配地址范围,例如0x4000_0000起始、4KB大小;为PCIe IP的M_AXI接口分配DDR地址范围,例如0x0000_0000~0x1FFF_FFFF(512MB),确保PCIe DMA能够访问到DDR缓冲区。

Zynq PCIe端点Block Design连接与地址映射 Zynq PS M_AXI_GP0 (主) S_AXI_HP0 (从) FCLK_CLK0 / RESET IRQ_F2P (中断输入) DDR 控制器 PCIe IP核 (Gen2 x4) S_AXI (AXI-Lite 配置) M_AXI (Memory Mapped) axi_aclk / axi_aresetn interrupt_out BAR0: 64bit 4KB / BAR1: 32bit 16MB AXI-Lite 配置访问 DMA 数据搬运 时钟/复位 MSI 中断 PCIe 差分收发对 pcie_7x_mgt (x4) 参考时钟输入 100MHz 差分 Address Editor 地址分配 PCIe S_AXI (AXI-Lite) 0x4000_0000 ~ 0x4000_0FFF (4KB) PCIe M_AXI → DDR 0x0000_0000 ~ 0x1FFF_FFFF (512MB)

五、综合、实现与比特流生成

Block Design验证通过后,右键选择Create HDL Wrapper生成顶层HDL。随后在Sources窗口中确认顶层模块正确,并添加XDC约束文件,至少包含以下内容:

# PCIe参考时钟差分输入
set_property PACKAGE_PIN F6 [get_ports refclk_p]
set_property IOSTANDARD LVDS [get_ports refclk_p]
create_clock -period 10.000 -name refclk [get_ports refclk_p]

# PCIe复位信号
set_property PACKAGE_PIN G5 [get_ports pcie_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports pcie_rst_n]

# GTX收发器位置约束(根据器件手册确定)
set_property LOC GTXE2_CHANNEL_X0Y0 [get_cells ...]

约束文件编写完成后,依次执行Run Synthesis、Run Implementation、Generate Bitstream。综合阶段重点关注是否有PCIe IP核相关的严重警告,例如参考时钟未约束、GTX位置未分配等;实现阶段重点关注时序是否收敛,尤其是axi_aclk域下的建立时间和保持时间。若时序不收敛,可尝试降低AXI时钟频率、优化DMA数据路径或增加流水线寄存器。

生成比特流后,建议先通过Open Implemented Design查看PCIe IP核的GTX收发器是否被正确放置到与金手指相连的Bank上。若GTX位置错误,即使比特流生成成功,链路也无法建立。

六、关键参数速查

配置项示例值说明
链路宽度x4受GTX资源和板级走线限制
链路速度Gen2 (5.0GT/s)x4理论带宽约2GB/s
参考时钟100MHz差分需与板上晶振一致
BAR064位 / 4KB / 可预取映射用户寄存器
BAR132位 / 16MB / 不可预取映射数据缓冲区
中断MSI,1个向量接入PS IRQ_F2P
AXI-Lite地址0x4000_0000PS访问配置空间
DMA地址0x0000_0000PCIe访问DDR

完成以上步骤后,一个可综合、可实现、可生成比特流的PCIe端点工程就构建完毕。下一步需要把比特流下载到开发板,并通过主机端枚举设备、读取配置空间来验证链路是否真正建立。