這一篇文章來簡單地分析幾個Ack/Nak機制的例子。
Example 1. Example of Ack
Step1 設備A準備依次向設備B發送5個TLP,其對應的序列號分別為3,4,5,6,7;
Step2 設備B成功的接收到了TLP3,并將NEXT_RCV_SEQ從3加到4,但是設備B沒有立即向設備A返回Ack(此時AckNak_LATENCY_TIMER尚未溢出);
Step3 設備B又成功地接收到了TLP4和TLP5;
Step4 假設此時AckNak_LATENCY_TIMER溢出了,則設備B會向設備A返回一個帶有序列號為5的Ack DLLP。同時,設備B將AckNak_LATENCY_TIMER復位,但是并未重新啟動,直到設備B成功地接收到了TLP6。
Step5 設備A接收到了Ack5,將REPLAY_TIMER和REPLAY_NUM復位,然后將Buffer中的序列號5(和5之前)的TLP備份移除;
Step6 一旦設備B接收到TLP6,AckNak_LATENCY_TIMER又會被重新啟動。
Example 2. Ack with Sequence Number Rollover
Step1 設備A準備依次向設備B發送序列號為4094,4095,0,1,2的TLP,注意第一個發送的是TLP4094,最后一個發送的是TLP2。也就是說序列號Rollover了;
Step2 設備B成功接收到TLP4094~TLP1后,假設此時AckNak_LATENCY_TIMER溢出了,則設備B向設備A返回Ack1 DLLP;
Step3 設備A接收到Ack1,并將Buffer中的序列號為1(和之前的,包括TLP4094~TLP1)的TLP備份移除。同時將REPLAY_TIMER和REPLAY_NUM復位。
Example 3. Example of Nak
Step1 假設設備A準備依次向設備B發送序列號為4094,4095,0,1,2的TLP;
Step2 設備B成功地接受了TLP4094,并將NEXT_RCV_SEQ加1,變為4095;
Step3 設備B接收到了TLP4095,但是該TLP并未通過CRC校檢(即存在錯誤)。此時無論AckNak_LATENCY_TIMER處于何種狀態,設備B都會立即向設備A返回Ack4094(注意返回的Ack DLLP中的序列號為上一次成功接收的TLP的序列號)。同時設備B將AckNak_LATENCY_TIMER停止并復位;
Step4 設備B會一直等待設備A向其發送TLP4095,但是設備A卻并不知發生了什么,在接收到設備B向其返回的Ack/Nak之前,會繼續發送TLP0~TLP2,只是設備B會直接忽略這些TLP。
Step5 當設備A接收到來自設備B的Nak4094 DLLP時,會將Buffer中的TLP4094(和之前的TLP)移除,并從TLP4095從新開始發送。同時,將REPLAY_TIMER復位。
注:Mindshare書中,此處說還會復位REPLAY_NUM,這是不正確的。
Step6 由于設備A接收到的是Nak,而不是Ack,因此設備A會重新啟動REPLAY_TIMER并將REPLAY_NUM加一;
Step7 一旦設備B成功地接收到TLP4095,設備B便會清除NAK_SCHEDULED標志位,并將NEXT_RCV_SEQ計數器加一,同時重啟AckNak_LATENCY_TIMER。
Example 4. Example of Lost TLPs
Step1 假設設備A準備依次向設備B發送TLP 4094,4095,0,1,2;
Step2 設備B成功地接收了TLP4094~TLP0,并向設備A返回Ack0,此時設備B的NEXT_RCV_SEQ為1;
Step3 設備A接收到設備B返回的Ack0,從Buffer中移除相應的TLP備份;
Step4 設備B接收到了TLP2(而不是TLP1),也就是說TLP1在傳輸過程中丟失了。此時,設備B會直接將TLP2丟棄,并將NAK_SCHEDULED標志位置位,同時向設備A返回Nak0 DLLP;
Step5 設備A接收到Nak0 DLLP后,會將Buffer中的TLP0(以及之前的,如果有的話)移除。同時,從TLP1開始,重新向設備B發送。
Example 5. Example of Bad Nak
Step1 設備A準備依次向設備B發送TLP 4094,4095,0,1,2;
Step2 設備B成功的接收了TLP4094~TLP0,但是由于AckNak_LATENCY_TIMER尚未溢出,所以設備B沒有立即向設備A返回Ack DLLP;
Step3 設備B發現TLP1中存在錯誤,于是向設備A返回Nak0 DLLP,并將NAK_SCHEDULED標志位置位;
Step4 設備A發現其接收到的Nak0 DLLP中也存在錯誤(CRC校檢不通過),于是直接丟棄了Nak0;
Step5 然而設備B卻一直在等待設備A向其發送TLP1,在其成功接收TLP1之前,設備B不會返回任何Ack或者Nak,不管設備A向其發送什么(除TLP1之外的)。設備B的NAK_SCHEDULED標志位也一直保持置位;
Step6 尷尬的是,設備A并不知道設備B想要其重發TLP1(由于沒有成功接收到Nak0)。因此,設備A會繼續向設備B發送之后的TLP,但是由于一直沒有接收到設備B的Ack/Nak DLLP,設備A的REPLAY_TIMER會在一段時間后溢出;
Step7 當設備A的REPLAY_TIMER溢出后,設備A會向Buffer中的所有TLP都重新發送一遍,并重啟REPLAY_TIMER,同時將REPLAY_NUM計數器加一;
Step8 設備B會再次接收到TLP4094~TLP0,但是這在之前就已經成功接受到過了。因此設備B會直接將其丟棄,且不會像設備A返回任何的Ack或者Nak
Step9 此時,設備B再次接收到了TLP1,并未發現錯誤(成功接收)。于是,設備B將NAK_SCHEDULED標志位清零,并重啟AckNak_LATENCY_TIMER,將NEXT_RCV_SEQ加一。
-
計數器
+關注
關注
32文章
2253瀏覽量
94352 -
TLP
+關注
關注
0文章
32瀏覽量
15605
原文標題:【博文連載】PCIe掃盲——Ack/Nak 機制詳解(二)
文章出處:【微信號:ChinaAET,微信公眾號:電子技術應用ChinaAET】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論