ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

PCIe协议学习之-Ack/Nak协议

2021-05-05 21:59:24  阅读:409  来源: 互联网

标签:TLP SEQ Ack Nak DLLP PCIe NUM


Ack/Nak协议是PCIe Data Link layer中最重要的内容。它用来保证TLP的可靠传输。它是基于Retry buffer实现的,Tx发出TLP后,将原始的TLP存到Retry buffer里面,当RX通过Ack DLLP告知已经正确收到TLP后才会将TLP中相应的TLP移除。当Rx通过Nak DLLP告知Tx有TLP出现错误后,Tx可以将Retry buffer中的相应TLP resent出去。

Tx和Rx的逻辑框图如下:

TX端

1)SEQ Num分配

DL层从TL层收到TLP后,要为其分配SEQ Num, 这个SEQ Num来自一个12bits的NEXT_TRANSMIT_SEQ(NTS), NTS从0开始每次加1,到4095后又rollover到0.

2)Ack/Nak DLLP

在Ack DLLP中,AckNak_Seq_Num的含义是Rx成功接收的最后一个TLP的SEQ_NUM。在Nak DLLP的含义也是Rx成功接收的最后一个TLP的SEQ_NUM,而不是失败的TLP的SEQ_NUM. 也就是说,当Tx收到Ack/Nak后,等于或者小于SEQ_NUM的TLP都可以从Retry buffer中移除了。

2)AckD_SEQ(AS)

含义是最近一次被成功接收了的SEQ_NUM, AckD应该是Acknowledged的意思??

3)Retry Timer

当Tx方向发出了TLP而没有收到Ack/Nak,则这个timer就处于running. 当收到Ack后,reset timer, 将retry buffer里面等于或者小于SEQ_NUM的TLP移除后,若retry buffer里面还有TLP,则重新启动timer, 若retry buffer里面没有TLP则保持timer为0,直到后面Tx又发出了新的TLP, timer重新启动。每当timer超时后,Tx就会将Retry buffer里面的TLP全部重新发一遍然后重启这个timer.

4) Retry Num Count

用于记录retry的次数,2bits, 初始值为0,每进行一次retry, Retry Num都会加1,当Tx收到Ack DLLP,且SEQ_NUM>AS(即有一个或多个TLP被正确接收了)清0。当Retry Num从3 rollover到0时,DL通知PL进行retrain, PL的LTSSM跳到Recovery状态。Retrain完成后,Tx将resent retry buffer里面的TLP.

5) 上诉逻辑图中,只进行了SEQ_NUM==AS的判断,为什么没有进行大于和小于的判断?

只要SEQ_NUM != AS, 就将AS更新为SEQ_NUM的值,理论上讲,NTS-AS的差值不会超过最大值的一半即2048,如果超过了2048就在逻辑上代表NTS<AS, 会上报DLL Protocal error。回到上面的问题,之所以不进行SEQ_NUM<AS的判断,是因为不会出现这种情况,否则就要上报错误。值得注意的是,NTS达到最大值后都是rollover的,因此判断SEQ_NUM的大小都是通过两者之差是否小于最大值的一半来判断的,这一点于Flow control里面的counter类似。可以结合下图进行理解,比一个数大的就是其右边的2037个,再往右的2048个都是比自己小的。

6) DLLP CRC Check

当TX端收到来自RX端的Ack/Nak DLLP后,会首先进行DLLP的CRC校验,如果校验失败则直接丢弃DLLP,同时上报Correctble Error (if enable)。不用担心DLLP丢弃后会丢失信息,RX端后续发过来的Ack/Nak会报告RX端最后收到的Good TLP的SEQ_NUM。

RX端

1)NRS

NEXT_RCV_SEQ(NRS) counter用来记录RX端期望下一次接收到的TLP的SEQ_NUM, 12bits, 初始值为0。当收到1个good TLP后该counter会加1。

2)LCRC Check

收到TLP后进行LCRC Check,如果Pass则继续SEQ_NUM Check。如果LCRC fail则认为是一个bad TLP,丢弃bad TLP并将NAK_SCHEDULED置1,如果NAK_SCHEDULED的前值为0则立即发送Nak DLLP(SEQ_NUM=NRS-1)。NAK_SCHEDULED的存在,是为了避免重复发送Nak DLLP, Nak DLLP只会在NAK_SCHEDULED的上升沿发送。当收到good TLP后将NAK_SCHEDULED清0。

3)SEQ_NUM Check

3.1 当TLP的SEQ_NUM==NRS, 这正是期望的,意味着收到一个good TLP。TLP收下来并转交给TL层,NRS加1。需要发送Ack DLLP,但不需要马上就发,等到AckNak_Latency_Timer超时后再发送SEQ_NUM=NRS-1的Ack

3.2 当TLP的SEQ_NUM<NRS,证明收到的TLP之前已经收到过了。导致这种情况可能是由于之前RX端发过去的Ack由于某些原因TX端并没有正确收到,然后TX端的Retry Timer超时后将Retry Buffer里面的TLPs又发了一遍。这种情况TLP直接丢弃,然后发送一个SEQ_NUM=NRS-1的Ack DLLP(不用等AckNak_Latency_TImer超时)。

3.3 当TLP的SEQ_NUM>NRS, 证明一定有TLP丢失了,因为good TLP一定是按顺序接收的,不应该出现SEQ_NUM>NRS的情况。这种情况下,bad TLP被丢弃,如果NAK_SCHEDULED为0则将其置1并发送一个SEQ_NUM=NRS-1的Nak DLLP。

4)AckNak_Latency_Timer

当RX方还有good TLP没有被Ack时,该timer running。当收到Good TLP后开始启动,当发送了Ack/Nak后清0。当该timer超时后,发送一个SEQ_NUM=MRS-1的Ack DLLP。

 

标签:TLP,SEQ,Ack,Nak,DLLP,PCIe,NUM
来源: https://blog.csdn.net/HelloQili/article/details/115737108

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有