本文為明德揚原創文章,轉載請注明出處!作者:小耀
光纖接口是FPGA比較常用的接口之一,它的傳輸方式與一些尋常接口的傳輸方式有些不同,為了讓大家了解光纖接口,并避免配置接口時的一些常見問題,我特意寫下了這個總結,希望能夠對大家有所幫助。
一、光纖接口的傳輸特點
大多數接口發送包文數據時會發送:數據data、有效指示信號data_vld、包文起始信號data_sop、包文結束信號data_eop以及無效字節數data_mty等。如下圖1所示。
圖1
光纖接口和上述接口發送的方式不同,光纖接口發送包文數據時只會發送數據txdata和K碼tx_k,內部讀取數據時也只會讀取數據rxdata和k碼rx_k。若數據(txdata、rxdata)為8字節,則k碼為8位數據。如下圖2所示。
圖2
二、k碼的表示
k碼是用來表示數據是否有效的,那么我們應該如何設定k碼呢?假設用下述方式表示k碼:
數據無效時:8’b0 ;
數據有效+SOP時:8’mty(4位mty)+0110 ;
數據有效+EOP時:8’mty(4位mty)+0011 ;
數據有效+其它時:8’mty(4位mty)+0010 ;
我們會發現數據會出現錯誤!因為數據和k碼在傳輸過程中可能會發生偏移!例如發送第一個數據時,txdata=64’h0102030405060708,tx_k=8’b00000110。
而內部接收時,數據可能會右移2位,造成接收到的數據與發送出的數據有所不同。如rxdata=64’h0000010203040506,rx_k=8’b000000001。即如下圖所示3。

圖3
因此,我們僅將k碼用做有效無效的指示信號以及同步信號,并用下述方式進行表示:
數據無效時,發送固定k碼:0x01,接收根據這個1的位置,判斷開始位;
數據有效時,發送固定k碼:0x00,接收根據k碼的值,識別數據是否有效。
在這種情況下,即使發生了偏移,我們也能知道k碼中1后面的8個0所對應的rxdata為有效數據。例如,第n個周期接收到rxdata=64’h00bc010203040506,接收到rx_k=8’b01000000,第n+1個周期接收到rxdata=64’h0708020304050607,接收到rx_k=8’b00000000。通過第n個周期rx_k中的1能夠判斷出后面8位0所對應的rxdata=64’h0102030405060708為有效數據。
三、比特位順序調換
我們先介紹一下小頭模式和大頭模式。小頭模式指的是低位在前高位在后,大頭模式指的是高位在前低位在后。例如同樣的數據012345678,在小頭模式中,0是最低位,8是最高位,在大頭模式中則0是最高位,8是最低位。由于光纖接口是小頭模式,而我們熟悉的是大頭模式。因此我們需要將光纖接口數據的比特位順序進行調換。
四、數據對齊
由于我們接收到的數據是偏移了的,因此我們需要利用一個模塊將光纖接口偏移的數據進行還原。例如,第n個周期接收到rxdata=64’h00bc010203040506,接收到rx_k=8’b01000000,第n+1個周期接收到rxdata=64’h0708020304050607,接收到rx_k=8’b00000000,我們通過對其模塊將其還原成第n個周期為rxdata=64’0102030405060708,rx_k=8’00000000即將下圖4變換成下圖5。
圖4

圖5
五、數據解包與打包
我們定義發送包文的方式是發送:55D5+16b長度+長度字節個DATA+校驗和。為了判斷是否接收有效包文,我們設定當接收到55D5時,表示后面的數據信號有效,接著接收數據的長度,表示該包文的有效長度,然后接收數據,最后再接收一個校驗位,檢驗包文是否有錯誤。
例如接收到8’h55+8’hd5 + 8’h00+8’h03 + 8’h12+8’hbc +8’h63 + 8’h00+ 8’h03 , 表示55d5后面的數據是包文,包文內數據一共有3個,數據分別是 8’h12、8’hbc、8’h63,最后檢驗位顯示一共有3個數據,包文正確。這樣我們就將一個有效包文解包成有效數據 8’h12、8’hbc、8’h63。
數據打包的過程與打包的過程正好相反,假如我們接收到5字節有效數據8’h12、8’hbc、8’h63、8’hbc、8’h63,我們需要將其打包成8’h55+8’hd5 + 8’h00+8’h05 + 8’h12+8’hbc +8’h63 + 8’hbc +8’h63 + 8’h00 +8’h05。
六、光纖串口的模塊
在接收端中,我們利用Rx_data_reverse模塊和Rx_ctrl_reverse模塊將輸入的rxdata和rx_k執行要點三的比特位順序調換操作,利用Rx_align模塊執行要點四的數據對齊操作,利用Decoder模塊執行有效數據的判斷,利用Unpackcomm模塊執行數據的解包操作。
在發送端中,我們利用packcommpack模塊將數據進行打包,再利用Tx_data_reverse模塊和Tx_ctrl_reverse模塊將數據從大頭模式還原成小頭模式,即再進行一次比特位順序的調換,然后再發送。