1、8B10B解決的問題
??8B10B編碼是1983年IBM公司提出的傳輸編碼標準,通常用于高速收發器中,常見的JESD204B、SATA等接口協議,使用查表就可以實現編碼和解碼。
??在這些高速收發器的接收端需要通過CDR技術去恢復時鐘與數據的相位關系,在這個過程中需要不斷的檢測數據邊沿和數據中心,從而調整時鐘和數據的相位,因此需要保證接收的數據需要不斷的變化,從而給CDR提供足夠多的待檢測數據邊沿。
??另外高速接口電路一般采用交流耦合方式進行連接,在交流耦合電路中的信號線會接電容(隔直通交),如果傳輸的數據在一段時間內全是1或全是0,那么這段時間傳輸的信號可以等效成直流信號,會產生直流偏移,在通過電容時,有可能解碼錯誤。
??因此通過8B10B編碼,保證編碼后的數據在一定時間內0的個數與1的個數保持相等。
2、8B10B編碼規則
??8B10B就是把8位數據編碼成10位數據,8位共有256種狀態,而10位數據有1024種狀態,可以從1024種狀態中選取256種0和1個數相等的數據作為編碼結果,在從剩下的數據中選取12個作為控制字符,即常見的K碼。
??如下圖所示,將輸入的8位數據分為高3位和低5位,分別進行3B4B、5B6B編碼,結果為10位數據。
??通常把編碼前的低5位數據EDCBA的十進制數值記為x,把編碼前的高3位數據HGF的十進制數值記為y,原始8位數據可以表示為D.x.y。
??比如待編碼數據為110_00011,高3位數據的十進制為6,低5位的十進制數據為3,則D.3.6就表示110_00011。
??常見的控制字符K.28.5的也是采用上述方式,控制字符的編碼結果是固定的,不會與數據的編碼結果沖突。
??低5位數據總共有32種狀態,對應的5B6B編碼規則如下表所示。
??下面是3B4B編碼的表格,原理與5B6B編碼一致。
??可能第一次看下表會有疑問,為什么D.00的編碼結果有兩種?RD又是什么東西?
??5位數據總共有32種狀態,編碼結果有6位數據,0和1數量相等的只有000_111、001_011…、110_001、111_000等20種狀態。其中000_111和111_000存在三個連續相同的狀態,并沒有被使用。導致編碼后0和1數據相等的結果就只有18種狀態,并不能滿足輸入5位數據的32種數據狀態,3B4B編碼也有同樣的問題。
??此時設計編碼的人提出,一次編碼如果不能保證編碼結果0和1個數相等,那么可以讓連續兩次編碼結果的0和1相等,也能滿足要求。
??極性偏差(running disparity,RD)用來記錄上一次編碼結果中0和1個數的多少。RD=-1表示編碼結果0多于1,RD=1表示編碼結果1多于0。
??如果編碼結果的1和0個數相等,稱為平衡編碼,此時RD的數值保持不變。如果編碼結果1和0個數不等,稱為非平衡編碼,此時RD的數值翻轉,下次編碼采用RD對應數值的編碼作為編碼結果。
??將上次8B10B編碼結果的RD數值用作本次5B6B編碼的起始RD,而3B4B編碼的起始RD等于5B6B編碼結果的RD,3B4B編碼結果的RD作為本次8B10B編碼的RD。
??對應的編碼狀態跳轉如下圖所示。
??通過這種方式才能保證一次編碼結果要么0和1個數相等,要么相差兩個。關于這方面的講述,網上絕大多數文章都是錯誤的,認為上次8B10B編碼結果的RD會作為下次5B6B和3B4B編碼的起始RD,造成3B4B編碼錯誤。
??上述講解的是數據編碼過程,因為8B10B編碼大多用于異步串行通信,接收方需要識別數據的幀頭、幀尾這些控制信息,從而完成數據的對齊、同步等等。
??因此8B10B編碼有12個控制字符,通常稱為K碼,這些控制字符的編碼結果是唯一的,不會與數據編碼的結果重復。下表就是12個控制字符的編碼。
??因為K碼的編碼結果是唯一的,因此接收端檢測K碼的方式很簡單,通過一組移位寄存器,將輸入數據依次移入,當移位寄存器的數值與K碼的編碼結果相同時,就認為檢測到對應K碼了,從而實現對應功能,包括逗號檢測、時鐘糾正、起始位、停止位等等。
3、8B10B編碼練習
??8B10B相關的理論講解就到此結束了,以兩個示例測試是否真的掌握該編碼,請問D.8.3的8B10B編碼結果是多少?
??由于起始RD并沒有明確指出,可能為1或者-1,所以會存在兩種編碼結果。
??首先RD=-1時,根據圖2得D.8的5B6B編碼結果為111001,5B6B編碼完成后,RD翻轉變為1。將RD=1作為D.x.3的3B4B編碼起始RD,根據圖3查表得編碼結果為0011,再次將RD翻轉作為本次8B10B編碼結果的RD。
??因此起始RD=-1的編碼結果為111001_0011,先輸出高位數據。
??當起始RD=1時,根據圖2得D.8的5B6B編碼結果為000110,RD翻轉作為3B4B起始RD,得D.x.3的3B4B編碼結果為1100,因此8B10編碼及熱鍋為000110_1100。
??怎么驗證上述計算是否正確呢?
??Xilinx的UG476手冊的附錄有所有8B10B編碼數據的結果,如下圖所示,起始RD=-1時,D.8.3編碼結果為111001_0011,起始RD=1時,D.8.3編碼結果為000110_1100,與上述計算結果保持一致,證明計算方法沒有問題。
??第二個問題,當前RD=1,則K.28.5、D.2.6、D.23.4的編碼結果依次是多少,且最終的RD是多少?
??首先RD=1時,通過圖5查得k.28.5編碼結果為110000_0101,然后RD保持不變,因為K28.5的5B6B和3B4B都是不平衡編碼,因此RD翻轉兩次的結果就是不變。
??因此D.2.6的起始RD=1,首先D.2的5B6B編碼結果為010010,RD翻轉變為-1。D.x.6的3B4B編碼結果為0110,由于D.x.6是平衡編碼,因此RD保持不變。
??故D.2.6的編碼結果為010010_0110,RD最終為-1。
??當RD=-1時,D.23.4的5B6B編碼結果為111010,然后RD翻轉為1。之后D.x.4的編碼結果為0010,RD的極性再次翻轉為-1。
??所以K.28.5、D.2.6、D.23.4的編碼結果依次是110000_0101、010010_0110、111010_0010,RD的最終取值為-1。D.2.6、D.23.4的查表結果如下圖所示,與上述計算結果保持相同,證明編碼規則沒有問題。
??從上述編碼過程可知,每個輸入數據通過查表都可以得到其唯一的編碼結果,根據編碼結果也可以查表反推進行解碼,所以實現這個編碼和解碼的思路比較簡單,直接使用查表法即可。
??通過上述編碼也可以很清晰知道該編碼的缺陷,每次傳輸的10位數據中有2位是無效數據,損耗比較大。后續的64B66B編碼就是為了解決這個問題提出的,但是8B10B編碼的誤碼率會比64B66B編碼低。
??關于8B10B編碼內容講解就到此結束了,本來最開始是不想寫這方面內容的,結果在CSDN和B站看到很多大佬對RD極性變化的理解都有問題,編碼結果與官方提供的結果都不相同,因此寫了這篇文章,希望對大家的理解有幫助。