问题现象
与驱动联调:驱动无法扫描到 Xilinx 的 PCIE 设备。
通过 ILA 抓取 pcie_link_up 信号:发现 link up 一直为低。
问题分析
出现这种情况,在 FPGA 中搭建测试环境,使用 XDMA+BRAM 的形式,减少其它模块的影响。
1. 检查 PCIE 的时钟
时钟必须使用原理图上的 GT Ref 差分时钟,通过 IBUFDSGTE 转为单端时钟。
2. 检查 PCIE 复位
PCIE 复位信号有要求:上电后,PCIE_RSTN 信号需在电源稳定后延迟一段时间再释放,通常是 100ms 以上。
这 100ms 的时间,系统主要做以下事情:
- 电源稳定时间
- 参考时钟稳定时间
- PCIe IP 核的复位和初始化时间
- 链路训练时间
典型的 100ms 时间分配:
- 0-10ms: 电源稳定 (Power Stable)
- 10-20ms: 参考时钟稳定 (Refclk Stable)
- 20-30ms: 复位释放和 PLL 锁定 (Reset Release & PLL Lock)
- 30-50ms: 物理层初始化 (PHY Initialization)
- 50-70ms: 链路训练 (Link Training)
- 70-100ms: 设备配置 (Device Configuration)
为了避免这个问题,建议在程序中添加复位控制。虽然有时硬件复位时序可以满足要求,但保险起见还是加上。
3. LANE 检查
检查你的 LANE 约束,一般 XDMA IP 核生成的时候会自带一个约束文件,约束每个 LANE 的对外接口,但我们也可以自己约束,保证端口与原理图匹配即可。
这些确认无误,还是无法 link up 的,先将 PCIE 降速为 1.0 X1,看看情况。
4. PCIE 降速
如果还是不行,那我们需要检测 pcie 的相关的几个状态。
5. 具体问题定位(PCIE LTSSM 状态)
这里我们需要查看 PCIE 的 LTSSM 状态机。LTSSM 是一种常用于 PCI Express(PCIe)接口的状态机,它可以控制 PCIe 总线的传输流程。LTSSM 由多个状态组成,每个状态都代表了不同的总线传输阶段。
5.1 给 LTSSM 信号添加 debug
首先:勾选配置界面的 Use Class Code Lookup Assistant 这个选项。
此时还是无法在端口显示出 LTSSM 信号,不要着急,按照你的流程生成 IP 核,执行完 Run Syn 操作,然后点击 Set up debug。
在这里搜索 LTSSM 的小写,就能找到 ltssm_state 的信号,将其添加到 debug 里面正常的综合实现就可以了。
5.2 LTSSM 状态说明
LTSSM 状态机根据厂商不同会有微小的差异。我的状态卡在了 08 即 Lane 顺序检测,意味着是 lane 的问题。
那我们通过这个方式监控的除了 LTSSM 信号以外,还有几个关键信号。
5.3 其余关键信号说明
- phy_rdy_n:物理层就绪,一种存在性检查。0:表示物理层就绪;1:表示异常(时钟是否存在?复位序列是否正常?PLL 是否正常锁定?电源是否 power good?)
- cfg_current_speed_o:协商的速率,PCIE1.0/2.0/3.0 分别对应 1/2/3。
- link_width:协商的宽度。
6. 故障点说明及解决
我的故障就是:
- phy_rdy_n 为 0,说明物理层就绪,时钟和复位是正常的。
- LTSSM 卡在了 0x08,且 Link_width 为 0,说明是 LANE 的异常导致的。
重新检查电路,发现主机的 TX 端,没有放置电容,而使用的是电阻,导致的 AC 耦合问题。将电阻更换为电容,链路问题解决。
可以看到 Link up 拉起,驱动可以正常检测到 PCIE 设备。


