:Chip2Chip Aurora PHY配置實戰(zhàn))
前陣子調一塊板卡兩塊FPGA之間要傳一路視頻流再帶一路寄存器讀寫控制加起來大概3.2Gbps。一開始想走LVDS并行總線算了下差分對要三十多對PCB布線直接頭大換PCIe的話又覺得殺雞用牛刀光是枚舉和驅動就夠折騰。后來在Vivado的IP Catalog里翻到Chip2Chip這個核才意識到這就是干這活的合適人選。從配置到仿真再到上板前后花了一周鏈路終于穩(wěn)定跑起來。這篇文章就把Chip2Chip IP核基于Aurora PHY的通信配置過程、仿真驗證方法和我踩過的坑完整記下來給準備用高速串行鏈路做板間互聯(lián)的朋友一個參考。1. 為什么需要Chip2Chip高速板間互聯(lián)方案怎么選1.1 LVDS、PCIe、Aurora和Chip2Chip的定位區(qū)別板間高速互聯(lián)的常規(guī)選擇無非這么幾種并行LVDS、PCIe、Aurora協(xié)議以及這里要重點說的Chip2Chip IP核。它們之間不是簡單的“誰替代誰”而是適用場景差別很大。方案典型帶寬資源開銷復雜度適用場景LVDS并行總線幾百Mbps到2Gbps大量IO引腳低短距離、低速率、帶寬要求不高PCIe單通道2.5Gbps起硬核或PCIe IP DMA邏輯高主機與FPGA、系統(tǒng)級復雜互聯(lián)Aurora 8B/10B從1Gbps到10Gbps以上GT Aurora IP 用戶邏輯中任意兩點間的高速流式傳輸Chip2Chip和Aurora一致GT Chip2Chip IP中低兩塊FPGA之間點對點數(shù)據傳輸和寄存器訪問PCIe最大的問題不是性能而是“重”。一旦用了PCIe就得考慮鏈路訓練、BAR空間映射、DMA引擎、驅動適配如果只是兩塊FPGA之間互相傳數(shù)據這些全是額外負擔。而直接用Aurora 8B/10B IP核功能很強但需要自己處理初始化時序、流控、錯誤恢復等一大堆協(xié)議細節(jié)對于只要“把數(shù)據從A點搬到B點”的場景來說學習成本略高。Chip2Chip本質上是在Aurora 8B/10B物理層之上包了一層簡化協(xié)議把很多底層細節(jié)藏了起來用戶看到的基本上是AXI-Stream或AXI接口。它的優(yōu)勢在于不需要寫復雜的Aurora協(xié)議狀態(tài)機配置完IP核后直接讀寫數(shù)據即可。同時它還支持遠程寄存器訪問這對需要跨板卡讀寫控制寄存器的場景特別實用。1.2 什么場景用Chip2Chip最劃算根據我的實際使用體會以下場景優(yōu)先考慮Chip2Chip兩塊FPGA之間需要穩(wěn)定跑2Gbps以上的數(shù)據流比如視頻流、高速ADC采樣數(shù)據、雷達中頻數(shù)據。需要跨板卡訪問另一端的寄存器或存儲空間希望像訪問本地地址一樣操作遠端。不想自己維護Aurora協(xié)議的初始化、復位、錯誤處理邏輯。希望鏈路有相對確定的延遲而非類似以太網那樣的不確定性轉發(fā)。工程周期緊需要快速把物理層跑通把精力集中在業(yè)務邏輯上。反過來如果需要連接FPGA和主機CPU或者需要組網能力那還是老老實實用PCIe或EthernetChip2Chip只適合點對點場景這一點必須在方案定型前想清楚。2. 動手配置前先算好參數(shù)時鐘、位寬和GT資源2.1 線速率與GT參考時鐘頻率的匹配關系Chip2Chip的物理層是GT收發(fā)器GT內部靠QPLL或CPLL將參考時鐘倍頻到串行線速率。所以線速率和參考時鐘頻率之間必須滿足一個倍頻關系不是隨便組合都能用的。參考時鐘頻率、線速率和GT內部倍頻系數(shù)的關系可以簡單理解為線速率 參考時鐘頻率 × GT倍頻系數(shù)舉個例子如果線速率選2.5Gbps參考時鐘用125MHz那么GT倍頻系數(shù)就是20這在GT的合法配置范圍內。如果線速率是3.125Gbps參考時鐘同樣給125MHz倍頻系數(shù)就是25也常見。再比如5Gbps線速率搭配156.25MHz參考時鐘倍頻系數(shù)是32。配置IP核時Vivado會自動校驗參考時鐘頻率和線速率是否匹配。如果匹配不上界面會直接報錯或者在生成時彈警告。這里最容易踩的坑是自己想當然地給一個參考時鐘覺得“FPGA內部PLL總能搞定”實際上GT的PLL是有分頻系數(shù)范圍限制的不同F(xiàn)PGA器件、不同GT類型的限制還不一樣。我的建議是先定線速率再查器件手冊或參考Vivado下拉列表里能選的參考時鐘頻率不要反推。Vivado的Chip2Chip配置界面里參考時鐘那欄會列出該線速率下支持的合法頻率選一個離自己板卡時鐘樹最近的值后面硬件設計會省很多事。2.2 用戶時鐘頻率與數(shù)據位寬怎么算Chip2Chip的用戶接口支持2字節(jié)和4字節(jié)兩種數(shù)據位寬用戶時鐘頻率直接取決于線速率和位寬計算公式如下用戶時鐘頻率 線速率 / (10 × 數(shù)據位寬字節(jié)數(shù))這里除以10是因為Aurora 8B/10B編碼把每字節(jié)擴成了10bit傳輸。舉個例子線速率2.5Gbps、數(shù)據位寬2字節(jié)用戶時鐘 2.5G / (10 × 2) 125MHz。線速率3.125Gbps、數(shù)據位寬2字節(jié)用戶時鐘 3.125G / 20 156.25MHz。線速率6.6Gbps、數(shù)據位寬4字節(jié)用戶時鐘 6.6G / 40 165MHz。這個結果一定要在IP配置之前算清楚因為它決定了工程里用戶邏輯的時鐘域。實際項目中很多第一次用Chip2Chip的人會在這一步犯迷糊尤其是選了4字節(jié)位寬后以為用戶時鐘還是和線速率差不多快結果后面跨時鐘域處理全亂了。另外要注意雖然數(shù)據位寬增大后用戶時鐘頻率會降低但GT通道占用數(shù)也會變化。2字節(jié)位寬對應1個GT通道4字節(jié)位寬對應2個GT通道這一點下面細說。2.3 Chip2Chip占用幾個GT通道BANK怎么放Chip2Chip不像Aurora那樣配置多條lane擴展它的通道數(shù)基本由數(shù)據位寬決定。2字節(jié)位寬單通道即可跑通4字節(jié)位寬需要2條GT通道兩路并行分攤數(shù)據用戶側看到的就是更高帶寬的并行接口。通道數(shù)確定后還要考慮GT在FPGA物理位置上的約束。GT收發(fā)器是按Quad組織的每個Quad包含4個GT通道。單通道Chip2Chip隨便放雙通道就盡量放在同一個Quad里這樣QPLL資源可以共用時序也更容易收斂。如果板卡上有多個GT參考時鐘輸入務必讓Chip2Chip使用的GT通道和參考時鐘在同一個Quad或相鄰Quad。有些FPGA里GT參考時鐘的布線是有限制的跨太遠會導致參考時鐘無法布線或者在實現(xiàn)階段出現(xiàn)嚴重的時序問題。這個坑在原理圖設計階段就要避掉等PCB做回來再發(fā)現(xiàn)就麻煩了。3. Chip2Chip IP核核心配置實操3.1 生成主從兩個IP實例角色別選錯Chip2Chip是成對使用的IP通信雙方一端為主Primary另一端為從Secondary。配置時需要在Vivado IP Catalog里搜索chip2chip然后分別生成兩個IP實例一個選Primary一個選Secondary。這里有個很容易忽略的細節(jié)兩個實例雖然在配置界面上選項很多但協(xié)議類型、線速率、數(shù)據位寬必須完全一致否則物理層鏈路協(xié)商不起來。角色不同只影響初始化時的握手順序和部分控制信號極性不影響數(shù)據面格式。接口類型按需選擇。典型用法是數(shù)據通道用AXI4-Stream控制寄存器用AXI4-Lite。如果只想傳流式數(shù)據AXI4-Stream就夠了配置也最簡單如果還需要跨板卡讀寫寄存器就再加上AXI4-Lite接口。兩個接口可以同時存在于一個Chip2Chip IP核里只是會多占一些內部資源。生成完IP后建議先在IP Sources里打開Example Design把它作為學習參考。Example Design里包含完整的初始化模塊、時鐘模塊和收發(fā)數(shù)據驗證模塊比對著用戶手冊硬啃高效得多。我一般習慣直接基于Example Design改而不是從空工程開始。3.2 協(xié)議層選項Aurora 8B/10B PHY、流控和CRCChip2Chip配置界面里物理層協(xié)議可以選擇Aurora 8B/10B PHY或簡化物理層不使用Aurora協(xié)議。如果只要兩個Chip2Chip互相通信用哪種都能跑通。但考慮到可觀測性和通用性我推薦選Aurora 8B/10B PHY原因有三個鏈路初始化、字節(jié)對齊、通道綁定這些底層操作由Aurora PHY的狀態(tài)機管理穩(wěn)定可靠。調試時可以直接參考Aurora的lane_up和channel_up信號判斷物理層狀態(tài)。如果以后需要改成和其他Aurora設備互通至少物理層是一致的。流控建議根據業(yè)務需求決定。如果兩端的數(shù)據發(fā)送速率是固定的且接收端FIFO深度足夠可以不開啟流控簡化邏輯。如果存在突發(fā)流量建議開啟Native Flow Control這樣接收端FIFO快滿時能通知對端暫停發(fā)送避免丟數(shù)據。CRC校驗屬于可靠性增強選項。開啟后Chip2Chip會在每個數(shù)據包尾部附加校驗值接收端檢測錯誤后可以上報。對于需要高可靠傳輸?shù)膱鼍拔医ㄗh開啟代價是有效帶寬略降但對于大多數(shù)Gbps級別的應用來說可以接受。3.3 復位與初始化邏輯千萬別填錯Chip2Chip的初始化過程并不是上電后自己就乖乖完成的它需要用戶側提供合適的復位時序和初始化時鐘。最核心的幾點channel_init_clk是初始化模塊的工作時鐘頻率不能太高通常建議50MHz左右。這個時鐘要保證在GT復位期間持續(xù)穩(wěn)定不能等channel_up之后再給。gt_reset信號必須有效復位一段時間后釋放。釋放太早可能導致GT的PLL還沒完成鎖定后面初始化卡死釋放太晚也不會有什么問題就是浪費時間。gt_txresetdone和gt_rxresetdone兩個信號是GT單元給出的復位完成標志Chip2Chip內部的Aurora初始化狀態(tài)機依賴這兩個信號推進狀態(tài)。在Example Design里這些信號都被封裝好了基本不用自己動。但如果自己搭工程最容易犯的錯就是把channel_init_clk和user_clk接到同一個時鐘上。有些用戶時鐘頻率很高比如157MHz、165MHz拿來當初始化時鐘可能會導致時序違例使初始化狀態(tài)機亂跳。穩(wěn)妥做法是單獨分出一個50MHz時鐘給初始化模塊數(shù)據通路再跑高速用戶時鐘。還有一點關于power_down信號通常保持低電平即可。如果把GT的power_down意外拉高GT會進入低功耗模式鏈路怎么都練不起來初始化狀態(tài)機會一直卡在等待復位完成那一步。仿真時不注意還容易忽略因為仿真模型里power_down拉高并不一定立刻報錯。4. 仿真搭建與Aurora PHY初始化避坑4.1 用Example Design快速搭一個雙端仿真工程Chip2Chip的仿真一定要由兩個IP實例配合完成一端主、一端從GT發(fā)送端的差分信號txp/txn接到對端接收端的rxp/rxn。可以在頂層模塊里先實例化兩個IP然后把信號連起來。最快的起步方式是在生成IP后使用Vivado Tcl命令行打開Example Designopen_example_design -ip [get_ips chip2chip_0]Example Design里自帶時鐘模塊、復位模塊、數(shù)據生成和比對模塊直接跑行為仿真就能看到channel_up拉高的完整時序。我第一次做的時候就是先把主從兩端各自Example Design打開然后把兩邊的頂層里面與GT相連的差分收發(fā)信號互相交叉連接再跑仿真。仿真時間要設夠。GT的PLL鎖定和復位完成在仿真模型里會模擬出真實硬件的時間尺度通常需要幾十微秒到幾百微秒。如果仿真時間只給幾微秒可能還沒看到channel_up就結束了。建議至少跑到500微秒等channel_up穩(wěn)定后再做數(shù)據收發(fā)驗證。4.2 初始化時序里到底發(fā)生了什么Chip2Chip和Aurora PHY的初始化大致分三個階段PMA初始化GT的模擬部分上電復位QPLL/CPLL開始鎖定gt_txresetdone和gt_rxresetdone依次拉高。lane初始化發(fā)送端開始發(fā)送時鐘對齊序列接收端通過8B/10B的comma字符完成字節(jié)對齊lane_up拉高。channel初始化兩端交換初始化狀態(tài)機信息完成通道握手最終channel_up拉高用戶數(shù)據通路使能。仿真的時候可以拉出lane_up和channel_up信號觀察它們抬起的順序。正常情況下lane_up會先于channel_up。如果只看到lane_up拉高而channel_up一直不拉問題多半出在主從兩端參數(shù)不一致或者狀態(tài)機配置有差異。值得一提的是用戶接口的復位信號通常是低有效復位也就是說axi_resetn在channel_up拉高后才能釋放。如果外部邏輯不管三七二十一先把用戶邏輯復位釋放了而此時鏈路還沒建立數(shù)據就會在發(fā)送端堆積恢復后可能出現(xiàn)先入先出的對齊問題。工程上建議直接用channel_up信號作為用戶邏輯復位釋放的條件或者至少用它做一次同步。4.3 數(shù)據回環(huán)驗證從發(fā)計數(shù)器到收計數(shù)器比對鏈路初始化通過后第一件事不是跑業(yè)務數(shù)據而是做一個簡單的回環(huán)驗證。我常用的方法是在發(fā)送端用一個計數(shù)器循環(huán)發(fā)送0x0000到0xFFFF的數(shù)據接收端把收到的數(shù)據和本地產生的預期值進行比對一旦不一致就拉高錯誤標志。在Example Design里自帶的驗證模塊已經做了類似事情可以省不少事。如果想自己寫一個精簡版核心代碼邏輯大致是這樣// 發(fā)送端16bit計數(shù)器循環(huán)遞增 always (posedge user_clk) begin if (!tx_ready) tx_data tx_data 1b1; end // 接收端比對接收數(shù)據與本地遞增計數(shù) always (posedge user_clk) begin if (rx_valid) begin if (rx_data ! expected_data) error_flag 1b1; else expected_data expected_data 1b1; end end仿真時不要只比對一兩個包建議連續(xù)跑幾萬個數(shù)據。如果鏈路存在偶發(fā)誤碼或者初始化過程復位不干凈短時間內不一定暴露問題但長時間數(shù)據比對能大概率發(fā)現(xiàn)。數(shù)據驗證通過后再引入實際業(yè)務邏輯。迭代時先保通道、再加業(yè)務這個順序能極大減少排障時間。4.4 仿真中常見錯誤和解決方案速查我整理了一張自己在仿真中經常遇到的錯誤對照表基本覆蓋了Chip2Chip初始化階段的高頻問題現(xiàn)象可能原因解決辦法channel_up一直為低主從兩端線速率或位寬不一致檢查兩端IP配置是否完全一致lane_up不拉高GT參考時鐘沒起振或頻率不對查看仿真波形確認參考時鐘頻率正確gt_txresetdone不拉高gt_reset釋放太早或channel_init_clk沒跑拉長復位時間確保init_clk先運行數(shù)據偶發(fā)錯位用戶復位釋放時機錯誤用channel_up同步釋放axi_resetn仿真波形出現(xiàn)大量X態(tài)某些GT配置參數(shù)未初始化確認是否直接用了Example Design的仿真設置上板后鏈路正常但仿真不過仿真模型與實際硬件復位時間不同仿真中適當延長等待時間還有一個容易被忽視的問題仿真模型默認情況下不會模擬出真實的QPLL鎖定失敗場景。也就是說即使參考時鐘頻率不對行為仿真也可能看起來一切正常但上板后鏈路怎么都練不起來。所以仿真通過不等于硬件一定沒問題這一點要特別留意。5. 上板調試時容易忽略的硬件細節(jié)5.1 參考時鐘、差分走線和接地Chip2Chip跑的是高速串行信號物理層對參考時鐘和差分走線非常敏感。參考時鐘請使用時鐘源專用引腳輸入不要拿普通IO模擬差分時鐘抖動會直接影響GT的誤碼率。如果條件允許用獨立晶振或時鐘芯片給GT參考時鐘供給干凈時鐘源。差分走線要按100歐姆差分阻抗控制盡量短避免過孔。如果走線跨層記得在換層附近加回流地孔。兩塊FPGA板卡之間用連接器互連時連接器的信號完整性問題也要考慮最好選經過驗證的高速連接器。還有一個容易被忽略的點兩塊板卡的GND必須可靠連通。如果地電位不一致GT的共模電壓會漂移輕則誤碼率高重則鏈路完全無法建立。調試時先用萬用表確認兩端地線連接正常再上業(yè)務。5.2 上板后如何快速定位鏈路狀態(tài)上板后如果鏈路不通不要急著改代碼先看信號。我一般按這個順序排查用邏輯分析儀或ILA觀察gt_txresetdone和gt_rxresetdone是否拉高確認GT復位完成。觀察lane_up狀態(tài)確認字節(jié)對齊是否完成。觀察channel_up狀態(tài)確認兩端握手是否成功。如果都能拉高再跑數(shù)據回環(huán)抓取接收端錯誤標志。FPGA內部這些信號都很容易引出到ILA。如果工程里不好加探針可以直接在頂層模塊里把幾個關鍵信號引出來連到空閑LED上用示波器或肉眼觀察狀態(tài)。LED雖然土但真到了現(xiàn)場調試往往比打開Vivado抓波形還快。上板調試另一個常見問題是誤碼率不穩(wěn)。排除接線問題后優(yōu)先嘗試降低GT線速率比如從5G降到2.5G如果誤碼消失說明信號完整性問題比較大需要檢查PCB走線和連接器。這個診斷方法簡單有效能快速把問題范圍縮小到信號完整性還是協(xié)議配置上。最后再說兩句Chip2Chip這個IP核表面上看起來只是一個“串口加強版”用熟了以后才會發(fā)現(xiàn)它內部的Aurora PHY初始化其實藏著不少細節(jié)。它最友好的地方在于Xilinx用標準化封裝把底層協(xié)議打包了讓用戶把精力放到數(shù)據通路和業(yè)務邏輯上。但我個人的體會是越是這樣封裝的核越要在仿真階段把初始化時序吃透否則上板出了問題反而更不好排查。我后來的固定套路是新項目只要涉及Chip2Chip第一步一定是拿Example Design跑雙端仿真看到channel_up穩(wěn)定拉高后再改成自己的業(yè)務邏輯。這一步省掉了我不知道多少的回頭調試時間。希望這篇實戰(zhàn)經驗能幫你少走彎路。