学习协议是蛮枯燥的一个事情。而学习ACK/NAK就更枯燥,整个ACK/NAK流程比较复杂,发送接收都有较晦涩的逻辑流程。

        我们分解一下,先了解一些相关术语,我们从ACK/NAK基本的元素开始学习,首先看看发送端的:

A. Replay Buffer
        或者叫做retry buffer,它存储了所有发送出去还没有得到确认的的报文。并且按照序列号(sequence number)的顺序存放来自TL层的报文。如果对端确认收到,并回复ACK,相应的报文会从Replay Buffer删除,否则,将重发缓冲区的报文。

B. NEXT_TRANSMIT_SEQ counter
        它为每个TL下来的TLP报文生产一个序列号,并累加。12位的计数器达到4095后翻转为0。

C. LCRC Generator
        它为每一个TLP报文生成一个32位的LCRC,计算范围包括TLP的内容(Header, Data Payload, ECRC)以及添加的序列号,接收端会重新计算以校验LCRC是否正确。

D. REPLAY_NUM Count
        这个2位的计数器代表某个TLP发送失败的次数, 当收到NAK或者对应的REPLAY_TIMER溢出,均会加1。当超过4次重发后,数据链路层会触发物理层重新做链路训练(Link-retrain)。

E. REPLAY_TIMER Count
        当TLP启动发送后,即会启动REPLAY_TIMER,当收到应答后,TIMER清零。如果一定时间都没有收到接收端的应答,TIMER溢出,触发Replay Buffer中的TLP重发。注意:当收到应答后TIMER清零,不过如果这个时候Replay Buffer里面还有TLP待发送的话,TIMER会重新启动。
 TIMER的值的计算Spec定义了一套公式,根据链路带宽和最大负载(Max Payload Size)综合计算的,例如Gen3的TIMER值如下:
 

F. ACKD_SEQ Count
        这个12位的计数器保存着最后收到的应答的DLLP的序列号。这个计数器会跟NEXT_TRANSMIT_SEQ 做比较,如果两者差大于2047,DLL不会再从TL层接收新的TLP,并报告一个致命错误。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注