本页是介绍多吉比特收发器(MGT)的系列文章中的第六篇,也是关于 PMA 的第二页。
简介
在上一页中,我们讨论了借助 PMA 通过物理信道发送比特的问题。不过,这个数据流并不是始终打开的:为了省电,可以关闭 MGT 的很大一部分。这一点在笔记本电脑中实现 SATA、PCIe 或 SuperSpeed USB 时尤其重要。在使用这些协议时,如果没有数据要发送,却让物理链路一直保持活动状态,那是在浪费能源。
因此,MGT 必须能够进入低功耗状态。更重要的是,MGT 还必须能在需要从低功耗状态唤醒时通知对端。PMA 负责生成和检测带外信号(out-of-band signals,OOB),以实现这一目的(以及其他目的)。
OOB 信号由一组简单的电活动模式组成,这些电活动发生在与传输数据流相同的差分导线上。只有在常规数据流关闭之后,才能发送这些 OOB 信号。这些信号最重要的特点是:接收端可以借助非常简单的逻辑来检测它们。这样一来,即使接收 OOB 信号的 MGT 正处于低功耗状态,它也能检测到来信。
MGT 支持的另一个功能是:发送端能够检测自己是否在物理上连接到另一个 MGT(而无需对端 MGT 做任何事情)。这个功能称为接收端检测(receiver detection)。
为了方便起见,这里再次给出前两页中的 MGT 框图:
发送 OOB 信号
带外(Out-Of-Band,OOB)信号通常是一种频率恒定的简单方波信号。这种信号只能替代常规数据流来发送,绝不能与数据流同时发送。
每种协议对 OOB 信号的形态都有不同的要求。FPGA MGT 通常提供输入端口,让应用逻辑可以按照最常用的协议(尤其是 PCIe 和 SATA)来请求发送相应的 OOB 信号。
关于 OOB 信号的名称和要求,各协议之间不尽相同。例如:
- PCIe 协议把它的 OOB 信号称为 Beacon(信标)。其要求可以用一个频率介于 30 kHz 和 500 MHz 之间的方波信号来满足,但协议甚至不要求该信号是周期性的。Beacon 用于从低功耗状态唤醒。
- SATA 协议定义了三种 OOB 信号:COMRESET、COMINIT 和 COMWAKE。该协议对这三种信号的形成方式做了精确规定。COMRESET 由主机端使用,用于复位设备。COMINIT 只由设备发送,用于初始化链路。COMRESET 和 COMINIT 实际上是完全相同的信号,只是含义取决于发送方是哪一个侧。COMWAKE 用于让任一侧把链路从低功耗状态唤醒。
- USB SuperSpeed 协议把它的 OOB 信号称为低频周期信号(Low Frequency Periodic Signaling,LFPS)。这是一种频率介于 10 MHz 和 50 MHz 之间的方波。该信号不仅用于结束低功耗状态,还用于多种其他目的。尤其是,数据流的初始化过程由一组严格定义的 LFPS 信号交换组成。协议定义了若干种 LFPS 信号模式,每种模式含义不同。例如,如果主机连续发送 100 ms 的 LFPS 信号,就是对设备发出的复位要求。
有时,MGT 并不具备生成符合特定协议要求的 OOB 信号的能力。这个问题可以通过打开发送端来发送数据,并向 MGT 送入与所需信号模式相对应的数据流来解决。尤其是,如果关闭 MGT 的编码功能,MGT 的行为就像一个普通 SERDES。这样,就可以借助待发送的数据来任意塑造所需的信号模式。例如,通过发送连续的“0”和“1”序列就能产生方波。这种方案的主要缺点是 MGT 的编码功能被旁路了,因而必须在应用逻辑中另行实现编码功能。
电气空闲
当 MGT 的发送端被关闭或处于低功耗模式时,其输出通常处于电气空闲(electrical idle)状态。这意味着发送端把两条差分输出导线(D+ 和 D-)都连接到地。因此,这两根导线之间的电压为零,而且每根导线相对于地也是零电压。
当 MGT 处于休眠状态时,电气空闲状态正好与发送 OOB 信号相反。或者可以说,一个发送端有三种可能的状态:
- 发送数据。只有处于这种状态时,MGT 才被视为处于加电状态。
- 发送 OOB 信号。
- 电气空闲。
如上所述,OOB 只是偶尔用于把对端从低功耗状态唤醒,或作为链路启动的一部分。因此,MGT 在大多数时间里,要么在发送数据,要么在电气空闲状态下休眠。
检测 OOB 信号
当 MGT 被关闭或处于低功耗状态时,其接收端可能仍然需要检测对端是否发送了 OOB 信号。这一点对于响应恢复正常工作的请求尤其必要。
大多数协议并不会精确地规定 OOB 信号的波形,而是只给出一个可能的范围。因此,接收端无法把到达的信号与某个预期波形进行比较。实际上,只要差分导线上出现任何活动,就可以认为检测到了 OOB 信号。换句话说,如果数据流已经关闭,但差分导线上的电压变化太大,不能把它当成电气空闲,那就说明对端正在发送 OOB 信号。
因此,FPGA MGT 并没有专门用于检测 OOB 信号的输出端口。取而代之的是一个在接收端检测到电气空闲时变为高电平的输出端口。这个端口通常叫作 rx_elecidle 之类。
遗憾的是,MGT 对电气空闲的检测机制并不可靠。尤其是,当对端发送数据流时,接收端电气空闲检测器的行为在各 MGT 之间并不相同:有的 MGT 在这种情况下会检测到电气空闲;有的 MGT 则会明确判断不存在电气空闲;还有的 MGT 会随机地给出检测结果。每个 FPGA 的表现都不一样。
从理论上讲,这不成问题——在数据流仍然活跃时,为什么还需要去检查电气空闲呢?但在实际中,MGT 可能在对端完全没有预料的情况下发送数据。因此,应用逻辑的设计应当能正确处理下面这种情形:预期对端已经关闭,却收到了普通的数据流。
电气空闲检测的另一个问题是它对噪声敏感:理想的电气空闲是两条差分导线电压都为零。由于噪声的影响,接收端可能测到一个足以排除电气空闲的电压。这时,应用逻辑就会面临把它误判为 OOB 信号的风险。
总之,要想可靠地检测 OOB 信号,并没有简单的办法。应用逻辑在设计上必须能够弥补电气空闲检测器的这些不完善之处。
接收端检测
PCIe 协议和 SuperSpeed USB 都要求能够检测链路的对端是否连接着某个东西,而且这种检测不能尝试与对端发起通信。这个功能称为接收端检测(receiver detection)。
SuperSpeed USB 需要这一功能,因为计算机必须知道设备是否在物理上与自己断开了。如果这种断开发生在链路处于低功耗状态时,计算机将无从察觉出了事:反正也不指望在导线上看到任何活动。因此,该协议要求主机每 100 ms 执行一次接收端检测。这样,计算机就能在不浪费能源的情况下确认设备仍然连着。
PCIe 协议要求在尝试与可能连接在某个 PCIe 插槽上的设备建立链路之前,先对该插槽执行接收端检测。由于建立链路需要让 MGT 上电以发送数据(更准确地说,是发送训练序列),因此避免无谓的尝试对节省能源十分重要。
MGT 的发送端执行接收端检测的方法是:在它的两条输出导线(D+ 和 D-)上产生一个短促的电压脉冲。这是一个共模电压脉冲,也就是对两条导线施加相对地相同的电压。如果对端真的有接收端,就会有一个可测量的电流流过接收端的端接电阻。该电流会影响发送端输出端的电压。如果对端没有接收端,这个电流就小到可以忽略。于是,发送端在脉冲开始后不久测量其输出电压,并据此判断对端是否存在接收端。
之所以需要脉冲(而不是单纯的直流电压),是因为发送端和接收端之间存在电容。脉冲刚施加时,脉冲电压落在发送端和接收端的端接电阻上,因而有电流流过。随着电容不断充电,电流会像任何 RC 电路那样逐渐减小。如果电压保持稳定,电流最终会变为零。
需要特别注意的是,只有当接收端两侧各自都有一根端接电阻把 D+ 和 D- 分别连接到地时,接收端检测才能工作。例如,PCIe 协议要求这两根端接电阻都是 50Ω。但如果在 D+ 和 D- 之间接一个 100Ω 电阻,也可以实现相同的差分阻抗,只是不接地。如果采用这种端接方式,除接收端检测之外的所有功能都能正常,唯独接收端检测不行。差别在于:所有其他功能都依赖 D+ 和 D- 之间的差分电压,而接收端检测是靠给两条导线施加相同电压来实现的。假如端接电阻的中间点没有接地,就不会有电流流过,因而也就检测不到接收端。
