Flit模式操作
目录
⇦
Flit模式
一些缩写和翻译
下列内容采用英文原文,只在这里翻译一次,习惯后反而比中文更容易反应过来
- Flit : Flow Control Unit,流控单元
- PAM4 : Pulse Amplitude Modulation 4-levels,脉冲幅度调制 4 级
- FEC : Forward Error Correction,前向纠错
- Sequence Number : 序列号,用来指示是哪一笔 Flit
- Symbol : 符号,用于表明需要传输内容的位置
Flit构成
- Flit 模式将需要传输的内容固定为 256 字节,构成如下
位于 Flit 中的第几个字节 长度 类型 0 – 235 236 TLPs 236 – 241 6 DLP (Data Link Layer Payload, 数据链路层载荷) 242 – 249 8 CRC, CRC0 – CRC7 250 – 255 6 ECC, ECC0[0:1], ECC1[0:1], ECC2[0:1] - Flits 在 8b/10b 编码基本与 Non-Flit 模式相同,下面的列外
- 因为Flit模式会固定放置TLP和DLP,所以包的标志 Symbol 如 STP,SDP,END,EDB不会在使用
- Flits 在 128b/130b 编码基本与 Non-Flit 模式相同,下面的例外:
- 因为 Flit 模式下 TLP 和 DLP 会放在固定的位置,所有用于组帧的 Token 不在使用,比如STP,SDP,EDB,EDB Token
64.0GT/s及以上速率下使用的一些技术
64.0GT/s或者更高速度下的格雷码
- 每条lane上收发通路

- 格雷码编码原理
- 在发送端,输入 Gn(Gn1Gn0)转化为输出 Pn(Pn1Pn0),使用格雷码编码,输入00b,01b,10b,11b会变为00b,01b,11b和10b.输入和输出之间转换的公式为Pn1=Gn1,Pn0=Gn1^Gn0
- 接收端也是相同的逻辑,即 G‘n1 = P’n1和G‘n0=P’n1^P‘n0
- 格雷码编码规则
- 当两个位均已加扰时,仅对2位对齐边界上的加扰位进行格雷编码.TODO(?)
- 数据流中的所有比特都需要加扰和格雷码编码
- TS1/TS2有序集中,只有一些 Symbol 是加扰,这些 Symbol 也需要进行格雷码编码,不加扰的 Symbol 不需要格雷码编码
- 发送方向,所有半加扰TS0有序集 Symbol 选择性地进行格雷编码
- 只有在PAM4编码(64.0GT/s以及更高的速度)中才会使用到格雷码编码.
- 每条lane上格雷码编码是2比特对齐
- ±1的电压电平误差最多如何影响格雷编码的一位
| 电压幅度(Voltage Level) | 导致的电压幅度 | |
|---|---|---|
| +1错误 | -1错误 | |
| 0 | 1 | 0(没有错误) |
| 1 | 2 | 0 |
| 2 | 3 | 1 |
| 3 | 3(没有错误) | 2 |
- 好处
- 降低后续纠错的压力
- 如果没有使用格雷码编码,原始信息就以PAM4电平发送出去,接收到的PAM4电平就是原始信息,如果电平01识别成了电平10,后续纠错(有FEC和CRC)的时候就需要纠错2比特
- 如果使用了格雷码编码,发送的PAM4电平是经过原始信息编码的,接受接受到PAM4电平实际是编码后的信息,经过格雷码解码便可得到原始信息,如果电平01识别成了电平10,在经过格雷码解码后,解码后的原始信息位11,与正确的消息之间只有一比特的错误

64.0GT/s和更高速度下的预编码
- 预编码原理
- 发送端,输入是Pn,输出是Tn,Tn-1代表前一个时间单位预编码器(precoder)的输出值.当使能预编码并且前一个时间单位是一个未加扰的信号时,Tn-1是00b.
- 当使能预编码时,输出Tn会转化为PAM4电压.通道可能会产生错误En(En==00b表示没有错误).
- 接收端,Rn=Tn+En.输出到预编码的逻辑是R‘n(Rn=Tn+en),en是导线上的误差En以及任何内部DFE传播的误差.
- 当预编码使能时,预编码逻辑的输出为P‘n
- 真值表如下


- 预编码好处
- 预编码可以帮助减少突发错误的数量.
- 预编码规则
- 当两个比特都使能加扰和预编码时,只有2比特边界对齐的加扰比特是预编码的
- TS0有序集的所有 Symbol 都不需要与编码.1b/1b下的预编码规则与128b/130b下与编码规则一样.
PAM4 信号
- 特性
- PAM4 代表脉冲幅度调制 4 级 (Pulse Amplitude Modulation 4-levels),在相同的单元间隔 (Unit Interval,UI) 可以编码四种电平( 2 比特表示),这会导致眼图有三个眼睛.
- 四种电平0,1,2,3分配表示 -400mv,-133mv,+133mv 和 +400mv,按照小端比特顺序(little-endian bit order)顺序,他们用格雷码编码表示为 00b,01b,11b 和10b,使用的是小端模式

- 只在 64.0GT/s 或者更高速率下才会使用
- PAM4 信号优点
- PAM4 有助于减少通道损耗,因为它在 64.0 GT/s 数据速率下,与 32.0 GT/s 有相同的奈奎斯特频率(32.0GT/s下的采样频率比64.0GT/s更低).
- PAM4 信号缺点
- 电压电平(眼高或EH)和眼宽(EW)的降低会增加出错的可能性,使用格雷码可以最大限度地减少单元间隔中电压电平的错误.(TODO)
- 使用PAM4编码时,误码率(BER,bit error rate)比低速率(2.5,5.0,8.0,16.0,32.0GT/s)下的误码率要更大,低速率下的误码率为10-12.(就是说PAM4编码更容易误码,低速率下1012之间允许出现一比特的错误,PAM4编码可能在10^6就出现了一比特的错误)
- 在一条或者一些 lane 上,突发(burst)传输可能会出现错误,这也是在预期之内
- 一些保护措施
- 在 Flit 模式下的 Flit 层次上,会采用链路级的重传.
- 在 64.0GT/s 或更高速率下,通过复制一份来保护有序集
- 为了减少突发传输过程中的错误比特数,lane上会采用预编码机制,该机制会用在所有加扰过的比特上
- 电气要求
- 电气参数规定第一比特误码率 (FBER,First Bit Error Rate) 要小于10-6,以确保后续前向纠错后 Flit 错误的可能性要小于3×10-5
前向纠错(FEC)
- 前向纠错机制用于处理数据流中的第一比特高的误码率.
- 前向纠错工作在固定大小字节上,在数据流流发送或者接受TLPs或者DLLPs时会使用Flit
- 低开销(low-overhead)的FEC会有更低的延迟(lantecy).在Flit层次上,用强的CRC来保证高可靠性
64.0GT/s和更高速率下的1b/1b编码
1b/1b编码和收发流程
- 当链路速率在64.0GT/s或更高时,使用Flit模式
- PAM4是2比特边界对齐.一个 Symbol 表示为’S7S6S5S4S3S2S1S0‘,lane上放置的 Symbol 以S1S0开始,以S7S6‘结束

- 链路速率为64.0GT/s下及更高时,使用的Flit模式
- 1b/1b编码下,每条lane上传输的基本单元是一个 Symbol (8比特)
- Flit模式下,无论是数据流还是有序集,所有 Symbol 都采用PAM4信号编码
- 发送方向
- Flit层级上,发射方向首先计算出CRC,然后生成FEC.
- Flit一字节交错的方式放置在每条lane上.此后的操作基于每条lane
- 如果启用加扰(某些内容是不需要加扰的),就执行加绕
- 2比特边界对齐的格雷码编码
- 执行预编码(如果启用并且需要),预编码是2比特对齐的(TODO(翻译))

- 所有 Symbol ,无论是Flit(数据流)还是有序集中加扰的 Symbol 或者任意序列(Compliance序列,fast toggle序列,high swing jetter序列,low swing jetter序列,jitter measurement序列)都会经过格雷码编码和PAM4编码(通过位分配有效地处理了格雷编码和直流平衡)
- 接受方向 – 与发送方向相似
- PAM4电压转化为2比特对齐的数
- 是预编码(如果启用)
- 格雷码解码
- 在单一电平上解扰
- 数据流在所有 lane 上聚合,并经过 FEC 解码和纠错
- CRC 检查,发送事务和数据链路载荷

1b/1b加扰
- 64.0GT/s 下除了 TS0/TS1/TS2 有序集,其它部分的加扰原理与 8.0,16.0 和 32.0GT/s下相同
- 所有的数据流以及部分有序集需要经过加扰
- TS1 和 TS2 有序集
- Symbol 0 和 Symbol 8 不加扰
- Symbol 1 到 Symbol 6 和 Symbol 9 到 Symbol 14 需要加扰
- 如果用于直流平衡, Symbol 7 到 Symbol 15 不需要加扰,否则需要加扰
- TS0 有序集
- Symbol 0 和 Symbol 8 不加扰
- Symbol 1 到 Symbol 6 和 Symbol 9 到 Symbol 14 通过基于非归零码加扰(non-return-to-zero,NRZ)
- 基于非归零码加扰由 8 比特加扰跟着是选择性格雷码编码,以此来确保只有电压幅度为 0 和 3 在发送,具体实现方式是强制偶数位(2i)和奇数位(2i+1)相同(i在0到3之间)
- 如果 Symbol 7 和 Symbol 15 用于直流平衡,则绕过加扰;否则它们分别带有NRZ扰码的 Symbol 1至6 Symbol 9至14的偶校验信息
- TS0中的所有 Symbol 都是基于不归零编码(eg.每一个单元间隔(Unit Interval)只会匹配到电压水平为0或则3,编码为00b或者10b),64.0GT/s速率下,只有TS0有序集是基于非归零设计
64.0GT/s以及更高速度下的有序集块
- 一些通用的规则
- 在发送和接收端,除SKP外的所有有序集(如TS0,TS1,TS2,EIOS,EIEOS和SDS)都是16个字节(Bytes)长.
- 发送端SKP有序集可是40个字节,在接收端可以是24,32,40,48或者56个字节
- 当处理数据流中的有序集时,在获得块对齐后,下面的规则适用于EIEOS,SKPOS和EIEOS
- 在下面的条件下认为是收到了EIEOS
- 在块的第一或者最后8字节中,任意5个或者更多连续收到的字节与EIEOS的结束匹配
- 或者块的 Symbol 0或者 Symbol 8h与EIEOS Symbol 相应的比特 Symbol ,在这个对比的过程中,如果有一比特不符合,允许接收机忽略这种错误.
- 当处于对齐阶段时,如果EIEOS有序集持续时间超过了一个时间单位或者EIEOS有序集的持续时间小于一个时间单位但是后面跟着的是期望的有序集(第一个 Symbol 是有序集的标识),接收机必须切换到块边界.
- 在搜索EIEOS的过程中,在任意对齐的时间单位上,都可以是8比特的边界,接收端在执行格雷码编码,预编码或者解扰前必须先实现位锁定
- 在下面的条件下认为是收到了EIOS
- 块的第一个8字节中有5个或者更多对齐的字节f符合EIOS对应的比特
- 或者块的 Symbol 0或者 Symbol 8符合EIOS对应的比特.当收到EIOS后,lane准备进入电气空闲,而不管块中最后的7个字节
- 在下列情况下,认为收到了SKPOS.
- 块第一个8字节中,超过5个或者更多的字节与 SKP 相符,并且块的 Symbol 0是SKP或者 Symbol 8是SKP或者 Symbol 8是SKP_END.TODO
- 在下面的条件下认为是收到了EIEOS
1b/1b编码下块/Flit层次上的对齐
- 对齐规则
- 1b/1b编码下,块对齐与有序集边界对齐.完成此操作后,链接级别的Flit级对齐将自动发生,该数据流从控制SKP有序集的末端开始,该有序集立即跟着SDS有序集序列
- 只要Flit对齐开始,就会调试Flit的边界.
- 当预期收到有序集并且有序集是控制SKP有序集时,FLIT边界会自动调整以在有序集的结束时开始下一个Flit.
- 在Configuration或者Recovery状态时,当出现EIEOS有序集时,开始块级别上的对齐.
- EIEOS是一个独一无二的序列,在接收到的比特流中,接收机使用该序列来决定有序集边界的开始和结束.
- 接收到EIEOS之后,接收机会进入对齐的三种不同状态:未对齐(Unaligend),对齐(Aligned)和锁定.协议规定了每种状态需要的行为,但是没有规定具体的实现.
对齐过程中的三种状态·
- 未对齐状态(Unaligend Phase)
- 在经过一段时间的电气空闲状态后,接收机会进入该状态.(比如1b/1b编码下链路速度发生了改变或者退出了链路的低功耗状态).
- 在此状态,接收机检测接收到的比特流,并且寻找EIEOS比特序列
- 当检测到的比特流中有EIEOS序列后,接收机调整自己的对齐方式并进入到对齐状态
- 对齐状态(Aligned Phase)
- 接收机在接受到的比特流中检测EIEOS,并在接收到的块中检测SDS(Start of Data Stream)有序集.
- 如果检测到EIEOS比特序列,并且EIEOS的128比特边界跟当前的对齐方式不匹配,并且LTSSM处于Recovery.RcvrLock状态,接收机必须调整自己的对齐方式,以跟当前接受的EIEOS比特流对齐.
- 如果检测到EIEOS比特序列,并且EIEOS跟当前对齐方式不一致,并且LTSSM处于Recovery.RcvrCfg状态时,并且随后接收到的 Symbol 与期望有序集的第一个 Symbol 匹配,接收机必须调整自己的对齐方式,以跟新的EIEOS比特流对齐.
- 如果收到了SDS有序集,接收机会进入到锁定状态.
- 数据流开始于SDS有序集后,Flit开始于SDS有序集序列后的控制SKP有序集
- 在控制SKP有序集的结束,SDS有序集后跟着SKP有序集标志着Flit边界的开始
- 锁定状态
- 在此状态,接收必须调整块或者Flit的对齐方式.SDS有序集序列后跟着控制SKP有序集,随后期望收到数据块,调整块对齐会干扰这些块的处理.
- 如果链路进入到Recovery或者检测到帧错误,导致数据流中止,接收机必须返回未对齐或者对齐状态
- 额外的要求
- 处于对齐阶段时,当收到控制SKP后,如果有必要,接收机必须调整自己的对齐方式
- 处于锁定阶段时,当收到控制SKP后,如果有必要,接收机必须调整自己的块和Flit对齐方式
- LTSSM进入到Recovery后,在接收到EIEOS前,必须忽略所有接收到的TS有序集
- 接收到EIEOS验证了对齐方式,允许接收机处理TS有序集
- 如果接收到的EIEOS让LTSSM从L0跳转到Recovery,在进入Recovery之后,在收到另外的EIEOS之前,接收机即可以处理也可以忽略收到另外EIEOS之前的TS有序集
- 只要停止处理数据流,接收机可以从锁定阶段转跳转到未对齐或者对齐阶段
- 环回发起者,当处于Loopback.Entry,发起者必须有能力调整接收机的块/Flit对齐到接收到的EIEOS比特序列.当处于Loopback.Active时,发起者必须能够发送EIEOS,并且让接收机的对齐方式跟接环回的比特流一致
- 环回追随者,当处于Loopback.Entry,追随者必须有能力调节接收机的块/Flit对齐到接收到的EIEOS比特序列.当处于Loopback.Active时,追随者禁止调节块对齐方式,除非在预定控制SKP有序集边界处.从概念上讲,当追随者开始回环接收到的比特流时,追随会直接进入锁定阶段
Flit模式数据流中有序集的处理
- Flit模式不使用EDS token .取而代之的是,数据流结束的标识是EIOS(在进入低功耗状态前发送)或者EIEOS(进入Recovery之后)
- SKP有序集在数据流中以周期性间隔出现.
- 必要时,必须传输EIOS或EIEOS来代替SKP有序集
- 因此,这三个有序集(EIOS,EIEOS,SKP)被定义为即使有突发错误也不能别名到另一个有序集.
- 64.0GT/s或者更高速率,在数据流中或者数据流结尾,对有序集的处理遵循下面的规则
- 当期望收到有序集时,接收机会在相应位置检查有序集的第一个8字节
- 每条active lane,第一个对齐的8字节中有任意5个或者更多字节与SKP,EIOS或者EIEOS中相应的字节符合,则认为收到了收到的是有效的.否则是无效,并且是帧错误,链路必须进入到Recovery状态
- 如果从第一个8字节推断出了SKPOS,接收器查看每个后续对齐的8字节块并应用以下规则:
- 如果至少有5个对齐的字节匹配SKP_END,或者当前块是SKPOS开始后的第5个8字节的块(如:当前快是40-47字节),SKPOS将在下一个对齐的8字节块之后终止
- 在SKPOS结束时,如果SKPOS接收到SKP_END的5个对齐字节,数据流将恢复
- 如果SKPOS终止时没有收到5个对齐的SKP_END字节,则会发生帧错误.
- 以下任何一种情况都是帧错误,即使在每个活动通道上收到正确的有序集,链路也必须进入恢复状态:
- 在任意两条活动lane上同时接收这些有序集合的任意组合:EIEOS和EIOS或者EIEOS和SKPOS
- 在所有lane上收到长度不等的SKPOS
- 接收EIOS和SKPOS的组合以及满足一下任何一个条件:
- 链路没有使能L0p
- 接收EIOS的lane集合不是连续的
- 接收SKPOS的lane集合不是连续的
- 接收SKPOS的lane数量不是有效的链路宽度(1,2,4或8)
- 如果EIEOS是从任何活动Lane上的前8个字节推断出来的,则接收到EIEOS就结束数据流,链路必须进入Recovery状态
- 如果EIOS是从任何活动lane上的前8个字节推断出来的,链路准备进入已发生协商的低功耗状态(L0p或L1或L2)
- 如果以下所有条件均成立,则数据流在结束时继续在减少的lane上进行
- EIOS是从一些活动通道的前8个字节推断出来的,
- 其余活动lane在lane 1,2,4或8收到SKPOS,
- 链路使能了L0p
Flit模式中的数据流
- 一个flit以字节对齐的方式交叉在链路中的lane上,在64.0 GT/s及以上数据速率下,每个字节对应一个 Symbol .数据块的一个 Symbol 在8.0GT/s,16.0GT/s和32.0GT/s下采用128b/130b编码;在2.5GT/s和5.0GT/s下面采用8b/10b编码
- 由于TLP和DLP在每个flit中都有固定的字节分配,因此端口将相应地调度每种类型的数据包
- 8字节的CRC保护TLP和DLLP部分(不包含ECC字节)
- 6自己的ECC保护整个Flit,包括CRC
- 即使仅在具有64.0GT/s和更高数据速率的PAM4信令的高FBER时才需要ECC保护,但为了保持一致性,它将被部署在较低的数据速率下.
- 在链路重传时,只重传TLPs,不重传DLP.因此,每个flit中的链路层负载(DLP)不会进入发送器的链路层重试缓冲区(LLRB).
- 重传flits中的DLP字段将反映最新的数据链路层有效载荷.因此,DLP可能会丢失,DLLPs的相同复制/聚合机制确保数据链路层消息被传递到链路另一端.
- FEC是一个3路交错的ECC,每个ECC码能够纠正单个字节错误.
- 交错是这样做的,以便在任何Lane中高达16位的突发错误不会影响每个交错的ECC码字中超过一个字节.
- 每个交错的ECC都有不同的颜色.因此,所有的蓝色字节[例如,0,3,6,9,…,231,234,DLP1, DLP4,CRC1, CRC4和CRC7]是ECC Group 0的一部分,由2个蓝色的ECC0[0]和ECC0[1]字节覆盖(它们分别位于12和15通道中flit的最后一个 Symbol 中).



Flit中的字节布局
Flit中的TLP字节
- flit中的TLP字节携带事务层TLP.
- 由于Flit模式不支持STP token ,这些TLP字节必须由事务层填充,而不管它是否有要发送的TLP。
- 根据TLP的长度和位置,它可以跨越多个flits.必须遵守以下规则:
- 当事务层没有TLP可发送时,它发送NOP TLP(1DW).一旦计划发送NOP TLP,则必须将NOP TLP调度到Flit或Flit边界内的下一个4DW对齐边界,以较早者为准。
- NOP TLPs不消耗任何信用(credits)。
- Flit模式下的TLP在预定位置上有信息,可以确定TLP的长度,包括使用TLP前缀的情况
- 以下规则适用于每个Flit半段中的非NOP TLPs[即Flit的前32DW(字节0到127)或Flit的最后27个DWj(字节128到235):
- 不超过8个TLP,包括部分TLP。允许接收方检查此规则。如果检查,这将被记录为接收端口的数据链路协议错误(Data Link Protocol Error)
- 如果Flit结束时的一个TLP通过Flit_Status被毒害或无效扩展到后续的Flits,那么每个Flits也必须通过Flit_Status被毒害或无效,以便在TLP结束的Flit中设置中毒或无效的Flit_Status。
- 如果Flit末尾的TLP通过Flit_Status延伸到后续Flit 而中毒或无效,则每个Flit也必须通过Flit_Status中毒或无效,以便在TLP结束的Flit中设置中毒或无效的 Flit_Status. TODO(翻译问题). 接收方只被允许查看 TLP 结束处的 Flit 中的有害位。
- 如果Flit有效,则接收器将忽略通过下面描述的 DLP 字节中的 Flit_Status 字段无效的 TLP,但必须释放信用。
- 通过下面描述的DLP字节中的Flit_Status字段获得 EDB’ed 或有毒(Poisoned)的TLP在Flit结束时必须仅由NOP TLP继承。
- x16 flit模式TLP放置的例子
- flit开始于TLP19剩下2DW的连接处(第三个DW的头+1DW的数据)
- TLP20(4DW头+1DW数据)立刻在lane8开始,结束于lane11
- 因为发射机没有东西需要发送,发射机就发送NOP直到4DW边界对齐,即在lane12-lane15发送NOP
- TLP22和23是定期发送没有插入NOP
- 在TLP23之后,发射机没有需要发送的,就发送7个NOP,对齐到4DW边界,直到TLP24准备好,TLP24持续到flit中TLP部分的边界
- 在flit中,之后我们有6字节的DLP, 8字节的CRC覆盖236字节的TLP和6字节的DLP
- 然后我们有3组交错的ECC,每个2字节,覆盖整个256B的flit。

Flit 中的 DLP 字节
- 在每个 Flit 中,分配 6 个字节来承载数据链路层数据包(DLLP)所携带的信息。
- 虽然 DLP 字节的设计主要是为了重用 DLLP 机制和格式,但已经进行了一些优化,以便有效地携带 Ack/Nak flit 以及优化的信用释放(Optimized_Update_FC,定义如下)或传统的DLLP TODO(翻译问题)
- 在 DLP 中添加了一种编码,以便在DLP的一个32位有效载荷内为PRH、PRD和NPRH提供Update_FC Credit
- Flit 类型定义如下,以及他们期望的用途
Flit类型不是Flit中的某个字段,而是根据Flit的组成来判断的表格4-16 Flit类型Flit类型 TLP字节 DLP第0,1字节 DLP第2到5个字节 IDLE Flit 236个字节都是NOP TLPs 全0(包括Flit Sequence Number) NOP2 DLLP NOP Flit 236个字节都是NOP TLPs Flit Usage字段为00b;
如果重传命令(Replay Command)为00b,则Flit Sequence Number=NEXT_TX_FLIT_SEQ_NUM-1;
其它字段为任意合法的编码任何合法的编码 Payload Flit 236字节中至少有一个不是NOP TLP Flit Usage字段为01b;
如果重传命令为00b,则Flit Sequence Number字段=NEXT_TX_FLIT_SEQ_NUM-1;
其它字段为任意合法的编码任意合法的编码 - Flit中DLP的分布


| 字段 | 位置 | 编码 |
|---|---|---|
| Flit Usage (Flit用途) |
DLP0 的bit[7:6] | 00b : IDLE Flit 或者 NOP Flit; 01b : Palyload Flit; 其它 : 保留 |
| Prior Flit was Payload (前一个 Flit 类型是 Payload Flit) |
DLP0 的bit[5] | 0b : 前一个 Flit 是 NOP Flit 或者是 IDLE Flit; 1b : 前一个 Flit 是 Payload Flit |
| Type of DLLP Payload (Flit 载荷中 DLLP 的类型) |
DLP0 的bit[4] | 0b : DLP的byte 2,3,4,5是DLLP载荷 1b : DLP的byte 2,3,4,5是Optimized_Update_FC 或者是 Flit Marker |
| Replay Command[1:0] 重传命令[1:0] |
DLP0的bit[3:2] | 00b : 传输的Flit中,Flit中包含的Flit Sequence Number是显式 Flit 序列; 01b : 来自接收器的 Flit Sequence Number确认(Ack).包含的 Flit Sequence Number表示接收到的最后一个有效 Flit 的 Flit Sequence Number. 10b : Nak 请求重播所有未确认的 Flit.包含的 Flit Sequence Number表示接收到的最后一个有效 Flit 的 Flit Sequence Number. 11b : Nak请求重播单个Flit(Flit Sequence Number+1),包含的Flit Sequence Number表示接收到的最后一个有效Flit的Flit Sequence Number |
| Sequence Number Flit Sequence Number |
DLP0 的bit[1:0] DLP1的bit[7:0] |
Flit 中的10比特的Sequence Number,DLP0[1:0]是Flit Sequence Number的[9:8],DLP1[7:0] 是 Flit Sequence Number的[7:0] |
| DLLP载荷 或 Optimized_Update_FC 或 Flit_Marker |
DLP2的bit[31:24] DLP3 的bit[23:16] DLP4 的bit[15:8] DLP5 的 bit[7:0] |
如果 DLLP 载荷类型为0b,则为 DLLP Payload,常规的 DLLP 载荷 如果 DLLP 载荷类型为 1 且bit[31]=0b,则表示为 Optimized_Update_FC 如果 DLLP 载荷类型为 1 且bit[31]=1b,则表示为 Flit_Marker |
- Optimized_Update_FC
表格4-18 Optimized_Update_FC比特位 描述 31 Optimized_Update_FC指示符,必须是0 30:28 Shared Non-Posted HdrFc,在此VC上共享的信用 19:12 Shared Posted HdrFc,在此VC上共享的信用 11:0 Shared Posted DataFC,在此VC上共享的信用 - Flit_Marker
表格4-19 Flit_Marker比特位 描述 31 Flit_Marker标识符,必须为1 30:29 Flit_Status,表明Flit中最后一个TLP是否有效.
00b:没有特殊的信息,此Flit末尾的TLPs没有无效(Nullified)或者中毒(Poisoned),在此 Flit 中开始并在后续 Flit 中结束的 TLP 会在该 Flit 中进行标记.
01b:最后一个TLP是无效的,在当前Flit中,最后一个TLP结束是无效的,该机制取代了Non-Flit模式下组帧的EDB机制.
10b:最后一个TLP中毒,在当前Flit中最后一个TLP结束中毒,该机制与事务层EP位机制有关.
11b:保留28 PTM Message Contained in this Flit,在Flit模式中,Precision Time Management消息的时间戳是在Flit级别而不是在TLP级别测量的.该位表示该Flit包含非无效PTM消息的最后一个 Symbol .
无效的PTM消息不设置此位.
不允许使用有毒的PTM消息. - 不同类型的Flit有相同的CRC和FEC机制
- 基于携带的TLP和DLP字节,区分成不同的Flit,便于参考
- IDLE Flit
- 使用的Sequence Number为0,重传命令为00b
- 在128b/130b编码和1b/1b编码下,先发送SDSOS序列,然后发送SKPOS,在发送IDLE Flits
- 在8b/10b编码下,在TS2OS结束后(或者SKPOS,该SKPOS必须是发送完最后一个TS2OS后的SKPOS,取决于SKP的插入间隔)发送IDLE Flits
- 在8b/10b编码下,区分是IDLE Flit还是有序集的标准:在SKPOS的最后一个字符后面是否有COM,如果有COM则是有序集
- IDLE Flits必须持续发送,直到发送的Flit不在要求是IDLE Flit
- 如果在DLP 2,3,4,5中没有DLLP需要发送,允许在所有FC/VC中有无限信用的设备发送NOP DLLP
- 有效的Flit需要在执行完FEC纠正后通过CRC检查,并且FEC中的ECC组都没有报告不可纠正的错误(由ECC),并且Flit Usage以及Flit Status字段没有保留的编码
- FEC不可纠正错误是在FEC纠正后由CRC检测到的Flit错误,或FEC中ECC组报告的“不可纠正错误”,可能导致NAK和重播。
- 一个有效的非IDLE Flit要么是一个NOP Flit,要么是一个Payload Flit
- 当链路处于L0时,在第一个有效的非IDLE Flit之后的所有后续Flits都是非IDLE Flit。
- Optimized_Update_FC用于传输性能关键的NPRH、PRH和PRD积分(4信用).
- 为了调试和便于调试工具(如逻辑分析仪)使用,设备每10 μs发送至少一个DLLP,每个VC发送一个Update_FC DLLP,并带有缩放后的信用信息(scaled credit information).
- 强烈建议,只要在相应的VC中有要释放的信用,就可以在Optimized_Update_FC中以有限的非0信用循环通过VC。
- 允许接收机检查下列Flit错误,如果检查了,Flit错误会记录在相应端口的Data Link Protocol Error寄存器
- Flit Usage的保留值
- 在Flit_Marker中Flit_Status保留的编码
- 无效的Sequence Number
- 违反了TLP组报规则
Flit中的CRC字节
- CRC计算
- CRC产生采用多项式,g(x)=(x+α)(x+α2)…(x+α8),其中α是8次原多项式的根:x8+x5+x3+x+1.即多项式等于0时x的值。在GF(28)有限域上,其值为1
- 展开后g(x) = x8+α172x7+α116x6+α186x5+α172x5+α195x3+α134x2+α199x+α36
- 下图中,g0表示0次项的系数,…,g7表示x7项的次数, GF(28)表示有28=256个元素的有限域(GF:Global Field,伽罗瓦域)

- CRC检查规则
- 在接收端,生成的CRC字节与接收的CRC字节进行比较(在FEC解码/纠正之后),任何不匹配都表示不可纠正的错误。
- 任何不匹配都会导致Flit被声明为无效,并在需要时请求重传。
TODO
Flit中的EEC字节
- FEC代码是3路交错的,其中ECC Symbol 是在GF(28)上定义的。
- 3个连续的字节属于三个不同的ECC组
- 因此,导线中长度≤16的任何突发都保证不会影响一个码字中的多个 Symbol ,从而能够纠正单字节错误,以尽量减少FEC延迟。
- 假设α是x8+x4+x3+x2+1的根(表示为0x1D-0001 1101),因此α8=α4+α3+α2+1可以表示为
- 因此,每个8位 Symbol (在GF(28)上)可以表示为幂的多项式(1到254)或8次多项式。
TODO
Flit Sequence Number和重传机制
协议定义的一些项
| 名称 | 描述 |
|---|---|
| Explicit Sequence Number Flit | 显式Sequence Number的 Flit ,Payload Flit 或者 NOP Flit 中重传命令为 00b, 显式就是该笔 Flit 的 sequence number 是确定的,能直接知道是第几笔 Flit,就是 sequence number 的值; 对应隐式就是 Flit 的 sequence number 不是确定的,没法直接知道该笔 Flit 是第几笔, 该 Flit 的 sequence number 是用于回应对面的,如 Ack Flit 或者 Nak Flit |
| Ack Flit | Flit 中 Replay Command 为 01b, 此 Flit 中的 sequence number 为确定收到了对面发送的哪一笔 Flit ig. 如果是 Ack Flit, 且 sequence number 为 3,本端将该 Flit 发送给对面,对面就知道本端已经收到对面发送 sequence nubmer 为 3 的这一笔 Flit |
| Standard Nak Flit | Flit 中 Replay Command 为 10b |
| Selective Nak Flit | Flit 中 Replay Command 为 11b |
| Nak Flit | Flit 中 Replay Command 为 10b 或者 11b |
| Standard Nak | Nak, 请求重传所有未确认 Flit, Standard Nak 跟 Non-Flit 模式的重传类似,需要重传所有未被 Ack 的 Flit |
| Selective Nak | Nak, 请求重传特定 Flit, selective nak 不需要重传所有,只用重传该 Flit 中 sequence number 的那一笔 |
| Standard Replay | 重传 TX retry buffer 中所有未确认的 Flit |
| Selective Replay | 重传 TX retry buffer 中特定的 Flit |
| TX Retry Buffer | 存储传输 Flit 信息的 buffer,直到 Flit 被链路对端确认为止 |
| RX Retry Buffer | 存储接收到 Flit 信息的 buffer,直到Flit被接收方使用 |
| Nak Ignore Window | 在这个时间窗口内,对于特定的 Flit sequence number, 忽略接收到的 Nak Flit 当 Explicit Sequence Number Flit 要发送,并且 sequence number 为 NAK_IGNORE_FLIT_SEQ_NUM+1 并且 NAK_IGNORE_FLIT_SEQ_NUM 不为 0 时,启动 Nak Ignore Window |
隐式 sequence number 的 Flit 表示 Payload Flit 或者 Nop Flit 中的 replay command 不是 00b, 因为当 replay command 不为 00 时,Flit 中的 sequence number 字段表示是对该笔 sequence number 的 flit 进行响应,是告知对方本段已经确认或者拒绝了该 sequence nubmer 的 Flit。
ig. 当本段发送了一个 Payload Flit, 其 Replay Command 为 01b,sequence number 为10,表示告知对方本段已经收到了 sequence number 为 10 的 Flit,而不表示本段发送出来的 sequence nubmer 为 10。
Nak Ignore Windows 用于两种情况:
- 由于收到了 Nak Flit 后,重传已经开始了, 这时会忽略掉接收到的 NAK Flit
- 在收到一笔 Nak (其 Flit Sequence Number = NEXT_TX_FLIT_SEQ_NUM – 1 )后,需要发送一笔显式 Sequence Number 的 Flit,且 Flit Sequence Number 等于 NEXT_TX_FLIT_SEQ_NUM,此时会忽略到接收到的 Nak Flit
一些标志和计数器
这些标志和寄存器从名称也能大概猜测其含义
| 标志或计数器 | 含义 | 行为规则 |
|---|---|---|
| NEXT_TX_FLIT_SEQ_NUM |
|
|
| TX_ACKNAK_FLIT_SEQ_NUM |
|
|
| CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS |
|
|
| CONSECUTIVE_TX_NAK_FLITS |
|
|
| NEXT_EXPECTED_RX_FLIT_SEQ_NUM |
|
见 “Ack, Nak, and Discard Rules” |
| IMPLICIT_RX_FLIT_SEQ_NUM |
|
|
| ACKD_FLIT_SEQ_NUM |
|
|
| NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD |
|
见 “IMPLICIT_RX_FLIT_SEQ_NUM Rules” |
| REPLAY_SCHEDULED |
|
|
| REPLAY_SCHEDULED_TYPE |
|
|
| REPLAY_IN_PROGRESS |
|
|
| TX_REPLAY_FLIT_SEQ_NUM |
|
|
| FLIT_REPLAY_NUM |
|
|
| REPLAY_TIMEOUT_FLIT_COUNT |
|
|
| NAK_SCHEDULED |
|
|
| NAK_SCHEDULED_TYPE |
|
|
| NAK_WITHDRAWAL_ALLOWED |
|
见 “Ack, Nak, and Discard Rules” |
| NAK_IGNORE_FLIT_SEQ_NUM |
|
|
| NEXT_RX_FLIT_SEQ_NUM_TO_STORE |
|
见 “Ack, Nak, and Discard Rules” |
| RX_RETRY_BUFFER_OVERFLOW |
|
见 “Ack, Nak, and Discard Rules” |
| RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM |
|
见 “Ack, Nak, and Discard Rules” |
| MAX_UNACKNOWLEDGET_FLITS |
|
|
通用的规则
Flit Sequence Numbr Rules (Flit Sequence Number规则)
- 对 Payload Flit 来讲,Flit 有效的 sequence number 为 1-1023。如果是 Explicit Sequence Number Flit,则 Flit 中的 sequence number 就是当前 Flit 的 sequence number。如果是 Ack 或者 Nak Flit, Flit 中的 sequence number 是需要 ack 或者 nak 的。
- Flit sequence number 等于 0 只在IDLE Flit中使用
- NOP Flits 不消耗 Flit sequence number ( 即发送NOP Flit,Flit sequence number 不会增加)
- NOP Flit 如果也是 Explicit Sequence Number Flit ,需要将 Flit Sequence Number 设置为 NEXT_TX_FLIT_SEQ_NUM – 1。
- 如果没有 Payload Flits 需要发送,Flit sequence number 设置为1023
- 如果 REPLAY_IN_PROCESS 为1, 强烈建议发射机将 Sequence Number 设置为 Explicit Sequence Number, 该 sequence number 为最近发送的一个Payload Flit
- 所有 Flit Sequence Number 计数器将会从 1023 溢出到 1。
- 即使被 SKPOS 分开,两个发送或接收的 Flits 也被认为是连续的.
- Nak Ignore Window 应该取下面较小的值:
- 链路测量 Ack/Nak 延迟+ 最大大小的 SKP 有序集+ 2 Flits
- 300ns 或者下表较小的值
| 2.5 GT/s | 5.0 GT/s | 8.0 GT/s | 16.0 GT/s | 32.0 GT/s | 64.0 GT/s | 128.0 GT/s |
|---|---|---|---|---|---|---|
| 2250 ns | 1250 ns | 750 ns | 450 ns | 350 ns | 300 ns | 250 ns |
- 强烈建议在接收端引脚收到 Flit 后的规定时间内,针对该 Flit 发送 Ack 或 Nak。除非发送端正在发送有序集(Ordered Set),否则应遵守以下时间要求。测量时间段是从接收端引脚上所接收 Flit 的第一个比特开始,至发送端引脚上相应的 Ack Flit 或 Nak Flit 的第一个比特为止。
| 2.5 GT/s | 5.0 GT/s | 8.0 GT/s | 16.0 GT/s | 32.0 GT/s | 64.0 GT/s | 128.0 GT/s | |
|---|---|---|---|---|---|---|---|
| x16 | 112 ns | 80 ns | 64 ns | 56 ns | 52 ns | 50 ns | 49 ns |
| x8 | 176 ns | 112 ns | 80 ns | 64 ns | 56 ns | 52 ns | 50 ns |
| x4 | 304 ns | 176 ns | 112 ns | 80 ns | 64 ns | 56 ns | 52 ns |
| x2 | 560 ns | 304 ns | 176 ns | 112 ns | 80 ns | 64 ns | 56 ns |
| x1 | 1072 ns | 560 ns | 304 ns | 176 ns | 112 ns | 80 ns | 64 ns |
发射机规则
- 发射机必须将传输 Payload Flits 的以下信息存储在 Tx Retry Buffer 中:
- 与 NOP TLPs 关联的 TLP字节
- Flit_status (见上文)
- Flit sequence number
MAX_UNACKNOWLEDGET_FLITS Outstanding:
- 如果 NEXT_TX_FLIT_SEQ_NUM – ACKD_FLIT_SEQ_NUM 除以 1023 的余数大于 MAX_UNACKNOWLEDGET_FLITS
- 发送端不能接受来自事务层的任何新的 TLPs。
- 该条说明最多只能允许 MAX_UNACKNOWLEDGET_FLITS 个 Flit 没有被 Ack,如果超过这个数量的 Flit 没有被 Ack,那么认为可能存在问题,不能在继续发送 TLP 了
- 如果 REPLAY_SCHEDULED 和 REPLAY_IN_PROGRESS 都为 0,则发射机必须发送一个 NOP Flit
- 发送端不能接受来自事务层的任何新的 TLPs。
REPLAY_IN_PROGRESS Rules:
- 见前文标志和计数器 REPLAY_IN_PROCESS
CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS规则
- 当传输_Explicit Sequence Number Flit_时:
- CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 是增加的
- 当传输非_Explicit Sequence Number Flit_时:
- CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 置0b
- 以及 Replay Schedule Rule 0
REPLAY_TIMEOUT_FLIT_COUNT Rules:
- 见前文标志和计数器 REPLAY_TIMEOUT_FLIT_COUNT
NEXT_TX_FLIT_SEQ_NUM
- 发射机发送的 Flit 是来自 TX Retry Buffer,且该 Flit 是 Payload Flit,且没有重传,则 NEXT_TX_FLIT_SEQ_NUM 是增加的
- 在发送下面的Flit时,NEXT_TX_FLIT_SEQ_NUM 不改变
- IDLE Flit
- NOP Flit
- Selective Replay Payload Flit
- 来自 TX Retry Buffer 中的 Flit 已经重传
接收机规则
- 如果接收机已经计划接受 Selective Nak Flit,它必须将下列信息存放在 RX Retry Buffer 中:
- 非 NOP TLP
- 后续 Flit 的 Flit Sequence Number。
如果收到了 Nak,表明后续的 Flit 存在问题,将这些 Flit 的有效信息存放在 RX Retry Buffer 中
IMPLICIT_RX_FLIT_SEQ_NUM Rules
- IMPLICIT_RX_FLIT_SEQ_NUM 在执行 “Ack, Nak, and Discard Rules” 之前必须更新
- IMPLICIT_RX_FLIT_SEQ_NUM在下面几种情况保持不变:
- 收到一笔有效的 IDLE Flit
- 收到 Flit Sequence Number 为 0 的_Explicit Sequence Number Flit_
- NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD 为 0,并且满足下面其一:
- 收到了一个无效的Flit
- 收到一个有效的非_Explicit Sequence Number Flit_
- 收到一个有效的 NOP Flit,并且Sequence number 是隐式的,且满足下列之一:
- NAK_WITHDRAWAL_ALLOWED 是 0b
- NAK_WITHDRAWAL_ALLOWED 是 1b 并且 Prior Flit was Payload 字段为 1b
- 下面所有条件都为真:
- 收到有效的 Payload Flit,且是隐式的 Flit sequence number
- NAK_WITHDRAWAL_ALLOWED 是 1b (收到了无效的 NOP Flit)
- Prior Flit was Payload 是 0b
- 当下列条件为真时,IMPLICIT_RX_FLIT_SEQ_NUM 是增加的:
- NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD 是 1b (收到了非 IDLE Explicit Sequence Number Flit)
- 以下任意一种情况为真
- 收到有效的 Payload Flit,有非显式的 Flit Sequence Number,并且 NAK_WITHDRAWAL_ALLOWED 是 0b
- 收到有效的 Payload Flit,有非显式的 Flit sequence number ,并且 Prior Flit was Payload 是 1b,NAK_WITHDRAWAL_ALLOWED 是 1b
- 收到了无效的Flit
- 如果满足下面条件,IMPLICIT_RX_FLIT_SEQ_NUM 设置为 N
- 收到了有效的非 IDLE 显式Sequence Number的 Flit,且 Flit Sequence Number 为 N, N 不等于 0
- 如果满足下面所有条件,IMPLICIT_RX_FLIT_SEQ_NUM 减少
- 收到有效的 NOP Flit,具有非显式的 Flit Sequence Number
- NAK_WITHDRAWAL_ALLOWED 是 1b
- Prior Flit was Payload 字段是 0b
IDLE Flit Handshake Phase (IDLE Flit 握手阶段)
通用的规则
- 当 LTSSM 进入
Configuration.Idle或者Recovery.Idle时,Port 进入 IDLE Flit Handshake Phase
发射机规则
- 发射机必须按照 LTSSM 要求的规则发送 IDLE Flits
- 当 LTSSM 进入 L0 时,发射机进入到 Sequence Number Handshake Phase (Sequence Number握手阶段)
接收机规则
- 收到的所有 Flits 都会被丢弃
- 当收到两个连续有效的 IDLE Flits 后,接收机进入 Sequence Number Handshake Phase
Sequence Number Handshake Phase (Sequence Number握手阶段)
通用规则
- 如果数据链路控制和管理状态机分别处于
DL_Feature或DL_Init状态,在此阶段,允许设备进行数据链路特征交换和流量控制初始化, - 当下面两个条件都为真时,端口进入 Normal Flit Exchange Phase (正常 Flit 交换阶段)
- 在接收到一个或者更多显式 Sequence Number Flits (Flit Sequence Number 不为0)后,端口发送了 3 个或者更多 ACK Flits (Flit Sequence Number不为0)
- 端口发送了 9 个或者更多显式 Sequence Number的 Flits (Flit Sequence Number 不为 0 )
- 如果在此阶段,Port 在 1b/1b 编码下发送发送了 512 个 Flits 或者在 8b/10b 或者128b/130b 编码下发送了 256 个Flits,Port 必须进入 Recovery
发射机规则
- Flit 重传命令规则
- 在此状态,发射机交替发送三个连续的 Explicit Sequence Number Flit 和一个 Ack Flit和一个 Nak Flit,按照下列条件按照优先级排序
- 如果 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 小于 3,发射机必须发送一个 Explicit Sequence Number Flit
- 如果 NAK_SCHEDULED 是 1b,NAK_SCHEDULED_TYPE 是 STANDARD_NAK 且发送 Explicit Sequence Number Flit 的条件不满足,就发送 Standard Nak Flit
- 如果 NAK_SCHEDULED 是 1b,NAK_SCHEDULED_TYPE 是 SELECTIVE_NAK 且发送 Explicit Sequence Number Flit 的条件不满足,就发送 Selective Nak Flit
- 如果发送 Explicit Sequence Number Flit 条件不满足,发送 Standard Nak Flit 的条件不满足且发送 Selective Nak Flit 的条件不满足就必须发送 Ack Flit
- 如果由于 Replay Schedule Rule 0 导致 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 计数被复位,发射机可能会发高达 6 个连续的 Explicit Sequence Number Flits
- 在此状态,发射机交替发送三个连续的 Explicit Sequence Number Flit 和一个 Ack Flit和一个 Nak Flit,按照下列条件按照优先级排序
- Flit 重传发射机规则
- 当发送 Explicit Sequence Number Flit 且 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 是 0b 时,发射机必须从 TX 重传缓冲区中重传 Flits
- 当发送 Explicit Sequence Number Flit 时,如果重传的 Flit 来自 TX 重传缓冲区,则它必须使用 TX 重传缓冲区中的 Sequence Number
- 其它规则
- Flit Sequence Number规则
- 当发送 Ack Flit 或者 Nak flit 且 Flit sequence number 为非 0 时,Flit sequence number 设置为 TX_ACKNAK_FLIT_SEQ_NUM
- 当发送 Explicit Sequence Number Flit 时,NOP Flit 必须设置 Flit sequence number 为 NEXT_TX_FLIT_SEQ_NUM – 1
- 重传的 Payload Flit 必须将 Flit sequence 设置为在TX重传缓冲区存储的值
- 非重传的 Payload Flit 必须将 Flit sequence number 设置为 NEXT_TX_FLIT_SEQ_NUM
接收机规则
- Ack 和 Nak 处理规则
- Ack 和 Nak 调度规则
- 重传调度规则
Normal Flit Exchange Phase (正常 Flit 交换阶段)
发射机规则
- 当处于该状态时,根据 Flit 重传命令定义,只会发送 Explicit Sequence Number Flits
- 如果在此阶段发送了 Nak Flit
- 最少必须发送三个连续的 Nak Flits,除非下列任何一项为真:
- 由于 Replay Schedule Rule 0 将 CONSECUTIVE_TX_NAK_FLITS 复位
- 由于退出 L0 打断了 Flits 的传输
- 最少必须发送三个连续的 Nak Flits,除非下列任何一项为真:
- 如果在此阶段发送了 Explicit Sequence Number Flits:
- 必须连续发送三个 Explicit Sequence Number Flits,除非下面任意一项为真:
- 由于 Replay Schedule Rule 0 将 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS复位
- 由于退出 L0 打断了 Flits 的传输
- 必须连续发送三个 Explicit Sequence Number Flits,除非下面任意一项为真:
Flit 重传命令规则
- 按照下列优先级
- 满足下列所有条件,则发射机必须发送 Explicit Sequence Number Flit
- 满足下列任意一条:
- REPLAY_SCHEDULED是1b
- REPLAY_IN_PROGRESS是1b
- CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS大于0
- REPLAY_SCHEDULED是0b且REPLAY_IN_PROGRESS是0b且NAK_IGNORE_FLIT_SEQ_NUM不为00h
- CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS小于3
- 下列任意一个条件为真
- CONSECUTIVE_TX_NAK_FLITS等于0
- CONSECUTIVE_TX_NAK_FLITS大于2
- 满足下列任意一条:
- 如果 NAK_SCHEDULED 是 1b 且 NAK_SCHEDULED_TYPE 是 STANDARD_NAK 且不满足发送 Explicit Sequence Number Flit 的条件,就会发送 Standard NAK Flit
- 如果 NAK_SCHEDULED 是 1b 且 NAK_SCHEDULED_TYPE 是 SELECTIVE_NAK 且不满发送 Explicit Sequence Number Flit 和 Standard Nak Flit 的要求,发射机就会发送Selective Nak Flit
- 如果不满足发送 Explicit Sequence Number Flit,Standard Nak Flit 和 Selective Nak Flit 的要求,就会发送 Ack Flit
- 如果由于 Replay Schedule Rule 0 导致 CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS 计数被复位,则发射机发送的 Explicit Sequence Number Flits 可能高达 6 个
- 满足下列所有条件,则发射机必须发送 Explicit Sequence Number Flit
Flit Sequence Number规则
- 当传输 Ack Flit 或者 Nak Flit 时,Flit sequence number 设置为 TX_ACKNAK_FLIT_SEQ_NUM
- 当传输 Explicit Sequence Number Flit 时
- NOP Flit 必须设置 Flit Sequence Number 为 Next_TX_FLIT_SEQ_NUM – 1
- replay Payload Flit 必须设置 Flit Sequence Number 的值为 TX Retry Bufer 中存储的值
- 非 replay Payload Flit 必须设置Flit Sequence Number 为 NEXT_TX_FLIT_SEQ_NUM
接收机规则
- Ack 和 Nak 处理规则
- Ack 和 Nak 调度规则
- 重传调度规则
接受Ack和Nak处理过程
- 如果收到 Flit Sequence Number 为 0 的 AcK 或者 Nak,必须忽略
- 在接收到的 Ack Flit 或者 Nak Flit 中,处理有效的 Flit Sequence Number
- 如果下面所有都为真:
- 收到的 Ack Flit 或者 Nak Flit 是有效的,Flit Sequence Number 为 N
- N不同时满足以下两个条件:
- ((NEXT_TX_FLIT_SEQ_NUM-1)-N)模1023的值小于等于MAX_UNACKNOWLEDGET_FLITS
- (N-ACKD_FLIT_SEQ_NUM)模1023的值小于等于MAX_UNACKNOWLEDGET_FLITS
- 如果上述条件无法满足
- 则忽略接到的Ack和Nak
- 在相应的接受端口记录数据链路协议错误
- 如果下面所有都为真:
- 如果接收机接收到有效的 Ack Flit 或者 Nak Flit,且 Flit Sequence Number为N,它必须:
- 清除存储在 TX重传缓冲区的所有 Flits,这些 Flits的 Flit Sequence Number要小于等于N
- 如果(N-ACKD_FLIT_SEQ_NUM)模1023的值大于0,则清掉FLIT_REPLAY_NUM,并将ACKD_FLIT_SEQ_NUM设置为N
- 如果接收到的 Flit 是 Ack Flit,则将NAK_IGNORE_FLIT_SEQ_NUM 清零(000h),如果 (N-TX_REPLAY_FLIT_SEQ_NUM) 模 1023 的值小于 MAX_UNACKNOWLEDGET_FLITS,则设置 TX_REPLAY_FLIT_SEQ_NUM 为000h
- 如果接收到的 Flit 是 Nak Flit
- 如果 N=NEXT_TX_FLIT_SEQ_NUM-1,则NAK_IGNORE_FLIT_SEQ_NUM 设置为 N
- 如果收到的有效的 Nak Flit,其 Flit Sequence Number为 N,N 不等于 NAK_IGNORE_FLIT_SEQ_NUM 且 N 不等于 NEXT_TX_FLIT_SEQ_NUM-1,则将 NAK_IGNORE_FLIT_SEQ_NUM 清零(000h)
- 必要时需要重传.TODO
Ack,Nak和丢弃的规则
# python 伪代码
# 无效Flit处理
if "接收到无效的Flit":
if NAK_SCHEDULED == 1:
if NAK_SCHEDULED_TYPE == STANDARD_NAK:
"采用规则Flit Discard 1"
else:
"采用规则Nak Schedule 6"
else: # NAK_SCHEDULED == 0
if NAK_WITHDRAWAL_ALLOWED == 1:
"采用规则Nak Schedule 1"
else:
"采用规则Nak Schedule 0"
# 有效的Flit处理
if "接收到有效的Flit":
if "处于正常Flit交换阶段" and "Explicit Sequence Number Flit" and "Flit Sequence Number"==0:
"采用规则Flit Discard 2"
else if NAK_WITHDRAWAL_ALLOWED == 1:
NAK_WITHDRAWAL_ALLOWED = 0
if "Prior Flit was Payload字段" == 1:
if "是NOP Flit":
# 发送Standard或者Selective Nak计划
NAK_SCHEDULED = 1
TX_ACKNAK_FLIT_SEQ_NUM = NEXT_EXPECTED_RX_FLIT_SEQ_NUM - 1
NAK_SCHEDULED_TYPE = STANDARD_NAK or SELECTIVE_NAK
else: # 当前Flit是Payload Flit
# 发送Standard Nak计划
if "计划发送Standard Nak":
stadard_nak_procedure()
# 发送Selective Nak计划
else:
NEXT_RX_FLIT_SEQ_NUM_TO_STORE = NEXT_TX_FLIT_SEQ_NUM + 1
selective_nak_procedure()
else: # 前一个Flit时NOP
if bad_sequence_number() or bad_nop_sequence_number():
"采用规则Nak Schedule 2"
else: # Withdraw Nak
if ("Payload Flit" and duplicate_sequence_number()) or "NOP Flit":
# 为NEXT_EXPECTED_RX_FLIT_SEQ_NUM - 1调度Ack
TX_ACKNAK_FLIT_SEQ_NUM = NEXT_EXPECTED_RX_FLIT_SEQ_NUM - 1
"丢弃Flit中TLP字节"
# 对NEXT_EXPECTED_RX_FLIT_SEQ_NUM提前处理Schedule Ack
if "Paylod Flit" and (NEXT_EXPECTED_RX_FLIT_SEQ_NUM == IMPLICIT_RX_FLIT_SEQ_NUM):
TX_ACKNAK_FLIT_SEQ_NUM = NEXT_EXPECTED_RX_FLIT_SEQ_NUM
"NEXT_TX_FLIT_SEQ_NUM增加"
else: # NAK_WITHDRAWAL_ALLOWED == 0
if "NOP Flit":
if bad_nop_sequence_number():
"采用规则Nak Schedule 2"
else:
"采用规则Flit Discard 0"
else: # Payload Flit
if NAK_SCHEDULED == 1:
if NAK_SCHEDULED_TYPE == Standard Nak:
standard_nak_procedure()
else: # Selective Nak
selective_nak_procedure()
else: # NAK_SCHEDULED == 0
if duplicate_sequence_number():
"采用规则Flit Discard 0"
else if bad_sequence_number():
"采用规则Nak Schedule 2"
else: # 向前进
"采用规则Ack Schedule 0"
# end 有效的Flit
# 坏的 Sequence Number 检查逻辑
def bad_sequence_number():
return (NEXT_EXPECTED_RX_FLIT_SEQ_NUM - IMPLICIT_RX_FLIT_SEQ_NUM) mod 1023 > 511
def bad_nop_sequence_number():
return bad_nop_sequence_number() or (IMPLICIT_RX_FLIT_SEQ_NUM == NEXT_EXPECTED_RX_FLIT_SEQ_NUM)
# 重复Sequence Number检查逻辑
def duplicate_sequence_number():
return (TX_ACKNAK_FLIT_SEQ_NUM - IMPLICIT_RX_FLIT_SEQ_NUM) mod 1023 < 511
# 当调度一个Standard Nak或当一个Standard Nak是未完成的,Ack/Nak/丢弃逻辑。
def standard_nak_procedure():
if duplicate_sequence_number():
if NAK_SCHEDULED == 1:
"采用规则Flit Discard 0"
else:
"采用规则Nak Schedule 2"
else if "接收到的Flit是Explicit Sequence Number Flit" and (IMPLICIT_RX_FLIT_SEQ_NUM == NEXT_EXPECTED_RX_FLIT_SEQ_NUM):
"采用规则Ack Schedule 1"
else:
"采用规则Nak Schedule 2"
# 当调度一个Selective Nak或当一个Selective Nak是未完成的,Ack/Nak/丢弃逻辑。
def selective_nak_procedure():
if duplicate_sequence_number():
"采用规则Flit Discard 0"
else if "接收到的Flit是Explicit Sequence Number Flit" and (IMPLICIT_RX_FLIT_SEQ_NUM == NEXT_EXPECTED_RX_FLIT_SEQ_NUM):
if RX_RETRY_BUFFER_OVERFLOW == 1:
"采用规则Nak Schedule 5"
else:
"采用规则Ack Schedule 2"
else if IMPLICIT_RX_FLIT_SEQ_NUM == NEXT_RX_FLIT_SEQ_NUM_TO_STORE:
if "RX重传缓冲区满了":
"采用规则Nak Schedule 4"
else:
# 存储Flit
"采用规则Nak Schedule 3"
else: # 坏的Sequence Number
"采用规则Nak Schedule 2"
Nak规则
- Nak Schedule 0
- 丢弃接收到的 Flit
- NAK_WITHDRAWAL_ALLOWED 置为1b
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM 不变
- Nak Schedule 1
- 丢弃接收到的Flit
- NAK_SCHEDULED 置为1
- TX_ACKNAK_FLIT_SEQ_NUM 设置为 NEXT_EXPECTED_RX_FLIT_SEQ_NUM – 1
- NAK_SCHEDULED_TYPE 被设置为 STANDARD_NAK 或者 SELECTIVE_NAK
- 清掉 NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM 不变
- Nak Schedule 2
- 丢弃接受到 Flit 的 TLP 字节
- TX_ACKNAK_FLIT_SEQ_NUM 设置为 NEXT_EXPECTED_RX_FLIT_SEQ_NUM – 1
- NAK_SCHEDULED 设置为1
- NAK_SCHEDULED_TYPE 设置为 STANDARD_NAK
- RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM 设置为0b
- 清掉 NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM 不改变
- NaK Schedule 3
- RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM 设置为 IMPLICIT_RX_FLIT_SEQ_NUM
- NEXT_RX_FLIT_SEQ_NUM_TO_STORE 增加
- 清掉 NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM 不改变
- Nak Schedule 4
- 接收到的 Flit 如果不能存放在 RX 重传缓冲区,将会被丢弃
- 如果接收机继续选择 Selective Nak:
- RX_RETRY_BUFFER_OVERFLOW 设置为1b
- RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM 不改变
- 如果接收机选择将 Selective Nak 改变为 Standard Nak:
- NAK_SCHEDULED_TYPE 设置为 STANDARD_NAK
- TX_ACKNAK_FLIT_SEQ_NUM 设置为 NEXT_EXPECTED_RX_FLIT_SEQ_NUM – 1
- 所有在RX重传缓冲区存储的Flits都会丢掉
- RX_RETRY_BUFFER_OVERFLOW 设置为 000h
- 清掉NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM不改变
- Nak Schedule 5
- NAK_SCHEDULED仍然为1
- NAK_SCHEDULED_TYPE设置STANDARD_NAK
- NAK_SCHEDULED_TYPE设置为RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM
- 清掉RX_RETRY_BUFFER_OVERFLOW
- 清掉NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM设置为RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM+1
- RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM设置为000h
- Nak Schedule 6
- 丢掉接受的Flit
- NAK_SCHEDULED仍然为1
- NAK_SCHEDULED_TYPE设置为STANDARD_NAK
- 清掉RX_RETRY_BUFFER_OVERFLOW
- 清掉NAK_WITHDRAWAL_ALLOWED
- TX_ACKNAK_FLIT_SEQ_NUM设置为NEXT_EXPECTED_RX_FLIT_SEQ_NUM-1
- 所有存放在RX重传缓冲区都会被清理
- Nak Schedule 7
- 无论何种原因,允许接收机将TX_ACKNAK_FLIT_SEQ_NUM中的Selective Nak改变为TX_ACKNAK_FLIT_SEQ_NUM中的Standard Nak
Ack规则
- Ack Schedule 0
- TX_ACKNAK_FLIT_SEQ_NUM设置为NEXT_EXPECTED_RX_FLIT_SEQ_NUM
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM增加
- Ack Schedule 1
- 清掉NAK_SCHEDULED
- TX_ACKNAK_FLIT_SEQ_NUM设置为IMPLICIT_RX_FLIT_SEQ_NUM
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM设置为IMPLICIT_RX_FLIT_SEQ_NUM+1
- Ack Schedule 2
- 清掉NAK_SCHEDULED
- 如果RX重传缓冲区为空
- TX_ACKNAK_FLIT_SEQ_NUM设置为N
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM设置为N+1
- 如果RX重传缓冲区不为空:
- TX_ACKNAK_FLIT_SEQ_NUM设置为RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM设置为RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM+1
- RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM设置为000h
- Ack Schedule 3
- 清掉NAK_WITHDRAWAL_ALLOWED
- TX_ACKNAK_FLIT_SEQ_NUM设置为IMPLICIT_RX_FLIT_SEQ_NUM
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM设置为IMPLICIT_RX_FLIT_SEQ_NUM+1
Flit丢弃规则
- Flit Discard 0
- 丢弃接受到Flit中TLP字节
- 清掉NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM不改变
- Flit Discard 1
- 丢掉接受到的Flit
- 清掉NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM不改变
- Flit Discard 2
- 丢掉接受到的Flit
- 在相应得接受端口记录数据链路协议错误
- 清掉NAK_WITHDRAWAL_ALLOWED
- NEXT_EXPECTED_RX_FLIT_SEQ_NUM不改变
Flit重传规则
- Replay Schedule Rule 0
- 超时重传
- 如果REPLAY_TIMEOUT_FLIT_COUNT大于等于1500,REPLAY_SCHEDULED是0且REPLAY_IN_PROGRESS是0,则:
- REPLAY_SCHEDULED置1b
- REPLAY_SCHEDULED_TYPE设置为STANDARD_REPLTY
- TX_REPLAY_FLIT_SEQ_NUM设置为ACKD_FLIT_SEQ_NUM+1
- CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS设置为0b
- CONSECUTIVE_TX_NAK_FLITS设置为0b
- REPLAY_TIMEOUT_FLIT_COUNT设置为0b
- 重传计数器超时错误会记录在端口中
- Replay Schedule Rule 1
- 收到Payload Flit的Nak
- 如果下面所有条件为真:
- 收到有效的Nak Flit,其Flit Sequence Number为N
- Flit Sequence NumberN+1的Payload Flit存放在TX重传缓冲区
- REPLAY_SCHEDULED是0b
- REPLAY_IN_PROGRESS是0b
- 下面其中一个为真:
- NAK_IGNORE_FLIT_SEQ_NUM不为N
- Nak Ignore Window还没开始或者已过去
- 那么:
- REPLAY_SCHEDULED设置为1b
- TX_REPLAY_FLIT_SEQ_NUM设置为N+1
- NAK_IGNORE_FLIT_SEQ_NUM设置为N
- 如果收到的Flit是Standard Nak Flit
- 则REPLAY_SCHEDULED_TYPE设置为STANDARD_REPLTY
- 如果收到的Flit是Selective Nak Flit
- 则REPLAY_SCHEDULED_TYPE设置为SELECTIVE_REPLAY
- Replay Schedule Rule 2
- 对于Payload Flit而言,Selective Nak后收到Standard Nak
- 如果下面所有条件都为真:
- 收到有效的Standard Nak Flit,其Flit Sequence Number为N
- N等于TX_REPLAY_FLIT_SEQ_NUM
- REPLAY_SCHEDULED是1b
- REPLAY_IN_PROGRESS是0b
- REPLAY_SCHEDULED_TYPE是SELECTIVE_REPLAY
- 那么:
- REPLAY_SCHEDULED设置为0b
- TX_REPLAY_FLIT_SEQ_NUM不改变
- REPLAY_SCHEDULED_TYPE设置为STANDARD_REPLTY
Flit重传发射规则
- Flit Replay Transmit Rule 0
- Standard Replay场景
- 如果下列所有条件为真:
- REPLAY_SCHEDULED是1b
- REPLAY_IN_PROGRESS是0b
- REPLAY_SCHEDULED_TYPE是STANDARD_REPLTY
- CONSECUTIVE_TX_NAK_FLITS要么是0,要么大于2
- 以下满足其一:
- 数据速度是64.0GT/s且FLIT_REPLAY_NUM小于111b
- 数据速度是32.0GT/s且FLIT_REPLAY_NUM小于110b
- 那么:
- 发射机必须从包含Flit Sequence NumberTX_REPLAY_FLIT_SEQ_NUM的Flit开始重播所有未确认的Flit。
- 如果数据速度是64.0GT/s
- FLIT_REPLAY_NUM加1
- 如果数据速度小于等于32.0GT/s
- FLIT_REPLAY_NUM加2
- REPLAY_IN_PROGRESS设置为1b
- REPLAY_SCHEDULED设置为0b
- Flit Replay Transmit Rule 1
- Selective Replay场景
- 如果下面所有条件都满足:
- REPLAY_SCHEDULED是1b
- REPLAY_IN_PROGRESS是0b
- REPLAY_SCHEDULED_TYPE是SELECTIVE_REPLAY
- CONSECUTIVE_TX_NAK_FLITS要么是0要么大于2
- 或者满足下面其一:
- 数据速率是64.0GT/s且FLIT_REPLAY_NUM小于111b
- 数据速率小于等于32.0GT/s且FLIT_REPLAY_NUM小于110b
- 那么:
- 发送器必须从TX重传缓冲区中重传Flit,重传的 Flit Sequence Number 为 TX_REPLAY_FLIT_SEQ_NUM.
- FLIT_REPLAY_NUM 增加
- REPLAY_IN_PROGRESS 设置为 1b
- REPLAY_SCHEDULED 设置为 0b
- Flit Replay Transmit Rule 2
Replay Rollover场景- 如果下面所有条件为真:
- REPLAY_SCHEDULED 是 1b
- REPLAY_IN_PROGRESS 是 0b
- 满足以下其一:
- 数据速率是 64.0GT/s 且 FLIT_REPLAY_NUM 等于 111b
- 数据速率小于等于 32.0GT/s 且 FLIT_REPLAY_NUM 大于等于110b
- 那么:
- 如果数据速率是 64.0GT/s,FLIT_REPLAY_NUM 加 1 (可能导致从111b变到000b)
- 如果数据速率小于等于 32.0GT/s,FLIT_REPLAY_NUM 加 2 (可能导致变到 000b 或者 001b )
- 端口必须记录 REPLAY_NUM Rollover 错误
- 端口必须进入 Recovery
- 如果下面所有条件为真:
Flit模式下,数据流中插入有序集
- 在2.5GT/s和5.0GT/s速度下,SKP有序集插入间隔跟Non-Flit模式一直(插入间隔为1180到1538个 Symbol ),但是插入位置是在Flit边界
- 在8.0GT/s及以上速率时,规则如下
- 无论先前的控制SKP有序集是何时传输,控制SKP有序集必须紧跟SDS有序集(标记数据流开始)之后,
- 一旦数据流开始传输,有序集必须在固定的间隔发送
- 如果数据流继续,则必须在所有激活(或待激活)的lane上传输SKP Ordered Set.
- 在L0p,如果具有升lane的能力:将将要激活的lane加入到激活的lane中,在所有将被激活的lane(而不是那些已经激活的lane)上传输SDS有序集,然后在所有更宽的链路上发送SKP有序集,之后将在更宽的链路上发送Flits
- 如果链路将进入低功耗状态,则必须在所有活动lane上发送EIOSQ
- 如果(链路需要进入Recovery状态):链路上所有配置的lane都必须发送EIEOS
- 如果链路进入Recovery状态,则必须在第一个有序集(EIEOS)之后立即传输适当的SKP有序集。
- 如果数据流继续,则必须在所有激活(或待激活)的lane上传输SKP Ordered Set.
| 链路宽度和时钟模式 | x16 | x8 | x4 | x2 | x1 |
|---|---|---|---|---|---|
| 1b/1b编码下Common Clock/SRNS | 748 | 374 | 187 | 93 | 46 |
| 128b/130b编码下Common Clock/SRNS | 374 | 187 | 93 | 46 | 23 |
| 1b/1b编码下SRIS模式 | 74 | 137 | 18 | 9 | 4 |
| 128b/138b编码下SRIS模式 | 37 | 18 | 9 | 4 | 2 |
如果在这个过程中遇到了其它问题,欢迎在评论区留言,如果你已解决,也欢迎把具体的解决方法留在评论区,以供后来者参考
×
感谢您的支持,请扫码打赏
很不错,帮大忙了
@cszdzc 哈哈,后面有了新的理解,如果有时间,会慢慢完善