編 者 按
讀cocotbext-pcie源碼,有部分牽涉到數據鏈路層。雖然自工作以來接觸到PCIe還是蠻多的,但一般往往專注在TLP層,對于數據鏈路層還是接觸的比較少的。PCIe Spec洋洋灑灑數千頁,也不會從頭到尾去通讀整個協議。對于cocotbext-pcie里面牽涉到的鏈路層的ACK/NAK,牽涉到的PCIe背景,聊做記錄。
本文僅結合PCIe Spce與cocotbext-pcie做記錄。
》ACK/NAK
與TCP協議般,PCIe協議在數據鏈路層采用滑動窗口ACK/NAK協議來保證數據傳輸。對于傳輸層下發的TLP報文,數據鏈路層會做一次封裝:
ACK/NAK報文格式定義如下:
關于滑動窗口機制,往上隨便搜下還是蠻多的,不做過多啰嗦。鏈路層的滑動窗口正是基于TLP Sequence Number。
TLP Sequence Number定義為12 bits。對于發送端而言,其會維護兩個變量:
NEXT_TRANSMIT_SEQ:用于存儲下一個待發送TLP報文所使用的TLP Sequence Number。初始化時賦值為0.
ACKD_SEQ: 記錄從ACK、NAK中返回的 Sequence Number。初始化時賦值為0xfff。對于發送端,規定:(NEXT_TRANSMIT_SEQ - ACKD_SEQ) mod 4096 >= 2048
若上面的條件滿足則停止從傳輸層接收TLP,等待該條件不再成立。
也就意味著在pending中的報文不超過2048(牽涉到報文重傳)。
那么由此發送端對于收到的ACK/NAK中協議牽涉到的處理流程Spec定義為:
由于發送端窗口中pending待確認的報文不會超過2048,故若上面1式不成立,那么則意味著用到了尚未使用到的sequence,表示為錯誤的TLP報文,同樣單次增加的ACKD也不會超過2048,否則也應標為錯誤的TLP。
在式3中,如果條件不成立,則意味著可以窗口前移,可以從replay buffer中移出已發送成功的數據,設置ACKD_SEQ等變量。在cocotbext-pcie中關于dllp的處理也和spec保持一致:
而對于接收端,其定義了:
NEXT_RCV_SEQ:下一個待接收TLP的Sequence Number。
其處理流程為:
這里可以看到,僅當收到的TLP報文的Sequence Number等于NEXT_REC_SEQ時,才會被接收。注意紅框中,若條件滿足則認為是重復的報文,此時則應發送ACK DLLP報文,否則認為是錯誤的報文,則應發送NAK。
來看cocotbext-pcie中的處理:
這里在563行取了<而非<=,或可有誤。當收到的是期望的報文時(555行),則會更新next_recv_seq、清除nak_scheduled,拉起ack_latency_timer(不必每個TLP均發起一個ACK,但又要確保按照Spec中規定的間隔時間來發送ACK)。而如果收到的是一個重復的TLP(563行),此時將send_ack觸發條件拉起,表示要立即發送ACK,而同時關掉ack_latency_timer,避免超時條件觸發后多發ACK。否則(567行)將會發送NAK報文。
》One More Thing
關于接收端的ack_latency,協議中有詳細的規定,其與flow control定義有相似之處,放在后面結合cocotbext-pcie進行梳理。
審核編輯:劉清
-
接收機
+關注
關注
8文章
1223瀏覽量
54464 -
觸發器
+關注
關注
14文章
2039瀏覽量
62076 -
TLP
+關注
關注
0文章
34瀏覽量
16009 -
PCIe接口
+關注
關注
0文章
121瀏覽量
10108
原文標題:有點兒東西—PCIe鏈路層里的ACK/NAK
文章出處:【微信號:Spinal FPGA,微信公眾號:Spinal FPGA】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
CY7C65215A作為從站,在主站寫入時響應NAK是怎么回事?
nvme IP開發之PCIe上

【每日一知識點】在STM32F4上OTG 主機庫在 BULK 傳輸上對 NAK 的處理
介紹車用CAN通訊的基礎知識,數據鏈路層部分
一文詳解CXL鏈路層格式的定義
什么是ACK (ACKnowledge Character)
數據鏈路層到底是什么_數據鏈路層工作原理是怎樣的

PCIe總線的通信機制

Ack/Nak機制詳細介紹

簡單地分析幾個Ack/Nak機制的例子

評論