引言

Xillyp2p 旨在两块 FPGA 之间维持稳健可靠的通信流,即便物理链路偶尔出现不稳定或信号质量下降,也能保证通信的持续。这意味着,物理链路的问题对用户应用程序而言几乎是透明的——尤其是在双向物理链路上:未能正确到达的数据会被重传,这仅仅会降低带宽的有效利用率,而这种降低可能根本不会被察觉到。

因此,建议持续监测 Xillyp2p 输出端口所提供的状态信号,并以适当方式将这些信号呈现给操作人员,以便在物理链路出现问题时能够及时采取应对措施。针对 Ultrascale 的设计示例(以及针对 7 系列 FPGA 的设计示例)中,给出了如何将状态信号连接到 LED 的建议,使得仅持续一个时钟周期的短暂事件(尤其是比特错误)也能被明显显示出来。

这些状态信号在 FPGA 开发过程中也大有裨益,因为它们能提供有关潜在问题原因的一些信息。尤其应当将 status_link_partner_mismatch 这个输出端口的状态显示出来(例如用 LED 指示),因为它指示了链路对端的 IP 核是否因不匹配而被拒绝——即对端的 IP 核与当前 IP 核不属于 “IP Core Factory” 中相互配对的一组,这种情况在 FPGA 项目开发中很容易出现。

另外,关于如何检查 MGT 或 SERDES 是否工作正常,请参阅本指南末尾的建议。

除了监测状态信号之外,还建议在 FPGA 项目开发期间,通过主动注入比特错误的方式来测试应用程序对异常状况的响应能力。有关这一点,可以参考 Xillyp2p 端口与 API 指南 中提到的 error_test_rate 输入端口。

主要状态输出端口概述

  • status_link_down:当该输出端口为高电平时,表示通信链路尚未准备好传输数据。具体原因可通过其他状态信号来判断。请注意,该输出端口主要用于指示问题,而非实时指示当前能否发送或接收数据:即使该输出为高电平,有效数据仍然有可能被发送和接收,因为该输出的响应存在一定延迟。当该输出为低电平时,这是链路可用的主要标志。
  • status_link_partner_mismatch:当该输出端口为高电平时,表示对端的 Xillyp2p IP 核不属于与之正确配对的另一 IP 核。出现这种情况时,需要更换对端 FPGA 中的比特流,使其基于正确的 Xillyp2p IP 核重新生成。
  • status_initializing:该输出端口仅在物理链路为双向时存在。当该端口为高电平时,表示双向协议尚未完成初始化。具体原因由其他状态信号指示:
    • 如果该输出为高电平且 status_link_partner_mismatch 也为高电平,原因是对端与本端的 Xillyp2p IP 核不匹配(见上文)。
    • 如果该输出为高电平且 status_debug 的第 0 位为高电平,则表示物理链路上到达的数据流已断开或严重畸形(例如,MGT 或 SERDES 配置错误,或者接收端未同步)。
    • 如果该输出偶尔变为高电平(尤其是在高速传输数据时),原因可能是两侧的时钟频率相差过大。换句话说,两侧时钟之间的频率容差超过了生成 Xillyp2p IP 核时所指定的容差范围。
    • 除了以上三种原因外,链路应当能够快速完成初始化,并且不应出现需要重新初始化的情况。因此,如果排除了上述三种原因,建议检查是否存在导致 FPGA 整体工作异常的因素,例如:时序约束不正确、时序约束未能满足、时钟不稳定、供电电压问题等。
  • status_bit_error:当物理数据链路上发生比特错误时,该输出会在一个时钟周期内保持高电平。有时,物理链路上的单次错误会导致 status_bit_error 多次变为高电平。因此,不应使用该输出来测量误码率(BER)。相反,该输出可用于定性判断链路是否基本无误:当该输出持续为低电平时,接收端已与到达的数据链路同步,并且没有比特错误(即使没有应用数据发送,所有比特错误也能被检测到)。当接收端无法与到达的数据链路同步时(即 status_debug[0] 为高电平),该输出会被保持为高电平。
  • status_rev_polarity:当到达的数据流极性反转时(即物理链路上的所有位都被取反),该输出为高电平。这不是一个错误指示,而是一个提供信息的状态信号。Xillyp2p IP 核对于极性反转不敏感,因此校正极性并没有实际的好处。
  • status_debug:这是一个 32 位的向量,包含一些额外的信息,可用于排查通信链路故障。这些信号的详细说明如下。

如果应用使用的是 MGT 以外的物理层方案,则可能需要对到达比特流的采样位置进行精细调整。status_link_down 和 status_bit_error 可用于此目的,具体将在下面的单独章节中说明。

status_debug 中的比特位

  • 第 0 位:当该输出为高电平时,表示接收端未与物理链路上到达的数据流同步。更准确地说,当该输出为低电平时,表示接收端的内部扰码器已与发送端的扰码器实现同步。从 xillyp2p 核获得有效数据流开始,到该输出变为低电平,通常不超过 223 个比特。如果数据流断开,该输出通常会在约 222 个比特之后变为高电平。如果物理链路的接收端在数据流中额外增加或减少了一个比特(例如由于时钟同步不良导致的意外比特滑动),这将导致短暂的同步丢失,持续时间约为 223 个比特。请注意,数据可能在该输出变为低电平之前就已经到达用户应用程序的 FIFO 中。
  • 第 2 位:当 Xillyp2p IP 核因物理链路上发生比特错误而被请求重传数据时,该位会在一个时钟周期内变为高电平。
  • 第 3 位:当 Xillyp2p IP 核在到达的数据中检测到错误,并因此请求对端重传数据时,该位会在一个时钟周期内变为高电平。

第 2 位和第 3 位表明对比特错误做出了正确的响应。当这些位偶尔变为高电平时,一切仍在正常工作,但由于重传的发生,实测的数据吞吐率可能会有所降低。当物理链路为单向时,这些位永远不会为高电平,因为单向链路不支持重传。

位 [31:4] 包含用于诊断意外情况的高级信息。这些位中的任何一位都不应变为高电平。如果确实出现了高电平,建议检查是否存在导致 FPGA 整体工作异常的因素(如前所述:时序约束不正确、时序约束未能满足、时钟不稳定、供电电压问题等)。这些位的含义与 Xillyp2p 协议的内部细节有关,对最终用户来说没有实际意义。不过,在寻求技术支持时,指出是哪一位变为了高电平可能会有所帮助。

使物理链路正常工作

对于即使是经验最丰富的 FPGA 工程师来说,建立物理链路也是一项具有挑战性的任务。在链路能够实现其基本功能(即近乎无错误地在物理介质上传输一系列并行字)之前,可能需要进行一些反复的尝试和调整。当使用 MGT 时尤其如此。

Xillyp2p 的状态输出端口在此过程中可以提供有用的信息。因此,建议在 FPGA 项目的初次尝试中,就将物理链路连接到 Xillyp2p IP 核。如果从一开始就能正常工作,其优势显而易见;但即使不行,IP 核的诊断信号也能提供一些指导。

即使链路只能部分工作,Xillyp2p 的状态信号仍然有用。尤其是 status_debug[0],它指示扰码器是否已实现同步。这在双向物理链路中尤其有价值,因为有时问题只出现在其中一个方向上。这种情况下,一侧的 status_debug[0] 为高电平,而另一侧为低电平,这立即为需要排查哪个方向的问题提供了线索。

如果两侧的 status_debug[0] 都为低电平,可以通过发送一个固定的字来深入了解情况。例如,如果使用的是并行字宽度为 32 位的 MGT,可以将 32'hff00f055 赋值给 MGT 的数据输入端口(而不是 Xillyp2p IP 核的 out_data),然后在另一端获取 MGT 的数据输出值,据此评估物理链路的工作状况。

为了获取数据,如果板卡上有 PCIe 接口,可以使用 Xillybus IP 核,或者使用任何其他能从 FPGA 内部捕获数据的方法。此外,也可以使用集成逻辑分析仪(ILA)来达到此目的。

观察接收到的并行字,以下是几种典型情况及其可能的原因:

  • 如果收到重复的并行字,请检查该字是否是发送的字经过位旋转后的结果。如果是这种情况,则链路(在所检查的方向上)工作正常,并且 Xillyp2p 的 status_debug[0] 输出应为低电平。例如,发送的字是 32'hff00f055,而接收到的字是 32h'157fc03c,因为后者正是前者向右旋转 10 位的结果。需要注意的是,由于 MGT 的编码功能已被关闭,它不会也不能调整字的对齐边界。
  • 如果并行字是重复且一致的,但字的内容不正确:
    • 尝试将接收到的所有位取反(例如与 32h'ffffffff 异或)。如果结果与发送的字相差一个任意的位旋转,那么这也是正常的,并且 Xillyp2p 的 status_debug[0] 输出应为低电平。请注意,即使位的极性翻转了(当然是所有位都翻转或都没有翻转),Xillyp2p 也能正常工作。
    • 否则,请寻找与发送字之间的相似性。如果接收到的字部分损坏,可能是承载数据流的模拟信号存在问题。例如,接收端的端接电压不正确、端接电阻不正确、该端接的地方没有端接或反之、耦合电容该有却没有或有却不应有等。
  • 如果接收到的数据重复几次,然后又重复另一个字,如此反复:这表明接收端的时钟恢复机制未能与发送端的时钟同步。这可能与时钟本身的问题有关(频率差异过大或时钟抖动过大)。另一种可能性是模拟信号接收不当,原因与上述提到的不正确重复字情况类似。
  • 如果接收到的数据完全是随机的,极有可能根本没有建立连接。例如,引脚分配错误、参考时钟不正确、或者 MGT 电路供电电压不正确/缺失。

上面给出的固定并行字 32'hff00f055 只是一个例子。如果并行字的宽度不同,则需要选择另一个字(而且无论宽度如何,换一个不同的字可能都是有益的)。选择这样的并行字时,需要注意以下三点:

  • 理想情况下,该字应该是直流平衡的,即 0 和 1 的数量相等。否则模拟电路可能无法正常工作。
  • 该字应包含若干从 0 到 1 再回到 0 的快速跳变。在例子中,bits[7:0] 即 0x55 部分就起到了这个作用。这些跳变有助于时钟恢复电路准确锁定。
  • 该字应具有一定的随机性,尤其是当使用了判决反馈均衡器(DFE)时。例子中的 32'hff00f055 在这方面不够好,因为它包含较长的连续 0 和连续 1 序列。这些序列对人类来说更容易处理,但可能会促使均衡器在一定程度上破坏模拟信号。这需要在方便性和“因测试字选择不当而引发并排查问题”的风险之间做出权衡。

上述三点规则并非绝对,尤其是最后一条,即使忽略它,也有可能看到通道正常工作。

利用信号进行时序调整

当物理链路使用 SERDES 实现,或者可能使用从 I/O 端口采样的单比特实现时,应用逻辑通常需要在系统运行时找到最佳的采样时间点。当数据通过 PCB 走线从一块 FPGA 传输到另一块 FPGA,且两块 FPGA 共享同一个参考时钟时,这种情况尤为常见。在这种场景下,比特时钟的频率是确定的,但为了采样到达的比特序列,需要在一个范围内扫描以找到该时钟的最佳相位。逻辑通过调整采样时钟的相位,有时也通过调整输入引脚的延迟来实现这一点。

寻找最佳采样点的逻辑超出了本指南的范围。然而,使用 Xillyp2p IP 核时,无需额外添加逻辑来检查某个采样点是否足够好。相反,整个过程可以将两侧(单向情况下则为一侧)的发送器都连接到 Xillyp2p。接收侧的 IP 核也保持连接,并且它会提供采样点质量的指示。

以下是利用 IP 核的 status_debug[0] 和 status_bit_error 来寻找无错误采样位置的建议步骤:

  • 在设置好相移或输入引脚延迟后,等待对应于物理链路上传输略多于 222 个比特的时间。这是当物理链路不可用时(即使链路质量接近极限时可能会更晚发生),status_debug[0] 变为高电平所需的时间。这一步的目的是确保 status_debug[0] 不是因为尚未检测到链路质量差而保持低电平。一旦 status_debug[0] 变为高电平,就可以继续进行下一步。
  • 如果此时 status_debug[0] 仍然为高电平,则再等待一段对应于物理链路上 224–225 个比特的时间,以便让 Xillyp2p 的接收端有机会锁定。一旦 status_debug[0] 变为低电平,就继续下一步(可能立即继续)。但是,如果该输出端口一直保持高电平,说明采样点确实非常差:Xillyp2p 甚至无法同步其扰码器。
  • 持续监测 status_bit_error 一段时间。如果 status_bit_error 始终保持低电平,说明没有发生比特错误,这是一个采样点良好的标志。这一步需要停留多长时间取决于不同的设计考量。例如,如果这一步运行了对应于 220 个比特的时间且未检测到错误,这大致相当于检查了 10-6 的误码率。但既然前一步已经要求了 225 个比特的时间,那么这一步至少也停留同样数量的比特数是合理的。

常见的做法是在一定范围内扫描各种相移选项,找到一个足够长的、没有检测到错误的位置区间。完成扫描后,使用该区间中间的位置作为正常工作时的采样点。因此,比特错误测试持续多长时间并不是那么重要。

实际上,仅凭 status_debug[0] 为低电平的那些点来找到中间位置可能就足够了,尽管这种方法可能不够精确。

另一种方法是只依赖 status_bit_error,因为当 status_debug[0] 为高电平时,status_bit_error 输出会被强制为高电平。换句话说,如果 Xillyp2p 无法同步其扰码器,所有比特都会被当作错误。然而,仅依赖 status_bit_error 需要在改变比特采样位置后,忽略该信号达 224–225 个比特的时间,以确保接收端有机会完成同步。与那种只要 status_debug[0] 在采样位置改变后略多于 222 个比特时变为低电平就可以立即开始监测 status_bit_error 的方法相比,这种方法会拖慢整个流程。