Flit模式操作
Flit模式
一些缩写
- Flit : Flow Control Unit,流控单元
- PAM4 : Pulse Amplitude Modulation 4-levels,脉冲幅度调制 4 级
- FEC : Forward Error Correction,前向纠错
Flit构成
- Flit模式将需要传输的内容固定为256字节,构成如下
- 236字节的TLPs(Flit中的字节0到字节235)
- 6字节的数据链路层载荷(Data Link Layer Payload,DLP,DLP在Flit中处于236字节到241字节,DLP0..6)
- 8字节的CRC(在Flit中位于242字节到249字节,CRC0..7)
- 6字节的ECC(在Flit中位于250字节到255字节,ECC0[0:1],ECC1[0:1],ECC2[0:1])
- Flits在8b/10b编码基本与Non-Flit模式相同,除开下面的列外
- 因为Flit模式会固定放置TLP和DLP,所以包的标志符号如STP,SDP,END,EDB不会在使用
- Flits在128b/130b编码基本与Non-Flit模式相同,除开下面的例外:
- 因为Flit模式下TLP和DLP会放在固定的位置,所有用于组帧的令牌不在使用,比如STP,SDP,EDB,EDB令牌
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有序集中,只有一些符号是加扰,这些符号也需要进行格雷码编码,不加扰的符号不需要格雷码编码
- 发送方向,所有半加扰TS0有序集符号选择性地进行格雷编码
- 只有在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有序集的所有符号都不需要与编码.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比特边界对齐.一个符号表示为’S7S6S5S4S3S2S1S0‘,lane上放置的符号以S1S0开始,以S7S6‘结束
- 链路速率为64.0GT/s下及更高时,使用的Flit模式
- 1b/1b编码下,每条lane上传输的基本单元是一个符号(8比特)
- Flit模式下,无论是数据流还是有序集,所有符号都采用PAM4信号编码
- 发送方向
- Flit层级上,发射方向首先计算出CRC,然后生成FEC.
- Flit一字节交错的方式放置在每条lane上.此后的操作基于每条lane
- 如果启用加扰(某些内容是不需要加扰的),就执行加绕
- 2比特边界对齐的格雷码编码
- 执行预编码(如果启用并且需要),预编码是2比特对齐的(TODO(翻译))
- 所有符号,无论是Flit(数据流)还是有序集中加扰的符号或者任意序列(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有序集
- 符号0和符号8不加扰
- 符合1到符号6和符号9到符号14需要加扰
- 如果用于直流平衡,符号7到符号15不需要加扰,否则需要加扰
- TS0有序集
- 符号0和符号8不加扰
- 符号1到符号6和符号9到符号14通过基于非归零码加扰(non-return-to-zero,NRZ)
- 基于非归零码加扰由8比特加扰跟着是选择性格雷码编码,以此来确保只有电压幅度为0和3在发送,具体实现方式是强制偶数位(2i)和奇数位(2i+1)相同(i在0到3之间)
- 如果符号7和符号15用于直流平衡,则绕过加扰;否则它们分别带有NRZ扰码的符号1至6符号9至14的偶校验信息
- TS0中的所有符号都是基于不归零编码(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的结束匹配
- 或者块的符号0或者符号8h与EIEOS符号相应的比特符号,在这个对比的过程中,如果有一比特不符合,允许接收机忽略这种错误.
- 当处于对齐阶段时,如果EIEOS有序集持续时间超过了一个时间单位或者EIEOS有序集的持续时间小于一个时间单位但是后面跟着的是期望的有序集(第一个符号是有序集的标识),接收机必须切换到块边界.
- 在搜索EIEOS的过程中,在任意对齐的时间单位上,都可以是8比特的边界,接收端在执行格雷码编码,预编码或者解扰前必须先实现位锁定
- 在下面的条件下认为是收到了EIOS
- 块的第一个8字节中有5个或者更多对齐的字节f符合EIOS对应的比特
- 或者块的符号0或者符号8符合EIOS对应的比特.当收到EIOS后,lane准备进入电气空闲,而不管块中最后的7个字节
- 在下列情况下,认为收到了SKPOS.
- 块第一个8字节中,超过5个或者更多的字节与SKP相符,并且块的符号0是SKP或者符号8是SKP或者符号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状态时,并且随后接收到的符号与期望有序集的第一个符号匹配,接收机必须调整自己的对齐方式,以跟新的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令牌.取而代之的是,数据流结束的标识是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及以上数据速率下,每个字节对应一个符号.数据块的一个符号在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的最后一个符号中).
Flit中的字节布局
Flit中的TLP字节
- flit中的TLP字节携带事务层TLP.
- 由于Flit模式不支持STP令牌,这些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信用
- Flit中DLP的分布
- 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序列号=NEXT_TX_FLIT_SEQ_NUM-1;其它字段为任意合法的编码 任何合法的编码 Payload Flit 236字节中至少有一个不是NOP TLP Flit Usage字段为01b;如果重传命令为00b,Flit序列号字段=NEXT_TX_FLIT_SEQ_NUM-1;其它字段为任意合法的编码 任意合法的编码 表格4-17 Flit中的DLP字节字段 位置 编码 Flit Usage DLP0的bit[7:6] 00b:IDLE Flit或者NOP Flit;
01b:Palyload Flit;
其它:保留前一个Flit是有效载荷Flit DLP0的bit[5] 0b:前一个Flit是NOP Flit或者是IDLE Flit;
1b:前一个Flit是Payload Flit载荷中DLLP的类型 DLP0的bit[4] 0b:DLP的2,3,4,5是DLLP载荷
1b:DLP 2,3,4,5是Optimized_Update_FC或者是Flit标志重传命令[1:0] DLP0的bit[3:2] 00b:传输的Flit中,Flit中包含的Flit序列号是显式Flit序列;
01b:来自接收器的Flit序列号确认(Ack).包含的Flit序列号表示接收到的最后一个有效Flit的Flit序列号.
10b:Nak请求重播所有未确认的 Flit.包含的Flit序列号表示接收到的最后一个有效Flit的Flit序列号.
11b:Nak请求重播单个Flit(Flit序列号+1),包含的Flit序列号表示接收到的最后一个有效Flit的Flit序列号Flit序列号[9:0] DLP0的bit[1:0],DLP1的bit[7:0] Flit中的10比特的序列号,DLP0[1:0]是Flit序列号的[9:8],DLP1[7:0]是Flit序列号的[7:0] DLLP载荷 {DLP2,DLP3,DLP4,DLP5} DLLP载荷类型为0b,常规的DLLP载荷 Optimized_Update_FC DLP2,3,4,5 bit[31:0] DLLP载荷类型为1且bit[31]=0b Flit_Marker DLP2的bit[31:24]
DLP3的bit[23:16]
DLP4的bit[15:8]
DLP5的bit[7:0]DLLP载荷类型为1且bit[31]=1b - 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消息的最后一个符号.
无效的PTM消息不设置此位.
不允许使用有毒的PTM消息. - 不同类型的Flit有相同的CRC和FEC机制
- 基于携带的TLP和DLP字节,区分成不同的Flit,便于参考
- IDLE Flit
- 使用的序列号为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保留的编码
- 无效的序列号
- 违反了TLP组报规则
Flit中的CRC字节
- CRC计算
- CRC产生采用多项式,g(x)=(x+α)(x+α2)…(x+α8),其中α是8次原多项式的根:x8+x5+x3+x+1.
- 展开后g(x) = x8+α172x7+α116x6+α186x5+α172x5+α195x3+α134x2+α199x+α36
- 下图中,g0表示0次项的系数,…,g7表示x7项的次数, GF(28)表示256位
- CRC检查规则
- 在接收端,生成的CRC字节与接收的CRC字节进行比较(在FEC解码/纠正之后),任何不匹配都表示不可纠正的错误。
- 任何不匹配都会导致Flit被声明为无效,并在需要时请求重传。 TODO
Flit中的EEC字节
- FEC代码是3路交错的,其中ECC符号是在GF(28)上定义的。
- 3个连续的字节属于三个不同的ECC组
- 因此,导线中长度≤16的任何突发都保证不会影响一个码字中的多个符号,从而能够纠正单字节错误,以尽量减少FEC延迟。
- 假设α是x8+x4+x3+x2+1的根(表示为0x1D-0001 1101),因此α8=α4+α3+α2+1可以表示为{0001_1101}
- 因此,每个8位符号(在GF(28)上)可以表示为幂的多项式(1到254)或8次多项式。 TODO
Flit序列号和重传机制
预定义的项
Explicit Sequence Number Flit
: 显式序列号的Flit,载荷Flit或者NOP Flit中重传命令位00bAck Flit
: Flit中重传命令位01bStandard Nak Flit
: Flit中重传命令位10bSelective Nak Flit
: Flit中重传命令位11bNak Flit
: Flit中重传命令位10b或者11bStandard Nak
: 请求重传所有未确认Flit的Nak.Selective Nak
: 请求重传特定Flit的NakStandard Replay
: 重传TX重传缓冲区中所有未确认的Flit。Selective Replay
: 重传TX重传缓冲区中特定的FlitTX Retry Buffer
: 存储传输Flit信息的缓冲区,直到Flit被链路对端确认为止.RX Retry Buffer
: 存储接收到Flit信息的缓冲区,直到Flit被接收方使用.Nak Ignore Window
: 在这个时间窗口内,对于特定的Flit序列号,忽略接收到的Nak Flit- 当Explicit Sequence Number Flit要发送,并且序列号为NAK_IGNORE_FLIT_SEQ_NUM+1(NAK_IGNORE_FLIT_SEQ_NUM不为0)时,启动Nak Ignore Window
一些标志和计数器
NEXT_TX_FLIT_SEQ_NUM
: 10比特无符号计数器,此计数器记录传输Flit的Flit序列号- 在DL_Inactive状态为001h
TX_ACKNAK_FLIT_SEQ_NUM
: 存储下一个Ack Flit或Nak Flit中要传输的10位序列号.- 在DL_Inactive状态设置为1023
CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
: 2位无符号计数器,跟踪发射机发送了多少个连续的Explicit Sequence Number Flits
。- 在IDLE Flit Handshake阶段设置为00b
CONSECUTIVE_TX_NAK_FLITS
: 3位无符号计数器,跟踪发射机发射了多少连续的Nak Flits.- 在IDLE Flit Handshake阶段设置为000b
- 此计数器最多计数到111b,并且不会翻转到000b
NEXT_EXPECTED_RX_FLIT_SEQ_NUM
: 10位无符号计数器,存储要接收的下一个有效非IDLE非重复Flit的预期Flit序列号。- 在DL_Inactive状态设置为001h
IMPLICIT_RX_FLIT_SEQ_NUM
: 10位无符号计数器,用来追踪接收到Flit中显式Flit序列号- 在DL_Inactive状态设置为000h
ACKD_FLIT_SEQ_NUM
: 存储10位Flit序列号,该序列号为最近处理的有效Ack Flit或Nak Flit中的- 在DL_Inactive状态设置为3FFh
NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD
: 自IDLE Flit握手阶段的最后一个条目以来,标志已接收到非IDLEExplicit Sequence Number Flit
。- 在进入IDLE Flit握手阶段时清掉
REPLAY_SCHEDULED
: 标志已计划从TX重传缓冲区中重传一个Flit。- 在DL_Inactive状态清零
REPLAY_SCHEDULED_TYPE
: 指示是否计划了Standard Replay
或Selective Replay
。- 如果
REPLAY_SCHEDULED
为1:REPLAY_SCHEDULED_TYPE
为0表示是一个Standard Replay
,并将其称为STANDARD_REPLTY
REPLAY_SCHEDULED_TYPE
为1表示是一个Selective Replay
,并讲你称为SELECTIVE_REPLAY
- 如果
REPLAY_IN_PROGRESS
: 表明发送器正在从TX重传缓冲区发送Flits- 在DL_Inactive状态清零
TX_REPLAY_FLIT_SEQ_NUM
: 存储从TX重传缓冲区中重传的第一个Flit的10位Flit序列号。- 在DL_Inactive状态设置为000h
FLIT_REPLAY_NUM
: 3位无符号计数器,用于跟踪重传被启动而没有向前进行的次数。- 在DL_Inactive状态设置为000b
REPLAY_TIMEOUT_FLIT_COUNT
: 11位无符号计数器,计算自最后一次未完成的Flit Ack以来发送的有效载荷Flits和NOP Flits的数量。- 在DL_Inactive状态设置为000h
- 计数器在7FFh饱和,不会滚到000h。
NAK_SCHEDULED
: 指示Nak Flit已被安排传输- 在DL_Inactive状态清零
NAK_SCHEDULED_TYPE
: 标志将要发送的是Stand Nak Flit
还是Selective Nak Flit
- 在DL_Inactive状态设置为0
- 如果
NAK_SCHEDULED
是1:NAK_SCHEDULED_TYPE
为0表明是Standard Nak Flit
,并将其称为STANDARD_NAK
NAK_SCHEDULED_TYPE
为1表明是Selective Nak Flit
,并将其称为SELECTIVE_NAK
NAK_WITHDRAWAL_ALLOWED
: 指示接收到无效Flit,但如果后续接收到的Flit将”Prior Flit was Payload”设置为0b(指示无效Flit是NOP Flit),则不应被 Nak’d。- 在DL_Inactive状态清掉
NAK_IGNORE_FLIT_SEQ_NUM
: 存储在Nak Ignore Window
期间要忽略的10位Flit序列号。- 在DL_Inactive状态设置为000h
NEXT_RX_FLIT_SEQ_NUM_TO_STORE
: 存储要存储在RX重传缓冲区中的下一个Flit的10位Flit序列号。- 在DL_Inactive状态清掉
RX_RETRY_BUFFER_OVERFLOW
: 表示在收到未完成Selective Nak
的Selective Replay
之前,由于缓冲区已满,因此无法将Flit存储在RX重传缓冲区中。- 在DL_Inactive状态清掉
RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM
: 如果RX重传缓冲区溢出,则存储RX重传缓冲区中存储的最后一个Flit的10位Flit序列号。- 在DL_Inactive状态清掉
MAX_UNACKNOWLEDGET_FLITS
: 未确认的未完成Flits的最大数目- 取其中较小者:
- TX重传缓冲区可以存储的Flit数目
- 511 Flits
- 取其中较小者:
通用的规则
Flit序列号规则
- 对载荷Flit来讲,Flit序列号有效为1-1023.
- Flit序列号0只在IDLE Flit中使用
- NOP Flits不消耗Flit序列号(即发送NOP Flit,Flit序列号不会增加)
- NOP Flit也是
Explicit Sequence Number Flit
,将Flit序号设置为NEXT_TX_FLIT_SEQ_NUM – 1。 - 如果没有载荷Flits需要发送,Flit序列号设置为1023
- 所有Flit Sequence Number计数器将从1023转到1。
- 即使被SKP OS分开,两个发送或接收的Flits也被认为是连续的.
Nak Ignore Window
应该取两者较小的值:- 链路测量Ack/Nak延迟+ 最大大小的SKP有序集+ 2 Flits
- 300ns
- NOP Flit也是
发射机规则
- 发送器必须在TX重传缓冲区中存储传输的有效载荷Flits的以下信息:
- 与非NOP TLP关联的TLP字节
- Flit状态
- Flit序列号
未完成的MAX_UNACKNOWLEDGET_FLITS
- 如果
NEXT_TX_FLIT_SEQ_NUM
–ACKD_FLIT_SEQ_NUM
模1023大于MAX_UNACKNOWLEDGET_FLITS
- 发送端不能接受来自事务层的任何新的TLPs。
- 如果
REPLAY_SCHEDULED
和REPLAY_IN_PROGRESS
都为0,则发射机必须发送一个NOP Flit
REPLAY_IN_PROGRESS规则
- 如果
REPLAY_IN_PROGRESS
为1- 发送端不能接受来自事务层的任何新的TLPs。
- 如果下列条件为真,就清掉
REPLAY_IN_PROGRESS
REPLAY_SCHEDULED_TYPE
是STANDARD_REPLTY
并且在TX重传缓冲区中所有未确认的Flit都发送了REPLAY_SCHEDULED'
是SELECTIVE_REPLAY
并且Flit中Flit序列号等于TX_REPLAY_FLIT_SEQ_NUM
的Flit也发送了
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规则:
- 当传输
Payload Flit
或者NOP Flit
时,并且TX重传缓冲区不为空REPLAY_TIMEOUT_FLIT_COUNT
是增加的
- 当接收到存储在 TX 重试缓冲区中的 Flit 的 ACK时(TODO(翻译))
REPLAY_TIMEOUT_FLIT_COUNT
设置为0
Replay Schedule Rule 0
NEXT_TX_FLIT_SEQ_NUM
- 发送器将重播命令应用于具有显示Flit序列号的的有效载荷后,
NEXT_TX_FLIT_SEQ_NUM
是增加的 - 在发送下面的Flit时,
NEXT_TX_FLIT_SEQ_NUM
不改变- IDLE Flit
- NOP Flit
Selective Replay Payload Flit
接收机规则
- 如果接收者已经安排了一个
Selective Nak Flit
,它必须继续在RX重传缓冲区中存储非NOP TLP字节和随后Flit的Flit序列号。
IMPLICIT_RX_FLIT_SEQ_NUM
- 该值必须更新(TODO)
IMPLICIT_RX_FLIT_SEQ_NUM
在下面几种情况保持不变- 收到IDLE Flit
- 收到Flit序列号为0的
Explicit Sequence Number Flit
NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD
为0,并且满足下面其一:- 收到了一个无效的Flit
- 收到一个有效的非
Explicit Sequence Number Flit
- 收到一个有效的NOP Flit,并且是非显式Flit序列号,且满足下列之一:
NAK_WITHDRAWAL_ALLOWED
是0bNAK_WITHDRAWAL_ALLOWED
是1b并且Prior Flit was Payload
字段为1b
- 下面所有条件都为真:
- 收到有效的
Payload Flit
,且是非显示的Flit序列号 NAK_WITHDRAWAL_ALLOWED
是1bPrior Flit was Payload
是0b
- 收到有效的
- 当下列条件为真时,
IMPLICIT_RX_FLIT_SEQ_NUM
是增加的:NON_IDLE_EXPLICIT_SEQ_NUM_FLIT_RCVD
是1b- 以下任意一种情况为真
- 收到有效的
Payload Flit
,有非显式的Flit序列号,并且NAK_WITHDRAWAL_ALLOWED
是0b - 收到有效的
Payload Flit
,有非显式的Flit序列号,并且Prior Flit was Payload
是1b,NAK_WITHDRAWAL_ALLOWED
是1b - 收到了无效的Flit
- 收到有效的
IMPLICIT_RX_FLIT_SEQ_NUM
设置为N,如果满足下面其一:- 收到了有效的非IDLE显式序列号的Flit,且Flit序列号为N
- N不等于0
- 如果满足下面所有条件,
IMPLICIT_RX_FLIT_SEQ_NUM
减少- 收到有效的NOP Flit,具有非显式的Flit序列号
NAK_WITHDRAWAL_ALLOWED
是1bPrior Flit was Payload
字段是0b
IDLE Flit握手阶段
通用的规则
- 当LTSSM进入Configuration.Idle或者Recovery.Idle时,端口进入IDLE Flit握手阶段
发射机规则
- 发射机必须按照LTSSM要求的规则发送IDLE Flits
- 当LTSSM进入L0时,发射机进入到序列号握手阶段
接收机规则
- 收到的所有Flits都会被丢弃
- 当收到两个连续有效的IDLE Flits后,接收机进入序列号握手状态
序列号握手阶段
通用规则
- 如果数据链路控制和管理状态机分别处于DL_Feature或DL_Init状态,在此阶段,允许设备进行数据链路特征交换和流量控制初始化,
- 当下面两个条件都为真时,端口进入正常Flit交换阶段
- 在接收到一个或者更多显式序列号Flits(Flit序列号不为0)后,端口发送了3个或者更多ACK Flits(Flit序列号不为0)
- 端口发送了9个或者更多显式序列号的Flits(Flit序列号不为0)
- 如果在此阶段,端口发送在1b/1b编码下发送了512个Flits或者在8b/10b或者128b/130b编码下发送了256个Flits,端口必须进入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
- 在此状态,发射机交替发送三个连续的
- Flit重传发射机规则
- 当发送
Explicit Sequence Number Flit
且CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
是0b时,发射机必须从TX重传缓冲区中重传Flits - 当发送
Explicit Sequence Number Flit
时,如果重传的Flit来自TX重传缓冲区,则它必须使用TX重传缓冲区中的序列号 - 其它规则
- 当发送
- Flit序列号规则
- 当发送
Ack Flit
或者Nak flit
且Flit序列号为非0时,Flit序列号设置为TX_ACKNAK_FLIT_SEQ_NUM
- 当发送
Explicit Sequence Number Flit
时,NOP Flit
必须设置Flit序列号为NEXT_TX_FLIT_SEQ_NUM
-1 - 重传的
Payload Flit
必须将Flit序列号设置为在TX重传缓冲区存储的值 - 非重传的
Payload Flit
必须将Flit序列号设置为NEXT_TX_FLIT_SEQ_NUM
- 当发送
接收机规则
- Ack和Nak处理规则
- Ack和Nak调度规则
- 重传调度规则
正常Flit交换阶段
发射机规则
- 当处于该状态时,根据Flit重传命令定义,只会发送
Explicit Sequence Number Flits
- 如果在此阶段发送了
Nak Flit
- 最少必须发送三个连续的
Nak Flits
,除非下列任何一项为真:- 由于
Replay Schedule Rule 0
将CONSECUTIVE_TX_NAK_FLITS
复位 - 由于退出L0打断了Flits的传输
- 由于
- 最少必须发送三个连续的
- 如果在此阶段发送了
Explicit Sequence Number Flits
:- 必须连续发送三个
Explicit Sequence Number Flits
,除非下面任意一项为真:- 由于
Replay Schedule Rule 0
将CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
复位 - 由于退出L0打断了Flits的传输
- 由于
- 必须连续发送三个
Flit重传命令规则
- 按照下列优先级
- 满足下列所有条件,则发射机必须发送
Explicit Sequence Number Flit
- 满足下列任意一条:
REPLAY_SCHEDULED
是1bREPLAY_IN_PROGRESS
是1bCONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
大于0REPLAY_SCHEDULED
是0b且REPLAY_IN_PROGRESS
是0b且NAK_IGNORE_FLIT_SEQ_NUM
不为00h
CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
小于3- 下列任意一个条件为真
CONSECUTIVE_TX_NAK_FLITS
等于0CONSECUTIVE_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个
- 满足下列所有条件,则发射机必须发送
Flit序列号规则
- 当传输
Ack Flit
或者Nak Flit
时,Flit序列号设置为TX_ACKNAK_FLIT_SEQ_NUM
- 当传输
Explicit Sequence Number Flit
时,TODO
CONSECUTIVE_TX_NAK_FLITS规则
- 当传输
Nak Flit
时,CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
增加 - 当传输非
Nak Flit
时,CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
设置为0b - TODO
####接收机规则
- Ack和Nak处理规则
- Ack和Nak调度规则
- 重传调度规则
接受Ack和Nak处理过程
- 如果收到Flit序列号为0的AcK或者Nak,必须忽略
- 在接收到的
Ack Flit
或者Nak Flit
中,处理有效的Flit序列号- 如果下面所有都为真:
- 收到的
Ack Flit
或者Nak Flit
是有效的,Flit序列号为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序列号为N,它必须:- 清除存储在TX重传缓冲区的所有Flits,这些Flits的Flit序列号要小于等于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序列号为N,N不等于NAK_IGNORE_FLIT_SEQ_NUM
且N不等于NEXT_TX_FLIT_SEQ_NUM
-1,则将NAK_IGNORE_FLIT_SEQ_NUM
清零(000h) - 必要时需要重传.TODO
- 如果N=
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序列号"==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
# 坏的序列号检查逻辑
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)
# 重复序列号检查逻辑
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: # 坏的序列号
"采用规则Nak Schedule 2"
Nak规则
- Nak Schedule 0
- 丢弃接收到的Flit
NAK_WITHDRAWAL_ALLOWED
置为1bNEXT_EXPECTED_RX_FLIT_SEQ_NUM
不变
- Nak Schedule 1
- 丢弃接收到的Flit
NAK_SCHEDULED
置为1TX_ACKNAK_FLIT_SEQ_NUM
设置为NEXT_EXPECTED_RX_FLIT_SEQ_NUM
-1NAK_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
-1NAK_SCHEDULED
设置为1NAK_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
设置为1bRX_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
仍然为1NAK_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
+1RX_RETRY_BUFER_LAST_FLIT_SEQ_NUM
设置为000h
- Nak Schedule 6
- 丢掉接受的Flit
NAK_SCHEDULED
仍然为1NAK_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
设置为NNEXT_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
置1bREPLAY_SCHEDULED_TYPE
设置为STANDARD_REPLTY
TX_REPLAY_FLIT_SEQ_NUM
设置为ACKD_FLIT_SEQ_NUM
+1CONSECUTIVE_TX_EXPLICIT_SEQ_NUM_FLITS
设置为0bCONSECUTIVE_TX_NAK_FLITS
设置为0bREPLAY_TIMEOUT_FLIT_COUNT
设置为0b- 重传计数器超时错误会记录在端口中
- Replay Schedule Rule 1
- 收到
Payload Flit
的Nak - 如果下面所有条件为真:
- 收到有效的
Nak Flit
,其Flit序列号为N - Flit序列号N+1的
Payload Flit
存放在TX重传缓冲区 REPLAY_SCHEDULED
是0bREPLAY_IN_PROGRESS
是0b- 下面其中一个为真:
NAK_IGNORE_FLIT_SEQ_NUM
不为NNak Ignore Window
还没开始或者已过去
- 收到有效的
- 那么:
REPLAY_SCHEDULED
设置为1bTX_REPLAY_FLIT_SEQ_NUM
设置为N+1NAK_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序列号为N - N等于
TX_REPLAY_FLIT_SEQ_NUM
REPLAY_SCHEDULED
是1bREPLAY_IN_PROGRESS
是0bREPLAY_SCHEDULED_TYPE
是SELECTIVE_REPLAY
- 收到有效的
- 那么:
REPLAY_SCHEDULED
设置为0bTX_REPLAY_FLIT_SEQ_NUM
不改变REPLAY_SCHEDULED_TYPE
设置为STANDARD_REPLTY
- 对于
Flit重传发射规则
- Flit Replay Transmit Rule 0
Standard Replay
场景- 如果下列所有条件为真:
REPLAY_SCHEDULED
是1bREPLAY_IN_PROGRESS
是0bREPLAY_SCHEDULED_TYPE
是STANDARD_REPLTY
CONSECUTIVE_TX_NAK_FLITS
要么是0,要么大于2- 以下满足其一:
- 数据速度是64.0GT/s且
FLIT_REPLAY_NUM
小于111b - 数据速度是32.0GT/s且
FLIT_REPLAY_NUM
小于110b
- 数据速度是64.0GT/s且
- 那么:
- 发射机必须从包含Flit序列号
TX_REPLAY_FLIT_SEQ_NUM
的Flit开始重播所有未确认的Flit。 - 如果数据速度是64.0GT/s
FLIT_REPLAY_NUM
加1
- 如果数据速度小于等于32.0GT/s
FLIT_REPLAY_NUM
加2
REPLAY_IN_PROGRESS
设置为1bREPLAY_SCHEDULED
设置为0b
- 发射机必须从包含Flit序列号
- Flit Replay Transmit Rule 1
Selective Replay
场景- 如果下面所有条件都满足:
REPLAY_SCHEDULED
是1bREPLAY_IN_PROGRESS
是0bREPLAY_SCHEDULED_TYPE
是SELECTIVE_REPLAY
CONSECUTIVE_TX_NAK_FLITS
要么是0要么大于2- 或者满足下面其一:
- 数据速率是64.0GT/s且
FLIT_REPLAY_NUM
小于111b - 数据速率小于等于32.0GT/s且
FLIT_REPLAY_NUM
小于110b
- 数据速率是64.0GT/s且
- 那么:
- 发送器必须从TX重传缓冲区中重传Flit,重传的Flit序列号为
TX_REPLAY_FLIT_SEQ_NUM
. FLIT_REPLAY_NUM
增加REPLAY_IN_PROGRESS
设置为1bREPLAY_SCHEDULED
设置为0b
- 发送器必须从TX重传缓冲区中重传Flit,重传的Flit序列号为
- Flit Replay Transmit Rule 2
Replay Rollover
场景- 如果下面所有条件为真:
REPLAY_SCHEDULED
是1bREPLAY_IN_PROGRESS
是0b- 满足以下其一:
- 数据速率是64.0GT/s且
FLIT_REPLAY_NUM
等于111b - 数据速率小于等于32.0GT/s且
FLIT_REPLAY_NUM
大于等于110b
- 数据速率是64.0GT/s且
- 那么:
- 如果数据速率是64.0GT/s,
FLIT_REPLAY_NUM
加1(可能导致从111b变到000b) - 如果数据速率小于等于32.0GT/s,
FLIT_REPLAY_NUM
加2(可能导致变到000b或者001b) - 端口必须记录
REPLAY_NUM Rollover
错误 - 端口必须进入Recovery
- 如果数据速率是64.0GT/s,
Flit模式下,数据流中插入有序集
- 在2.5GT/s和5.0GT/s速度下,SKP有序集插入间隔不改变(插入间隔为1180到1538个符号),但是插入位置是在Flit边界
- 在8.0GT/s及以上速率时,规则如下
- 无论先前的控制SKP有序集是何时传输,控制SKP有序集必须紧跟SDS有序集(标记数据流开始)之后,
- 一旦数据流开始传输,有序集必须在固定的间隔发送
表格4-21 数据流中有序集插入间隔(值为Flit的个数)链路宽度和时钟模式 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 - 如果数据流继续,则必须在所有激活(或待激活)的lane上传输SKP Ordered Set.
- 在L0p,如果具有升lane的能力:将将要激活的lane加入到激活的lane中,在所有将被激活的车道(而不是那些已经激活的车道)上传输SDS有序集,然后在所有更宽的链路上发送SKP有序集,之后将在更宽的链路上发送Flits
- 如果链路将进入低功耗状态,则必须在所有活动lane上发送EIOSQ
- 如果(链路需要进入Recovery状态):链路上所有配置的lane都必须发送EIEOS
- 如果链路进入Recovery状态,则必须在第一个有序集(EIEOS)之后立即传输适当的SKP有序集。
- 如果数据流继续,则必须在所有激活(或待激活)的lane上传输SKP Ordered Set.
很不错,帮大忙了
@cszdzc 哈哈,后面有了新的理解,如果有时间,会慢慢完善