ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

XDMA仿真与LTSSM链路训练实战指南

XDMA仿真与LTSSM链路训练实战指南 1. 为什么XDMA仿真值得花时间死磕做FPGA加速卡或者数据采集卡的朋友绕不开的一个东西就是XDMA。Xilinx现在叫AMD了但大家还是习惯叫Xilinx的XDMA IP核几乎是PCIe上位机通信的标配方案DMA读写、描述符管理、中断上报一套下来能把PCIe链路的带宽跑得七七八八。但问题在于很多人拿到XDMA的Example Design之后直接上板子调试结果链路训练失败、枚举不到设备、DMA传输卡死然后就开始怀疑人生。我见过太多这样的情况板子焊好了电源正常参考时钟也有但PCIe就是认不到设备。这时候如果没有仿真环境你只能靠猜——是LTSSM卡在哪个状态了是参考时钟的扩频没配对还是复位时序有问题每一次改代码都要重新综合、实现、生成比特流运气好二十分钟运气不好一个小时就没了。而XDMA的仿真环境可以在几分钟内给你完整的链路训练日志LTSSM从Detect到L0的每一个状态跳转都看得清清楚楚。这篇文章面向的是已经有一定Vivado使用基础、正在做PCIe相关项目的工程师。我会从XDMA IP的配置开始一步步搭建仿真环境重点讲清楚LTSSM链路训练的过程怎么看、怎么分析以及仿真中那些容易踩的坑。全文基于Vivado 2022.2版本其他版本操作逻辑类似个别界面差异我会标注出来。注意XDMA仿真对机器性能有一定要求建议至少16GB内存仿真时间会比较长尤其是包含完整LTSSM训练过程的用例。2. XDMA IP核配置那些默认值不能用的地方2.1 基础配置页的关键选项打开Vivado的IP Catalog搜索XDMA出来的全称是DMA/Bridge Subsystem for PCI Express。双击进去第一页是Basic配置。这里有几个地方必须改PCIe Device / Port Type根据你的实际硬件选。如果是Root Port模式比如你在做Host侧的仿真选Root Port如果是Endpoint模式大多数加速卡场景选Endpoint。仿真的时候如果选错了LTSSM的行为完全不一样Root Port会主动发起训练Endpoint是等待被训练。PCIe Block Location这个选项决定了你用哪个PCIe硬核。对于UltraScale系列通常选X0Y0。如果你不确定去看你的板子原理图上PCIe接口连的是哪个Bank。Lane Width最大链路宽度。仿真的时候建议先设成x1等链路训练跑通了再改成x4或x8。为什么因为x1的LTSSM状态机最简单出了问题容易定位。我见过有人一上来就设x16结果仿真跑了一天都没到L0最后发现是一个Lane的映射搞错了。Maximum Link Speed5.0 GT/s对应Gen28.0 GT/s对应Gen3。仿真环境里Gen2就够用了Gen3的仿真时间会显著增加而且很多问题在Gen2就能暴露出来。2.2 BAR配置与地址映射第二页是PCIe BARs的配置。XDMA默认会给你几个BARBAR0通常用于XDMA的配置寄存器BAR1用于AXI Lite Master接口BAR2用于DMA的地址映射这里有个容易忽略的点BAR的Size要和你实际需要访问的地址空间匹配。仿真的时候如果BAR Size设小了上位机枚举的时候会报地址冲突。我一般建议BAR0设成1MBBAR1设成1MBBAR2根据DMA缓冲区的大小来定通常设成16MB或更大。实操心得在仿真阶段可以把所有BAR都设成最小尺寸比如64KB这样仿真模型的内存占用会小很多跑起来更快。等仿真通过了再改成实际需要的尺寸。2.3 中断与MSI配置第三页是中断配置。XDMA支持Legacy中断、MSI和MSI-X。仿真的时候建议选MSI-X因为这是实际项目中最常用的。MSI-X的Table Size根据你的中断源数量来定一般设成8或16就够了。这里有个坑MSI-X的Table和PBAPending Bit Array在仿真模型中的地址映射。如果你在仿真中看到中断上报了但上位机没收到大概率是Table的地址没配对。XDMA IP会自动分配这些地址但你需要确认它们落在BAR的地址范围内。2.4 时钟与复位配置第四页是Clock和Reset。这里的关键参数是Reference Clock Frequency默认是100MHz。如果你的板子用的是其他频率比如125MHz必须在这里改否则LTSSM训练的时候频率不匹配链路根本起不来。复位方面XDMA需要一个User Reset信号通常来自你的逻辑。仿真的时候可以把这个复位拉低固定几个周期模拟上电复位的时序。配置完成后点击OK生成IP。生成之后右键IP选择Open IP Example DesignVivado会自动生成一个包含XDMA IP和仿真测试平台的工程。这个Example Design就是我们后面仿真的基础。3. 仿真环境搭建从Example Design到自定义Testbench3.1 Example Design的结构拆解Vivado生成的XDMA Example Design包含以下几个关键文件xdma_0_example_design.v顶层文件例化了XDMA IP和测试逻辑xdma_0_sim.v仿真用的XDMA模型包含了PCIe链路的Behavioral模型xdma_0_pcie_ep.vEndpoint模式的PCIe硬核封装xdma_0_sim_testbench.v仿真测试平台这个Example Design默认会跑一个简单的DMA读写测试。但它的仿真时间很短LTSSM的训练过程可能还没跑完就结束了。我们需要修改Testbench让它跑完整的链路训练过程。3.2 修改Testbench以观察LTSSM打开xdma_0_sim_testbench.v找到LTSSM相关的信号。XDMA的仿真模型会输出LTSSM的状态通常是一个4位的信号比如ltssm_state。你需要把这个信号加到波形窗口里。// 在Testbench中例化XDMA时把LTSSM状态引出来 .xdma_0_ltssm_state(ltssm_state),然后在仿真脚本中设置足够的仿真时间。LTSSM从Detect到L0通常需要几十微秒的仿真时间如果时钟是100MHz那就是几千个时钟周期。建议把仿真时间设成至少1ms确保链路训练完成。# 在Vivado的仿真脚本中设置 run 1ms3.3 仿真模型的时钟与复位处理XDMA的仿真模型需要两个时钟PCIe参考时钟和AXI时钟。参考时钟通常是100MHzAXI时钟根据你的设计来定一般是250MHz或300MHz。复位方面仿真模型需要一个sys_rst_n信号。这个信号在上电后需要保持低电平至少100ns然后拉高。如果复位时间不够LTSSM可能无法正确初始化。// 典型的复位时序 initial begin sys_rst_n 0; #200; sys_rst_n 1; end注意仿真中如果看到LTSSM一直卡在Detect状态先检查参考时钟有没有正常翻转再检查复位信号有没有正确释放。3.4 仿真加速技巧XDMA的仿真跑起来很慢尤其是包含完整LTSSM训练过程的用例。这里有几个加速技巧关闭不必要的调试信号在仿真模型中很多调试信号默认是打开的会拖慢仿真速度。可以在仿真配置中关掉。使用编译后的仿真模型Vivado支持把仿真模型编译成共享库下次仿真时直接加载省去编译时间。分段仿真先跑LTSSM训练确认链路到L0之后再跑DMA传输。不要一次性跑完所有测试。4. LTSSM链路训练全解析从Detect到L0的每一步4.1 LTSSM状态机概览PCIe的链路训练状态机LTSSM是PCIe协议中最核心的部分之一。它负责在链路初始化时让两端的设备协商出共同的链路参数速率、宽度、均衡等最终进入L0状态开始正常的数据传输。LTSSM的主要状态包括状态说明典型停留时间Detect检测链路上是否有设备几微秒Polling交换TS1/TS2序列协商速率几十微秒Configuration协商链路宽度和Lane映射几十微秒Recovery速率切换或错误恢复视情况而定L0正常工作状态持续在XDMA仿真中你可以通过ltssm_state信号观察这些状态的跳转。每个状态都有对应的编码具体编码值参考PCIe规范或XDMA的仿真模型文档。4.2 Detect状态链路检测的细节Detect状态是LTSSM的第一个状态。在这个状态下设备会检测链路上是否有接收端。具体来说它会发送Detect序列一系列的电平跳变然后检查是否有回应。在仿真中如果你看到LTSSM卡在Detect状态可能的原因有参考时钟没有正确连接检查仿真模型中参考时钟的端口有没有接上。复位信号没有释放检查sys_rst_n是否已经拉高。链路对端没有响应在仿真中XDMA的仿真模型会模拟对端设备但如果配置不对对端可能不会响应。实操心得Detect状态在仿真中通常很快就能通过如果卡在这里超过10微秒基本可以确定是时钟或复位的问题。4.3 Polling状态速率协商的关键Polling状态是LTSSM中最复杂的状态之一。在这个状态下两端设备会交换TS1和TS2有序集协商链路速率。TS1和TS2是PCIe协议中定义的特殊序列包含了链路号、Lane号、速率等信息。在仿真中你可以通过观察TS1/TS2的交换过程判断速率协商是否成功。Polling状态又分为几个子状态Polling.Active发送TS1等待接收8个连续的TS1或TS2Polling.Compliance用于测试环境正常仿真中不会进入Polling.Configuration发送TS2确认速率协商完成如果LTSSM卡在Polling状态可能的原因有速率不匹配两端的Maximum Link Speed设置不一致。参考时钟频率偏差仿真中参考时钟的频率必须精确否则TS1/TS2的位宽会出错。Lane映射错误如果Lane的物理连接和逻辑映射不一致TS1/TS2无法正确交换。4.4 Configuration状态链路宽度协商Configuration状态负责协商链路宽度和Lane映射。在这个状态下设备会发送TS1序列其中包含了Link Number和Lane Number。对于多Lane的链路Configuration状态会逐个Lane进行协商。如果某个Lane没有响应链路宽度会降级。比如你配置的是x4但只有一个Lane能通最终链路会协商成x1。在仿真中你可以通过观察link_width信号来确认最终协商的链路宽度。如果协商结果和预期不符检查Lane的映射关系。4.5 进入L0链路训练完成的标志当LTSSM进入L0状态时链路训练就完成了。此时PCIe链路可以开始正常的数据传输XDMA的DMA引擎也可以开始工作。在仿真中进入L0后你应该能看到ltssm_state信号变成L0对应的编码link_up信号拉高DMA传输开始正常工作如果链路训练完成后DMA传输有问题那问题就不在LTSSM了需要检查XDMA的配置寄存器或DMA描述符。5. 仿真中常见的坑与排查思路5.1 链路训练卡在Polling状态这是最常见的问题之一。仿真跑了几十微秒LTSSM一直在Polling状态打转。排查思路检查参考时钟用波形窗口确认参考时钟的频率和占空比。100MHz的时钟周期是10ns如果周期不对TS1/TS2的位宽会出错。检查速率配置确认XDMA IP的Maximum Link Speed和仿真模型中的速率设置一致。检查TS1/TS2序列在波形中观察TS1/TS2的发送和接收看看有没有收到对端的响应。5.2 DMA传输卡死链路训练到L0了但DMA传输卡死。这种情况通常是描述符配置有问题。排查思路检查描述符地址确认描述符的地址在BAR的地址范围内。检查DMA引擎状态XDMA的仿真模型会输出DMA引擎的状态信号观察它是否在正常运行。检查中断如果DMA传输完成了但上位机没收到中断检查MSI-X的配置。5.3 仿真时间不够导致误判XDMA的仿真很慢有时候你看到LTSSM卡在某个状态其实只是仿真时间不够状态还没跳转。建议把仿真时间设长一点至少1ms确保所有状态都有足够的时间完成。注意仿真时间设长了仿真文件会很大。建议分段保存波形或者只保存关键信号的波形。5.4 仿真模型与硬件行为的差异XDMA的仿真模型是Behavioral模型和实际的硬件行为有一些差异。比如仿真模型中LTSSM的状态跳转是理想化的实际硬件中可能会有更多的重试和超时。仿真模型中的时钟是理想的实际硬件中时钟会有抖动。仿真模型中的复位是同步的实际硬件中复位可能是异步的。因此仿真通过不代表硬件一定能跑通。仿真只是帮你排除逻辑错误硬件调试还需要考虑信号完整性、电源噪声等因素。6. 从仿真到上板的过渡经验6.1 仿真通过后的检查清单在把仿真通过的代码上板之前建议做以下检查时钟约束确认XDC文件中包含了参考时钟和AXI时钟的约束。引脚约束确认PCIe的引脚约束和板子的原理图一致。复位约束确认复位信号的时序约束正确。电源检查确认板子的PCIe电源正常。6.2 上板后链路训练失败的排查如果上板后链路训练失败首先检查参考时钟用示波器测量参考时钟的频率和幅度。复位时序用逻辑分析仪抓取复位信号的时序。LTSSM状态如果板子支持可以通过JTAG读取LTSSM的状态。6.3 仿真与实测的差异处理仿真和实测最大的差异在于信号完整性。仿真中信号是理想的实测中信号会有反射、串扰、衰减。如果仿真通过但实测失败优先检查PCB的走线和阻抗匹配。我在实际项目中遇到过这样的情况仿真中链路训练完美上板后却频繁掉链路。最后发现是PCB上PCIe差分对的阻抗不匹配导致信号反射严重。重新设计PCB后问题解决。实操心得PCIe的差分对走线一定要控制阻抗通常是100欧姆差分阻抗。走线长度也要匹配偏差不要超过5mil。7. 一些提高仿真效率的实用技巧7.1 使用Vivado的仿真编译选项Vivado的仿真器支持一些编译选项可以显著提高仿真速度# 在仿真脚本中添加 set_property -name {xsim.simulate.runtime} -value {1ms} -objects [get_filesets sim_1] set_property -name {xsim.compile.xvlog.more_options} -value {-O3} -objects [get_filesets sim_1]-O3是最高级别的优化可以加快仿真速度但会增加编译时间。7.2 分段仿真策略不要一次性跑完所有测试。建议分成几个阶段第一阶段只跑LTSSM训练确认链路到L0。第二阶段跑简单的DMA读写确认DMA引擎正常。第三阶段跑完整的压力测试确认带宽和稳定性。每个阶段单独保存波形方便对比分析。7.3 波形保存的技巧XDMA的仿真波形很大如果保存所有信号波形文件可能几个GB。建议只保存关键信号LTSSM状态、链路宽度、DMA引擎状态、中断信号。使用Vivado的波形数据库WDB格式比VCD格式小很多。分段保存波形每个阶段一个文件。7.4 利用仿真日志定位问题XDMA的仿真模型会输出详细的日志信息包括LTSSM的状态跳转、TS1/TS2的交换、DMA传输的状态等。在仿真结束后仔细阅读日志往往能快速定位问题。# 仿真日志通常在这个路径下 ./project.sim/sim_1/behav/xsim/simulate.log日志中如果有LTSSM timeout或DMA error之类的关键字直接搜索这些关键字就能找到问题所在。8. 关于XDMA仿真的一些个人体会做了这么多年的PCIe项目XDMA的仿真环境是我见过的最有价值的调试工具之一。它不能替代硬件调试但能帮你排除掉80%的逻辑错误。剩下的20%才是真正需要上板子才能发现的问题。我个人的习惯是任何PCIe相关的改动先在仿真里跑一遍LTSSM训练确认链路能到L0再跑DMA传输。这样上板的时候至少链路层是没问题的可以把精力集中在信号完整性和电源上。还有一点XDMA的仿真模型在不同Vivado版本之间有一些差异。比如2022.2版本的仿真模型比2018.3版本的要完善很多LTSSM的状态输出更详细。如果你用的是老版本建议升级到2020.2以上。最后分享一个小技巧在仿真中你可以通过修改Testbench人为注入一些错误比如让参考时钟抖动、让复位信号提前释放观察LTSSM的反应。这样可以帮助你理解LTSSM的容错机制在实际调试中更快地定位问题。
返回列表