SFP光口傳輸設(shè)計(jì))
做了這么多年FPGA圖像接口CameraLink算是工業(yè)相機(jī)里最常打交道的接口之一但它有個(gè)天生短板傳輸距離實(shí)在有限。普通CameraLink線纜在Base配置下5米以外信號(hào)就開(kāi)始提心吊膽更別說(shuō)幾十米、上百米的場(chǎng)景。這時(shí)候最實(shí)用的思路就是加一道轉(zhuǎn)換把CameraLink相機(jī)信號(hào)接入FPGA在FPGA里完成數(shù)據(jù)打包和高速收發(fā)最終通過(guò)SFP光口送出去。這樣既保留了CameraLink相機(jī)的現(xiàn)有投資又能把傳輸距離一下子拉到幾百米甚至幾公里。這篇文章就是圍繞一個(gè)典型的“FPGA實(shí)現(xiàn)CameraLink轉(zhuǎn)SFP光口”項(xiàng)目展開(kāi)的。工程核心是基于Xilinx 7系列FPGA的GT Transceivers Wizard加Aurora 8B10B編解碼架構(gòu)最終形成4套可參考復(fù)現(xiàn)的工程源碼。我把自己從頭到尾的設(shè)計(jì)思路、IP配置、容易栽的坑、調(diào)試方法都整理出來(lái)適合正在做圖像遠(yuǎn)傳、機(jī)器視覺(jué)接口轉(zhuǎn)換、或者想上手Aurora協(xié)議但不知道怎么跟具體圖像格式對(duì)接的工程師參考。如果你是想評(píng)估方案可行性這篇也能幫你把技術(shù)鏈路里每一處關(guān)鍵決策都弄明白。1. 整體架構(gòu)與方案選型為什么偏偏是Aurora 8B10B在動(dòng)手寫(xiě)代碼之前最難的部分其實(shí)是架構(gòu)決策。攝像頭端是CameraLink遠(yuǎn)端是SFP光口FPGA夾在中間做翻譯。翻譯這件事聽(tīng)起來(lái)簡(jiǎn)單但選擇哪種高速串行協(xié)議直接決定了工程量、延遲、通用性和后續(xù)維護(hù)成本。1.1 CameraLink的傳輸瓶頸到底卡在哪先理解一下CameraLink本身。它在物理層用的是Channel Link技術(shù)Base配置下就是一組5對(duì)LVDS差分線其中1對(duì)時(shí)鐘、4對(duì)數(shù)據(jù)。并行側(cè)是28位數(shù)據(jù)位加4位同步信號(hào)接收芯片比如DS90CR288A把它解串成TTL并行信號(hào)給FPGA。像素時(shí)鐘越高LVDS線速率也越高比如85MHz像素時(shí)鐘下每對(duì)LVDS大約跑595Mbps。問(wèn)題在于LVDS在普通線纜上的高頻衰減很厲害。工業(yè)上常用CameraLink線纜做到5到10米已經(jīng)算不錯(cuò)如果環(huán)境有電機(jī)、變頻器干擾距離還要打折。而很多產(chǎn)線場(chǎng)景相機(jī)和控制室之間隔著幾十米或者相機(jī)裝在高架機(jī)器人上、處理主機(jī)在地面柜子里這時(shí)候把CameraLink變成光口是比換GigE相機(jī)更省事的選擇——相機(jī)不用換鏡頭視角、觸發(fā)方式、幀率特性全部不變變的只是中間的物理傳輸層。1.2 為什么用Aurora而不是UDP、PCIe或者SRIO很多朋友一聽(tīng)到“圖像遠(yuǎn)傳”第一個(gè)想到的是萬(wàn)兆以太網(wǎng)加UDP。但實(shí)際上在這個(gè)項(xiàng)目里需求是“點(diǎn)對(duì)點(diǎn)透明傳輸CameraLink時(shí)序”不是“把圖像打包成標(biāo)準(zhǔn)網(wǎng)絡(luò)包發(fā)給任意PC”。如果用UDP需要處理MAC、ARP、IP、UDP校驗(yàn)還要在遠(yuǎn)端解析重組且每一個(gè)環(huán)節(jié)都對(duì)端到端延遲有額外貢獻(xiàn)。CPU/ARM參與還得考慮協(xié)議棧調(diào)度問(wèn)題。Aurora 8B10B是Xilinx提供的免費(fèi)點(diǎn)對(duì)點(diǎn)鏈路層協(xié)議直接在GT高速收發(fā)器上跑。它解決的正是“我不管上面?zhèn)魇裁次抑回?fù)責(zé)把一堆字節(jié)可靠地從A送到B”這個(gè)問(wèn)題。它的開(kāi)銷(xiāo)非常小8B10B編碼自帶DC平衡和游程長(zhǎng)度控制物理上適合光模塊傳輸而且Xilinx IP核把鏈路初始化、通道對(duì)齊、錯(cuò)誤檢測(cè)都做好了用戶接口就是一個(gè)帶流控的簡(jiǎn)單總線。你要做的只是把CameraLink的圖像數(shù)據(jù)按時(shí)序塞進(jìn)這個(gè)總線另一端再取出來(lái)重建時(shí)序。在這個(gè)場(chǎng)景下SRIO和PCIe也不是不能用但它們的協(xié)議更重面向的是多設(shè)備尋址、DMA、多通道交換這些復(fù)雜特性。點(diǎn)對(duì)點(diǎn)傳圖像屬于殺雞用牛刀而且調(diào)試難度和耗時(shí)明顯更高。1.3 四套工程源碼各自解決什么階段的問(wèn)題項(xiàng)目標(biāo)題里寫(xiě)了“提供4套工程源碼”這也符合我自己的交付習(xí)慣。正常情況下我不會(huì)只給一套寫(xiě)完的工程因?yàn)橐惶坠こ虩o(wú)法覆蓋從驗(yàn)證到量產(chǎn)的所有場(chǎng)景。這4套的分工大致是這樣第一套用于硬件回環(huán)測(cè)試不接相機(jī)先在FPGA內(nèi)部產(chǎn)生測(cè)試數(shù)據(jù)發(fā)給GT自收自發(fā)確認(rèn)光口物理層、GT配置、SFP模塊沒(méi)有問(wèn)題。第二套是最小化的CameraLink Base轉(zhuǎn)SFP單向傳輸工程去掉一切花哨功能透明搬運(yùn)圖像數(shù)據(jù)和同步信號(hào)適合作為方案驗(yàn)證和二次開(kāi)發(fā)的基座。第三套在第二套基礎(chǔ)上把圖像打包格式做成可配置兼容不同像素位寬、行場(chǎng)同步極性和分辨率方便接不同型號(hào)的CameraLink相機(jī)。第四套是面向“遠(yuǎn)端需要一個(gè)標(biāo)準(zhǔn)CameraLink Source輸出”的完整收發(fā)工程把光口接收的數(shù)據(jù)重新還原成CameraLink并行時(shí)序給后端的采集卡或者顯示設(shè)備使用。這四套是遞進(jìn)關(guān)系也是排錯(cuò)隔離的關(guān)系。真到了現(xiàn)場(chǎng)出問(wèn)題先用第一套確認(rèn)鏈路再用第二套確認(rèn)圖像最后才去查第三、四套里的配置兼容性問(wèn)題能省下大量瞎猜的時(shí)間。2. CameraLink信號(hào)進(jìn)入FPGA之后數(shù)據(jù)流設(shè)計(jì)才是重頭戲硬件方案定了IP選型定了很多人會(huì)覺(jué)得剩下的事情就是把數(shù)據(jù)從A口搬到B口。但圖像數(shù)據(jù)遠(yuǎn)傳最忌諱的就是把它當(dāng)成普通字節(jié)流直接扔出去。CameraLink不只是像素?cái)?shù)據(jù)它還有FVAL、LVAL、DVAL三根同步信號(hào)。遠(yuǎn)端要把圖像還原成相機(jī)時(shí)序必須知道每一行從哪里開(kāi)始、每一幀從哪里開(kāi)始、像素什么時(shí)候有效。2.1 接收芯片后面的并行時(shí)序怎么理解以最常見(jiàn)的Base配置為例FPGA從DS90CR288A這類(lèi)芯片拿到的是pDATA[27:0]、FVAL、LVAL、DVAL、像素時(shí)鐘。這些信號(hào)本質(zhì)上和相機(jī)內(nèi)部的時(shí)序一致。FVAL拉高表示一幀有效LVAL拉高表示一行有效DVAL則根據(jù)配置表示數(shù)據(jù)是否有效有些相機(jī)不用DVAL直接用LVAL對(duì)齊數(shù)據(jù)。這里有個(gè)細(xì)節(jié)CameraLink的像素?cái)?shù)據(jù)不是簡(jiǎn)單按字節(jié)排的。8位、10位、12位、16位像素在pDATA上的位寬映射不一樣多tap相機(jī)的排列規(guī)則更復(fù)雜。如果FPGA端嘗試“理解”像素排列比如去做Bayer插值、RGB轉(zhuǎn)換就必須處理一堆廠商差異。所以在這個(gè)轉(zhuǎn)光口設(shè)計(jì)里我的原則是不解析語(yǔ)義只搬運(yùn)時(shí)序。FPGA不知道圖像是黑白還是彩色也不管像素是10位還是12位它只確保一件事件遠(yuǎn)端恢復(fù)出來(lái)的pDATA每一位、每一拍的相對(duì)關(guān)系和發(fā)送端進(jìn)來(lái)的完全一致。2.2 打包格式怎么設(shè)計(jì)才能做到透明既然要透明就得設(shè)計(jì)一種打包格式。簡(jiǎn)單粗暴地把pDATA連續(xù)存入FIFO然后讓Aurora讀走是可以跑的但一旦中間丟了一個(gè)字節(jié)或者鏈路重同步遠(yuǎn)端永遠(yuǎn)不知道哪里是行頭、哪里是幀頭圖像會(huì)徹底花掉且無(wú)法自動(dòng)恢復(fù)。我的做法是“行打包”。每當(dāng)檢測(cè)到LVAL上升沿開(kāi)始把這一行有效的像素?cái)?shù)據(jù)存起來(lái)LVAL拉低代表這一行結(jié)束之后把這一行數(shù)據(jù)加上自定義的行頭組成一個(gè)Aurora幀發(fā)送出去。行頭里包含幀計(jì)數(shù)、行計(jì)數(shù)、該行有效數(shù)據(jù)長(zhǎng)度、以及原始同步信號(hào)的極性標(biāo)志。FVAL本身不需要單獨(dú)打包行計(jì)數(shù)為0的那一行就代表新的一幀開(kāi)始。這樣傳輸鏈路只關(guān)心“幀”不關(guān)心“行內(nèi)數(shù)據(jù)到底長(zhǎng)什么樣”目的端的恢復(fù)模塊根據(jù)行頭重建FVAL和LVAL即可。8B10B編碼本身并不能保證幀邊界Aurora協(xié)議層能保證字節(jié)流可靠傳輸?shù)粫?huì)自己劃分“這一坨是一行圖像”。所以自定義行頭是必須的這也是整個(gè)工程里最有價(jià)值的設(shè)計(jì)之一。幀計(jì)數(shù)和行計(jì)數(shù)主要用來(lái)在遠(yuǎn)端做連續(xù)性校驗(yàn)一旦發(fā)現(xiàn)幀號(hào)斷裂說(shuō)明鏈路出現(xiàn)瞬時(shí)錯(cuò)誤把輸出同步信號(hào)復(fù)位重來(lái)避免一直帶著錯(cuò)位圖像跑下去。2.3 異步FIFO的深度與反壓處理CameraLink側(cè)的像素時(shí)鐘來(lái)自接收芯片可能正好是某顆晶振分頻出來(lái)的而Aurora側(cè)的發(fā)送時(shí)鐘來(lái)自于GT的用戶時(shí)鐘兩者頻率不可能天然一致。所以發(fā)送端必須先做異步FIFO隔離輸入側(cè)用像素時(shí)鐘寫(xiě)輸出側(cè)用Aurora用戶時(shí)鐘讀。FIFO深度要按“峰值積壓量”來(lái)算。最壞情況是連續(xù)幾行數(shù)據(jù)在短時(shí)間內(nèi)涌入但Aurora側(cè)因?yàn)殒溌妨骺貢簳r(shí)不能讀。實(shí)際工程里我一般深度做到4096到16384之間寬度做到32位或64位滿足Full HD分辨率下的多行緩沖。不推薦把FIFO做到上百KB因?yàn)槿绻霈F(xiàn)這種積壓說(shuō)明帶寬預(yù)算或者反壓邏輯根本不合格堆再深也只是掩耳盜鈴。反壓是另一個(gè)容易翻車(chē)的地方。Aurora用戶接口的發(fā)送端有ready信號(hào)如果對(duì)端還沒(méi)來(lái)得及接收本端就不能繼續(xù)送數(shù)據(jù)。但CameraLink是連續(xù)時(shí)鐘不會(huì)等FPGA準(zhǔn)備好所以FIFO讀使能必須由Aurora發(fā)送狀態(tài)機(jī)來(lái)控制。一旦ready為低立刻停止讀FIFO但輸入側(cè)還在繼續(xù)寫(xiě)此時(shí)如果FIFO滿了就必須丟棄新的像素并拉高一個(gè)溢出標(biāo)志。這個(gè)標(biāo)志一定要引出到LED或者調(diào)試寄存器不能悄悄吞掉。3. GT Transceivers Wizard與Aurora IP配置要點(diǎn)工程里用到Xilinx 7系列FPGA就繞不開(kāi)GT Transceivers Wizard和Aurora 8B10B這兩個(gè)IP。很多人以為自己只是“調(diào)個(gè)IP”但這兩個(gè)IP其實(shí)是整個(gè)系統(tǒng)里最需要理解物理含義的部分。配置錯(cuò)一個(gè)參考時(shí)鐘頻率或者排錯(cuò)GT位置上板后鏈路死活拉不起來(lái)。3.1 線速率和參考時(shí)鐘怎么選才合適線速率的選取取決于有效數(shù)據(jù)帶寬。CameraLink Base在85MHz像素時(shí)鐘下并行側(cè)理論帶寬大約是85M × 28bit ≈ 2.38Gbps但這是把所有信號(hào)位都算進(jìn)去了。實(shí)際圖像有效數(shù)據(jù)率取決于分辨率、幀率、消隱時(shí)間。比如1280×102460fps灰度8bit有效像素率大約78.6M pixels/s有效帶寬約0.63Gbps加上同步打包、8B10B編碼25%開(kāi)銷(xiāo)也要留一定裕量。實(shí)際工程里我習(xí)慣直接選2.5Gbps或者3.125Gbps。2.5G是很多SFP光模塊的舒適區(qū)3.125G則對(duì)應(yīng)常見(jiàn)的156.25MHz參考時(shí)鐘。Aurora 8B10B會(huì)在用戶接口產(chǎn)生一個(gè)用戶時(shí)鐘線速率和用戶時(shí)鐘的關(guān)系取決于IP核內(nèi)部選擇的總線寬度常見(jiàn)的是線速率/16或者線速率/32。對(duì)應(yīng)下來(lái)2.5G線速率配125MHz參考時(shí)鐘得到約156.25MHz的用戶時(shí)鐘3.125G線速率配156.25MHz參考時(shí)鐘得到約195.3125MHz的用戶時(shí)鐘。需要說(shuō)明的是以上是常見(jiàn)搭配具體數(shù)值以IP配置界面實(shí)際生成的時(shí)鐘約束為準(zhǔn)。參考時(shí)鐘必須是GT專(zhuān)用引腳引入不能隨意接到普通IO上。很多開(kāi)發(fā)板板載125MHz或者156.25MHz的MGT參考時(shí)鐘選型時(shí)先看原理圖確定SFP光模塊的GT所在的Bank用了哪一路參考時(shí)鐘再回過(guò)來(lái)在GT Wizard和Aurora IP里填對(duì)應(yīng)頻率。別想當(dāng)然地認(rèn)為開(kāi)發(fā)板上那個(gè)SFP一定能用任意參考時(shí)鐘我在一個(gè)板子上見(jiàn)過(guò)SFP的GT參考時(shí)鐘被設(shè)計(jì)成只能從某個(gè)特定Bank輸入結(jié)果那個(gè)Bank被其它接口占用最后只能改板子或者換工程。3.2 Aurora IP核內(nèi)部選項(xiàng)的坑Aurora 8B10B有兩個(gè)大方向Streaming接口和Frame接口。Streaming模式下用戶側(cè)是一個(gè)連續(xù)數(shù)據(jù)流沒(méi)有幀邊界適合純字節(jié)流傳輸。Frame接口則會(huì)識(shí)別SOF和EOF對(duì)應(yīng)我們打包模塊里的幀起始和幀結(jié)束。圖像傳輸我建議選Frame接口雖然多一個(gè)TLAST信號(hào)需要處理但語(yǔ)義更清晰遠(yuǎn)端也能明確知道一幀從哪開(kāi)始。另一個(gè)容易忽略的是“Little Endian”和“Flow Control”選項(xiàng)。Aurora協(xié)議本身可以配置數(shù)據(jù)位寬和字節(jié)序如果你的發(fā)送側(cè)是64位數(shù)據(jù)總線、接收側(cè)是32位這種不對(duì)稱(chēng)設(shè)計(jì)會(huì)讓IP核配置復(fù)雜很多。我的做法是兩端工程保持一致64位就都是64位32位就都是32位寧可多個(gè)bit拼接邏輯也不做端到端位寬轉(zhuǎn)換。Flow Control我一般直接關(guān)掉。Aurora的流控用于告訴對(duì)端“我暫時(shí)收不了”但圖像傳輸要求實(shí)時(shí)性一旦打開(kāi)了流控并且對(duì)端FIFO將滿它會(huì)插入空閑周期表面看數(shù)據(jù)不丟實(shí)際上延遲發(fā)生抖動(dòng)遠(yuǎn)端恢復(fù)出來(lái)的CameraLink時(shí)序就會(huì)不穩(wěn)定。正確做法是在應(yīng)用層配置足夠的緩沖確保任何情況下不會(huì)因?yàn)樗矔r(shí)帶寬抖動(dòng)丟數(shù)據(jù)。3.3 復(fù)位與初始化時(shí)序到底應(yīng)該怎么處理GT和Aurora初始化有自己的時(shí)序要求。7系列GT上電后需要給gt_rxreset、gt_txreset一個(gè)適當(dāng)?shù)拿}沖等待pll_lock、txresetdone、rxresetdone拉高。Aurora IP核內(nèi)部管理了一部分復(fù)位但用戶側(cè)的reset通常要跟gt_reset_done信號(hào)配合。如果直接在Vivado里把reset引腳接到固定高電平或者用一個(gè)很短的脈沖硬件回環(huán)可能正常但接上光模塊后可能一小時(shí)都不出一次問(wèn)題。正確做法是做一個(gè)上電復(fù)位延時(shí)模塊在配置完成后延時(shí)50到100ms再釋放Aurora復(fù)位確保SFP光模塊的電源穩(wěn)定。Aurora初始化完成以channel_up信號(hào)拉高為準(zhǔn)只有channel_up為高之后才能讓圖像數(shù)據(jù)進(jìn)入發(fā)送端狀態(tài)機(jī)。在channel_up拉低期間發(fā)送端的FIFO最好保持在復(fù)位狀態(tài)避免數(shù)據(jù)已經(jīng)讀出但并沒(méi)能送出去導(dǎo)致遠(yuǎn)端圖像缺行。這部分的調(diào)試經(jīng)驗(yàn)是把channel_up、lane_up、gt_pll_lock這些狀態(tài)信號(hào)全部引到ILA或者板上LED。不要只盯著最終的圖像鏈路狀態(tài)是排錯(cuò)的第一級(jí)入口。4. 核心模塊怎么拆發(fā)送狀態(tài)機(jī)與接收恢復(fù)邏輯4套工程源碼的代碼組織我采用清晰的模塊劃分方便直接復(fù)用。頂層之下CameraLink接收與打包邏輯、Aurora收發(fā)Wrapper、遠(yuǎn)端恢復(fù)邏輯、寄存器配置接口各自獨(dú)立。每個(gè)模塊之間的接口如果定義得足夠干凈后續(xù)更換FPGA型號(hào)或者調(diào)整分辨率就是改參數(shù)的事。4.1 發(fā)送端狀態(tài)機(jī)與自定義行頭結(jié)構(gòu)發(fā)送端的狀態(tài)機(jī)大概是這樣的等待FVAL和LVAL同時(shí)有效開(kāi)始把pDATA寫(xiě)入行緩沖FIFOLVAL拉低后停止寫(xiě)入然后檢測(cè)Aurora用戶接口是否可發(fā)送可發(fā)送則先發(fā)送一個(gè)行頭再連續(xù)發(fā)送該行數(shù)據(jù)。行頭的位寬與數(shù)據(jù)總線對(duì)齊例如在64位總線下我會(huì)用兩個(gè)周期發(fā)送一個(gè)128位的行頭。行頭里的字段可以劃分為幀計(jì)數(shù)、行計(jì)數(shù)、數(shù)據(jù)有效字長(zhǎng)、同步極性標(biāo)志、校驗(yàn)字段。如果用戶總線和像素位寬不是整數(shù)倍關(guān)系還需要在行尾做bit對(duì)齊由打包模塊完成右填充或左對(duì)齊。這里要注意的是LVAL拉低不等于下一行數(shù)據(jù)不會(huì)立刻到來(lái)。有些相機(jī)的行消隱非常短只有幾個(gè)像素時(shí)鐘周期發(fā)送狀態(tài)機(jī)必須能在幾拍之內(nèi)完成從“上一行收尾”到“下一行行頭開(kāi)始”的切換。所以我自己不傾向用復(fù)雜的AXI DMA搬移方式而是簡(jiǎn)單的乒乓FIFO一行寫(xiě)入FIFO A的同時(shí)狀態(tài)機(jī)正在發(fā)送上一行FIFO B里的內(nèi)容兩個(gè)FIFO在LVAL邊界處互換角色。這樣有效避開(kāi)了“同一塊FIFO還在讀又不能寫(xiě)”的死鎖問(wèn)題也保證了突發(fā)連續(xù)性。4.2 接收端如何重建CameraLink時(shí)序光口遠(yuǎn)端拿到的是打包后的數(shù)據(jù)第一步從Aurora Frame接口恢復(fù)出數(shù)據(jù)幀解析行頭驗(yàn)證幀計(jì)數(shù)和行計(jì)數(shù)連續(xù)然后進(jìn)入行緩存恢復(fù)模塊?;謴?fù)模塊按行頭里記錄的該行長(zhǎng)度把有效數(shù)據(jù)依次寫(xiě)入輸出FIFO。輸出側(cè)的同步信號(hào)生成邏輯需要產(chǎn)生一個(gè)模擬的像素時(shí)鐘或者直接使用一個(gè)相對(duì)穩(wěn)定的本地時(shí)鐘然后按照行頭參數(shù)生成LVAL、FVAL。這一段的難點(diǎn)在于“行頭里沒(méi)有絕對(duì)時(shí)間信息”只有行長(zhǎng)度。如果遠(yuǎn)端本地時(shí)鐘和發(fā)送端像素時(shí)鐘有微小頻差時(shí)間一長(zhǎng)FIFO會(huì)溢出或者讀空。實(shí)際工程我在恢復(fù)側(cè)使用一個(gè)可動(dòng)態(tài)調(diào)整的FIFO讀使能機(jī)制當(dāng)FIFO水位超過(guò)半滿說(shuō)明本地時(shí)鐘慢了下一行的LVAL寬度可以稍微調(diào)整一兩個(gè)時(shí)鐘周期當(dāng)FIFO水位低于某個(gè)閾值說(shuō)明本地時(shí)鐘快了下一行可以插入一個(gè)等待周期。這種做法本質(zhì)上是時(shí)鐘速率適配嚴(yán)格來(lái)說(shuō)會(huì)讓恢復(fù)的LVAL在極少數(shù)時(shí)候比原始行長(zhǎng)度多或少幾個(gè)周期但對(duì)于普通采集卡和顯示器來(lái)說(shuō)完全無(wú)感。如果要做到嚴(yán)格精確的時(shí)序恢復(fù)需要遠(yuǎn)端用CDR恢復(fù)出來(lái)的時(shí)鐘作為像素時(shí)鐘。這要求相機(jī)側(cè)發(fā)送的不是純異步數(shù)據(jù)而是跟GT參考時(shí)鐘有一定相位關(guān)聯(lián)??上Ы^大多數(shù)CameraLink相機(jī)并不同步于FPGA的GT時(shí)鐘所以實(shí)際工程里最穩(wěn)妥的仍然是“異步FIFO加水位自適應(yīng)”方案。4.3 回環(huán)測(cè)試工程怎么測(cè)才算有效第一套源碼是回環(huán)測(cè)試工程。它做了兩件事內(nèi)部生成PRBS或者固定遞增數(shù)據(jù)送給Aurora發(fā)送數(shù)據(jù)從光口出去之后再接一根光纖跳線回到同一個(gè)SFP模塊的接收端Aurora收到的數(shù)據(jù)送還給校驗(yàn)?zāi)K實(shí)時(shí)比對(duì)數(shù)據(jù)是否一致。這套工程的價(jià)值在于把GT物理層、SFP模塊、光纖、Aurora鏈路這些問(wèn)題先隔離掉。如果回環(huán)測(cè)試計(jì)數(shù)一直增長(zhǎng)不上來(lái)大概率是硬件鏈路或者IP配置的問(wèn)題跟圖像邏輯無(wú)關(guān)。實(shí)際測(cè)試不要只測(cè)幾分鐘最好連續(xù)跑12小時(shí)以上并讓誤碼計(jì)數(shù)器清零后不再增長(zhǎng)才算穩(wěn)定。回環(huán)測(cè)試也可以用光衰減器串在鏈路中間測(cè)試靈敏度這能提前發(fā)現(xiàn)SFP模塊質(zhì)量差或者在臨界光功率下工作的問(wèn)題。5. 上板調(diào)試實(shí)錄鏈路、圖像、長(zhǎng)時(shí)間運(yùn)行的坑流程走到這里理論上該出圖了。但實(shí)際調(diào)試過(guò)程中我?guī)缀鯖](méi)有遇到過(guò)“一把過(guò)”的情況。這里把最常見(jiàn)的幾類(lèi)問(wèn)題和排查思路整理出來(lái)遇到同樣問(wèn)題的朋友可以直接按順序查。5.1 channel_up一直拉不高的排查路線如果檢查了光模塊插緊、光纖跳線正常、電源正常channel_up仍然為低先不要懷疑Aurora IP應(yīng)該從GT層開(kāi)始查。第一看gt_pll_lock是否為高如果為低說(shuō)明GT參考時(shí)鐘沒(méi)有進(jìn)來(lái)或者頻率配置不對(duì)第二看tx_resetdone和rx_resetdone是否拉高如果沒(méi)拉高多半是GT復(fù)位時(shí)序不對(duì)第三看光模塊的RX_LOS信號(hào)如果這個(gè)信號(hào)為高說(shuō)明接收光功率太低檢查光纖是否接反、對(duì)端是否有光發(fā)出。一個(gè)很常見(jiàn)的坑是SFP模塊選型。很多千兆SFP模塊只支持1.25Gbps你在GT Wizard里配了2.5Gbps模塊內(nèi)部電路并不能工作在這個(gè)速率上。有朋友把支持10G的SFP模塊插到只提供3.3V電源的普通SFP座子上也可能無(wú)法正常工作。選模塊前務(wù)必查清楚規(guī)格書(shū)能否支持你選的線速率是不是需要特殊驅(qū)動(dòng)電流。還有一次我遇到的問(wèn)題非常隱蔽光纖跳線是單模的而SFP模塊是多模850nm的單模跳線內(nèi)芯更細(xì)多模模塊雖然能發(fā)光但接收端無(wú)法穩(wěn)定耦合到多模光纖的纖芯模式導(dǎo)致channel_up反復(fù)掉線。換一根多模跳線后問(wèn)題立刻消失。5.2 圖像錯(cuò)位、偏色、邊緣有雜色的排查如果channel_up正常但遠(yuǎn)端采集到的圖像左右錯(cuò)位、上下滾動(dòng)、顏色不對(duì)問(wèn)題最可能在打包或恢復(fù)的時(shí)序處理上。先說(shuō)錯(cuò)位。逐行掃描時(shí)行頭里記錄的長(zhǎng)度如果和實(shí)際像素長(zhǎng)度不一致遠(yuǎn)端恢復(fù)就會(huì)把行起始位置搞錯(cuò)。排查方法是在相機(jī)前放一個(gè)明顯非對(duì)稱(chēng)的測(cè)試圖比如左邊純白右邊純黑看看圖像里黑白的邊界是否在預(yù)期位置。如果有固定偏移說(shuō)明行頭長(zhǎng)度或LVAL邊沿識(shí)別邏輯有問(wèn)題如果錯(cuò)位是逐行累加的說(shuō)明恢復(fù)側(cè)丟行或者重復(fù)行檢查發(fā)送狀態(tài)機(jī)的幀計(jì)數(shù)和行計(jì)數(shù)。偏色問(wèn)題一般有兩種原因一是發(fā)送端的并行數(shù)據(jù)位序與遠(yuǎn)端采集端的像素位寬映射不一致比如12位像素時(shí)高4位和低8位的排列順序錯(cuò)了二是同步信號(hào)極性配置不正確導(dǎo)致采集端把無(wú)效數(shù)據(jù)當(dāng)有效數(shù)據(jù)。排查偏色我通常用ColorBar測(cè)試圖哪種顏色錯(cuò)亂可以反推出具體是哪個(gè)bit翻轉(zhuǎn)。比如綠色通道掉了多半是某根數(shù)據(jù)位虛焊或者代碼位寬拼接錯(cuò)了。5.3 長(zhǎng)時(shí)間運(yùn)行后偶發(fā)丟幀、花屏的根治辦法前面兩個(gè)問(wèn)題都算能穩(wěn)定復(fù)現(xiàn)的問(wèn)題真正難查的是“跑兩小時(shí)后突然花一幀然后自己恢復(fù)”。這種問(wèn)題大概率出在異步FIFO邊界或者誤碼沒(méi)有有效糾正上。異步FIFO的讀寫(xiě)指針跨時(shí)鐘域如果處理不好偶爾會(huì)出現(xiàn)讀到一個(gè)尚未寫(xiě)入的無(wú)效數(shù)據(jù)。8B10B編碼能檢測(cè)到線路誤碼但Aurora協(xié)議對(duì)于誤碼的處理如果配置不當(dāng)可能會(huì)讓錯(cuò)誤數(shù)據(jù)直接上行。解決思路是在自定義行頭里加上CRC或者簡(jiǎn)單的校驗(yàn)和接收端一旦發(fā)現(xiàn)校驗(yàn)錯(cuò)誤就丟棄整行并標(biāo)記幀計(jì)數(shù)異常由輸出恢復(fù)狀態(tài)機(jī)在下一幀重新同步。這樣偶發(fā)的單bit誤碼不會(huì)導(dǎo)致長(zhǎng)時(shí)間的花屏。鏈路長(zhǎng)時(shí)間運(yùn)行的另一個(gè)隱患是GT溫度漂移。如果FPGA散熱不好GT的RX抖動(dòng)性能會(huì)下降誤碼率逐步上升。我碰到過(guò)一個(gè)項(xiàng)目回環(huán)測(cè)試只測(cè)了兩個(gè)小時(shí)沒(méi)問(wèn)題上到產(chǎn)線跑八小時(shí)后開(kāi)始冒錯(cuò)。后來(lái)加了一個(gè)風(fēng)扇強(qiáng)制風(fēng)冷并把GT的RX均衡參數(shù)從默認(rèn)值調(diào)高一檔問(wèn)題解決。不要忽視FPGA芯片上GT附近的散熱設(shè)計(jì)光模塊本身也是發(fā)熱大戶FPGA和SFP緊挨著布局時(shí)更要仔細(xì)評(píng)估熱區(qū)。6. 四套源碼怎么選、怎么快速跑出第一張圖幫別人評(píng)估這類(lèi)“FPGA實(shí)現(xiàn)CameraLink轉(zhuǎn)SFP”方案時(shí)我經(jīng)常被問(wèn)到這幾套源碼我該先看哪個(gè)其實(shí)答案很簡(jiǎn)單按順序來(lái)。6.1 四套工程的適用場(chǎng)景和選擇建議第一套回環(huán)測(cè)試工程是最先應(yīng)該上板的。它和相機(jī)無(wú)關(guān)和圖像格式無(wú)關(guān)只驗(yàn)證FPGA到光模塊到光纖到光模塊到FPGA這條物理鏈路。這套工程跑通了后續(xù)問(wèn)題就可以縮小到圖像側(cè)邏輯。第二套最小化單向傳輸工程適合第一次接觸這塊方案的人它把打包和恢復(fù)邏輯做到最簡(jiǎn)單能幫你建立“圖像數(shù)據(jù)是這樣從一側(cè)到另一側(cè)”的完整認(rèn)知。第三套可配置工程適合要對(duì)齊多種相機(jī)、多種分辨率的生產(chǎn)環(huán)境我會(huì)在里面實(shí)現(xiàn)了寄存器接口用來(lái)配置行長(zhǎng)度、行頭模式、同步極性、數(shù)據(jù)位寬拼接方式。第四套完整收發(fā)工程則是面向最終產(chǎn)品形態(tài)的遠(yuǎn)端需要重建標(biāo)準(zhǔn)CameraLink Source并行時(shí)序時(shí)用它加入了輸出時(shí)鐘管理與自適應(yīng)FIFO邏輯。在實(shí)際項(xiàng)目里我的推進(jìn)路線一定是從第一套開(kāi)始確認(rèn)硬件鏈路后在第二套基礎(chǔ)上改到需要的分辨率和幀率然后切到第三套做參數(shù)配置最終固化到第四套作為交付。不要一上來(lái)就抱著第四套工程調(diào)試代碼層次越多問(wèn)題越難定位。6.2 上板后的快速驗(yàn)證步驟拿到源碼后我建議的驗(yàn)證步驟是第一步Vivado里檢查工程用的FPGA型號(hào)和板卡是否一致不一致先改器件并重新完成綜合布局布線別急著上板第二步核對(duì)引腳約束文件里的GT位置、參考時(shí)鐘引腳、CameraLink并行接口引腳尤其是差分信號(hào)正負(fù)極性不能反第三步燒錄第一套回環(huán)工程打開(kāi)串口或者ILA觀察誤碼計(jì)數(shù)是否一直為零第四步回環(huán)通過(guò)后燒錄第二套工程接上CameraLink相機(jī)先確認(rèn)近端側(cè)能正確解析到FVAL和LVAL再插光纖看遠(yuǎn)端能否出圖第五步長(zhǎng)穩(wěn)測(cè)試至少跑4小時(shí)以上同時(shí)人為拔插光纖幾次觀察恢復(fù)機(jī)制是否能自動(dòng)重新拉高鏈路和恢復(fù)圖像流。光模塊的線纜也很關(guān)鍵。SFP插座有的帶鎖扣有的不帶插拔光纖時(shí)不要拉線身要捏住接頭拔出。光纖端面臟污是工業(yè)現(xiàn)場(chǎng)最常見(jiàn)的隱性故障如果遇到衰耗大、偶發(fā)誤碼先用光纖清潔筆擦一下再試。6.3 想要繼續(xù)擴(kuò)展可以在哪里動(dòng)刀這套架構(gòu)最大的擴(kuò)展價(jià)值在于圖像數(shù)據(jù)到達(dá)FPGA之后天然可以做各種處理。目前工程源碼里如果只做“轉(zhuǎn)光口”其實(shí)浪費(fèi)了FPGA算力。你可以很自然地在CameraLink接收之后、Aurora發(fā)送之前插入一行處理流水線比如Bayer轉(zhuǎn)RGB、自動(dòng)白平衡、ROI裁剪、幀率降低、圖像壓縮等。因?yàn)槲仪懊孀远x行頭是數(shù)據(jù)不透明傳輸一旦在FPGA內(nèi)部修改了像素內(nèi)容或行長(zhǎng)度只需要同步修改行頭里的長(zhǎng)度字段即可。如果后端需要的是GigE Vision或者UDP數(shù)據(jù)包也可以把Aurora發(fā)送替換成Xilinx 1G/2.5G Ethernet MAC加UDP/IP封裝SFP光口物理層仍然復(fù)用GT。這個(gè)擴(kuò)展方向在需要把相機(jī)直接接入PC網(wǎng)絡(luò)時(shí)很有用只是工程量和復(fù)雜度比Aurora方案高一個(gè)量級(jí)建議在Aurora方案穩(wěn)定跑通之后再做。從個(gè)人實(shí)操角度講這類(lèi)接口轉(zhuǎn)換項(xiàng)目成敗的關(guān)鍵不在于哪個(gè)IP配得高深而在于你把鏈路分層、把時(shí)序邊界、把異常恢復(fù)機(jī)制理解到什么程度。我自己最深的體會(huì)是先做一套回環(huán)工程再談圖像傳輸這句話能幫你省掉至少一周的無(wú)效調(diào)試。另一個(gè)小建議是在行頭里多放幾個(gè)調(diào)試計(jì)數(shù)器比如總行數(shù)、總幀數(shù)、誤碼行數(shù)這些留在遠(yuǎn)端采集端非常有用比事后接ILA看波形高效得多。