計(jì):SelectIO IP核配置與調(diào)試實(shí)戰(zhàn)指南)
你打開(kāi)Vivado的IP Catalog在搜索框里敲下“SelectIO”雙擊那個(gè)藍(lán)綠色圖標(biāo)時(shí)屏幕前的新手和踩過(guò)坑的老工程師往往是兩種完全不同的心情。這個(gè)IP核的本質(zhì)并不復(fù)雜就是把FPGA物理層的差分收發(fā)邏輯、延遲調(diào)節(jié)、串并轉(zhuǎn)換打包成一個(gè)圖形化配置工具尤其是做LVDS接口采集或者高速ADC數(shù)據(jù)接收的時(shí)候它幾乎就是繞不開(kāi)的一站。我在多個(gè)7系列項(xiàng)目里用過(guò)這個(gè)IP核包括Artix-7和Kintex-7從最初照著別人的示例改端口到后來(lái)自己手寫約束、排查數(shù)據(jù)錯(cuò)位中間翻過(guò)不少文檔也踩過(guò)不少硬件坑。這篇東西不打算做成PG182的翻譯而是從一個(gè)實(shí)際工程的角度把SelectIO IP核的配置流程、7系列LVDS的硬件要點(diǎn)、時(shí)序約束和調(diào)試技巧串起來(lái)講給你一條可以直接上板驗(yàn)證的路。1. SelectIO IP核到底解決什么問(wèn)題從手寫原語(yǔ)到IP核的關(guān)鍵差異1.1 為什么7系列上LVDS強(qiáng)烈建議走SelectIO IP核很多剛從Verilog語(yǔ)法學(xué)完就開(kāi)始做FPGA的同學(xué)第一次接觸LVDS時(shí)想的都是“差分信號(hào)嘛IBUFDS和OBUFDS兩個(gè)原語(yǔ)一包不就完事了”。這個(gè)說(shuō)法在低速、點(diǎn)對(duì)點(diǎn)、單向傳輸?shù)膱?chǎng)景下確實(shí)成立比如把一對(duì)差分信號(hào)引入內(nèi)部邏輯用個(gè)IBUFDS實(shí)例化1-bit數(shù)據(jù)就出來(lái)了。但一旦數(shù)據(jù)位寬變大、速率上去問(wèn)題就完全不同了。以7系列內(nèi)部結(jié)構(gòu)為例每個(gè)IO Bank相當(dāng)于是由一系列IO Tile構(gòu)成的而每個(gè)IO Tile里除了最原始的輸入輸出緩沖器之外還有ISERDES和OSERDES這種專門做串并轉(zhuǎn)換的硬核資源再加上IDELAY、ODELAY這種可以精確調(diào)節(jié)數(shù)據(jù)延遲的模擬電路。直接寫原語(yǔ)意味著這些資源都得自己實(shí)例化、自己接時(shí)鐘、自己管理FIFO位寬變換還要自己處理bitslip對(duì)齊邏輯工作量很容易翻倍。而SelectIO IP核做的事情就是把這一套東西在圖形界面里暴露出來(lái)你在選項(xiàng)里勾選一下數(shù)據(jù)位寬、時(shí)鐘模式、差分標(biāo)準(zhǔn)它自動(dòng)幫你生成對(duì)應(yīng)的ISERDES/OSERDES/IDELAY邏輯和約束。統(tǒng)一用IP核還有一個(gè)很重要的原因Vivado在實(shí)現(xiàn)階段會(huì)對(duì)IP核內(nèi)部做特定優(yōu)化和約束傳遞。如果你自己手寫IBUFDSISERDES很可能漏掉IO delay相關(guān)約束或者參考時(shí)鐘連接不對(duì)結(jié)果就是時(shí)序報(bào)告看起來(lái)沒(méi)有問(wèn)題硬件上抓出來(lái)的數(shù)據(jù)卻錯(cuò)位、亂碼這種問(wèn)題極難排查。所以我的建議是7系列做LVDS接口除非你是想寫一篇講底層原語(yǔ)的博客否則一律走SelectIO IP核把時(shí)間花在調(diào)試和驗(yàn)證上。1.2 SelectIO和IBUFDS/OBUFDS/ISERDES/OSERDES的分工關(guān)系明白了為什么用IP核還得理解一下IP核內(nèi)部到底生成了什么不然碰到自定義需求時(shí)依然無(wú)從下手。SelectIO IP核本質(zhì)上是自動(dòng)生成了一段RTL和XDC的封裝它的底層調(diào)用的還是Xilinx的底層原語(yǔ)。以接收方向?yàn)槔齀P核內(nèi)部通常會(huì)實(shí)例化如下資源IBUFDS把外部差分P/N信號(hào)轉(zhuǎn)成內(nèi)部單端信號(hào)同時(shí)也負(fù)責(zé)DIFF_TERM終端電阻的控制IDELAY對(duì)輸入數(shù)據(jù)做延遲調(diào)整延遲顆粒度由IDELAYCTRL提供的參考時(shí)鐘決定ISERDESE2把高速串行數(shù)據(jù)按照設(shè)定的串并轉(zhuǎn)換比變成并行總線BUFIO/BUFR為ISERDES提供專用的時(shí)鐘網(wǎng)絡(luò)BUFIO負(fù)責(zé)高速時(shí)鐘BUFR負(fù)責(zé)分頻后的并行時(shí)鐘。輸出方向則是反過(guò)來(lái)的OBUFDS、ODELAY、OSERDESE2那一套。如果你勾選了雙向接口IP核還會(huì)自動(dòng)管理IO方向的使能邏輯。了解這一層之后再看到IP核配置界面里那些選項(xiàng)就不會(huì)懵了——你其實(shí)就是在替這些底層原語(yǔ)選參數(shù)只不過(guò)不用自己寫實(shí)例化代碼而已。這個(gè)認(rèn)知在調(diào)試階段也特別重要。比如你發(fā)現(xiàn)輸入數(shù)據(jù)在某個(gè)延遲值附近能采對(duì)換到另一塊板卡上就不行了其實(shí)就是IDELAY的延遲鏈在不同溫度和電壓下發(fā)生了變化。這時(shí)候你得知道去調(diào)整IP核的延遲參數(shù)或者直接通過(guò)動(dòng)態(tài)延遲接口如果開(kāi)了動(dòng)態(tài)延遲功能在運(yùn)行時(shí)微調(diào)而不是去懷疑數(shù)據(jù)邏輯寫錯(cuò)了。2. 7系列LVDS硬件基礎(chǔ)電壓域、終端電阻與引腳約束2.1 HP bank和HR bank第一步就要確認(rèn)VCCO配置IP核之前先看一眼原理圖上這個(gè)FPGA引腳落在了哪個(gè)Bank這是很多初學(xué)者最容易忽略的一步。7系列里的Bank分成兩類HPHigh Performancebank和HRHigh Rangebank。HP bank的IO電壓最高支持到1.8V適合高速接口LVDS這種低壓差分信號(hào)天生就是為HP bank準(zhǔn)備的HR bank則可以支持到3.3V低電壓支持到1.2V左右。SelectIO IP核里選擇LVDS標(biāo)準(zhǔn)時(shí)一般會(huì)看到LVDS和LVDS_25兩個(gè)選項(xiàng)對(duì)應(yīng)的VCCO要求分別是1.8V和2.5V。如果你在VCCO為1.8V的HP bank上做LVDS就選LVDS標(biāo)準(zhǔn)如果在2.5V的bank上做就選LVDS_25。還有一種叫LVDSEXT的擴(kuò)展擺幅模式適合更長(zhǎng)距離的傳輸?shù)胀ò寮?jí)差分互連基本用不上。我遇到過(guò)不止一次這種情況原理圖明明畫的是LVDS接口結(jié)果對(duì)應(yīng)Bank的VCCO因?yàn)橥瑫r(shí)接了別的電平信號(hào)被設(shè)計(jì)成了3.3V。這種時(shí)候LVDS根本沒(méi)法正常工作因?yàn)長(zhǎng)VDS的共模電壓在1.2V左右擺幅才350mV上下3.3V的輸入緩沖器根本沒(méi)法正確判斷這種電平。所以拿到一塊新板子第一件事永遠(yuǎn)是打開(kāi)原理圖逐個(gè)Bank核對(duì)VCCO和接口標(biāo)準(zhǔn)是否匹配這個(gè)習(xí)慣能省下后面一整周的調(diào)試時(shí)間。2.2 LVDS終端電阻內(nèi)部DIFF_TERM和外置100歐的取舍LVDS是電流驅(qū)動(dòng)的差分信號(hào)接收端必須有一個(gè)100歐姆的差分終端電阻把電流轉(zhuǎn)成電壓否則信號(hào)反射會(huì)造成嚴(yán)重?fù)p傷。這個(gè)終端電阻可以放在片外也可以直接用FPGA內(nèi)部的DIFF_TERM選項(xiàng)。SelectIO IP核配置界面上有一個(gè)很顯眼的選項(xiàng)叫DIFF_TERM勾上之后IP核會(huì)在約束文件里自動(dòng)加上set_property DIFF_TERM TRUE。對(duì)于普通的板內(nèi)LVDS傳輸內(nèi)部終端電阻足夠好用好處是省掉兩顆電阻布局面積也小。需要注意內(nèi)部這個(gè)電阻是弱終端嗎并不是實(shí)際上7系列內(nèi)部大約就是100歐姆左右的差分阻抗和規(guī)范要求一致。但我個(gè)人習(xí)慣是如果這個(gè)LVDS接口要跨板連接比如經(jīng)連接器連接到另一個(gè)單板或者鏈路長(zhǎng)度比較長(zhǎng)我會(huì)在接收端靠近FPGA引腳的地方放一對(duì)物理電阻用作終端。原因很簡(jiǎn)單檢測(cè)和替換都方便。內(nèi)部DIFF_TERM在高低溫下可能有微小波動(dòng)而且它消耗的功耗也比預(yù)期要高一點(diǎn)。究竟是內(nèi)部還是外部歸根結(jié)底是SI信號(hào)完整性設(shè)計(jì)和成本之間的權(quán)衡。如果你只是調(diào)試一個(gè)短距離ADC采樣板開(kāi)內(nèi)部終端就夠了如果你是做背板互聯(lián)建議老老實(shí)實(shí)把外部100歐焊上。2.3 引腳約束差分Pin和Pin assignment的實(shí)操細(xì)節(jié)在Vivado里約束差分引腳有個(gè)很容易踩的坑就是有些新手會(huì)試圖在XDC里分別給P端和N端寫兩行PACKAGE_PIN約束Vivado并不會(huì)直接報(bào)錯(cuò)但實(shí)現(xiàn)后你會(huì)發(fā)現(xiàn)N端方向有時(shí)變得不對(duì)或者差分標(biāo)準(zhǔn)被警告覆蓋。正確的做法是只對(duì)P端指定封裝引腳并給整個(gè)端口對(duì)port pair設(shè)置IO標(biāo)準(zhǔn)。舉個(gè)例子如果項(xiàng)目里有LVDS輸入信號(hào)adc_d_p和adc_d_n、adc_clk_p和adc_clk_nXDC可以這樣寫set_property PACKAGE_PIN K20 [get_ports adc_d_p] set_property PACKAGE_PIN K21 [get_ports adc_d_n] set_property IOSTANDARD LVDS_25 [get_ports adc_d_p] set_property DIFF_TERM TRUE [get_ports adc_d_p]如果你用了SelectIO IP核IP核生成的端口名一般是data_in_from_pins_p和data_in_from_pins_n這種格式依次類推還要約束clk_in_p/form_clk_n。差分對(duì)需要保證P/N連到物理上相鄰的引腳對(duì)通常叫P與N是互補(bǔ)的。Vivado在做引腳規(guī)劃時(shí)會(huì)在Device視圖里把你選中的兩個(gè)引腳用顏色標(biāo)注出來(lái)如果N端和P端不在同一個(gè)差分對(duì)里實(shí)現(xiàn)會(huì)直接報(bào)錯(cuò)。把引腳約束搞定之后下一步才能真正進(jìn)入IP核的圖形化配置。3. Vivado中SelectIO IP核的完整配置步驟與參數(shù)詳解3.1 打開(kāi)IP Catalog并創(chuàng)建SelectIO IP核實(shí)例在Vivado的Flow Navigator里點(diǎn)IP Catalog搜索SelectIO能看到一個(gè)叫“SelectIO Interface”的IP核直接雙擊。在彈出的對(duì)話框中先給IP核起一個(gè)名字比如lvds_rx_1to8然后會(huì)進(jìn)入它的配置界面。版本方面7系列用Vivado 2019.1到2022.2都遇到過(guò)不同小版本的界面排布略有區(qū)別但核心選項(xiàng)基本沒(méi)有變化。值得注意的是Vivado對(duì)7系列支持一直保持得很好即使比較新的版本也能直接生成7系列IP核不需要像某些專用IP那樣擔(dān)心授權(quán)問(wèn)題。SelectIO IP核在Vivado里是直接可用的不需要額外license。打開(kāi)的配置界面里首先要選擇接口方向。如果你要接ADC的LVDS輸出選Input如果要把并行數(shù)據(jù)發(fā)送給后級(jí)DAC或SerDes芯片選Output如果是類似并口轉(zhuǎn)LVDS再加上回讀信號(hào)這種場(chǎng)景可以選Bidirectional不過(guò)雙向模式下集成電路引腳復(fù)用會(huì)變得復(fù)雜建議按需選擇。3.2 配置頁(yè)關(guān)鍵選項(xiàng)逐項(xiàng)拆解第一個(gè)要決定的是串行化系數(shù)也就是Serialization Factor。這個(gè)系數(shù)代表每個(gè)物理LVDS引腳對(duì)應(yīng)內(nèi)部并行數(shù)據(jù)的位寬。7系列的ISERDESE2天然支持1:2的SDR、1:4的DDR以及1:6、1:8等模式。選系數(shù)時(shí)要考慮你的數(shù)據(jù)速率和FPGA內(nèi)部邏輯時(shí)鐘能否匹配上。舉個(gè)例子LVDS時(shí)鐘是100MHz DDR模式數(shù)據(jù)速率是200Mbps如果你選1:4串并轉(zhuǎn)換那么內(nèi)部并行總線時(shí)鐘就是50MHz這個(gè)頻率對(duì)于普通邏輯處理很舒服。如果你選1:8內(nèi)部時(shí)鐘降到25MHz但每個(gè)引腳數(shù)據(jù)位寬變成8bit總線面積也翻倍。我一般會(huì)優(yōu)先選1:4或1:8因?yàn)檫@兩個(gè)數(shù)值對(duì)外部數(shù)據(jù)對(duì)齊和內(nèi)部FIFO拼接都比較友好1:10、1:14這些系數(shù)雖然IP核也支持但意味著內(nèi)部需要額外的級(jí)聯(lián)邏輯時(shí)序收斂難度會(huì)上升。接下來(lái)是Data Rate的選擇。一般如果外部接口是DDR上升沿和下降沿都采樣就選DDR如果是SDR就選SDR。實(shí)際做ADC采集時(shí)絕大部分LVDS接口都是DDR因?yàn)镈DR可以在相同時(shí)鐘頻率下把吞吐翻倍這也是LVDS接口常見(jiàn)用法。時(shí)鐘模式里還有個(gè)選項(xiàng)是“Use Clock Forwarding”之類的意思是是否將接收到的源同步時(shí)鐘轉(zhuǎn)發(fā)輸出如果后級(jí)還接了別的FPGA或者芯片需要同一個(gè)參考時(shí)鐘可以考慮勾選但一般用不到。關(guān)鍵選項(xiàng)里還有Delay Control類比如Reference Clock頻率。IP核內(nèi)部IDELAY/ODELAY需要IDELAYCTRL提供一個(gè)參考時(shí)鐘這個(gè)參考時(shí)鐘的頻率直接決定了延遲鏈的單步精度。7系列的IDELAYCTRL要求參考時(shí)鐘范圍是190MHz~210MHz常見(jiàn)的就是200MHz可以在IP核的Delay Reference Clock里填200。這里有個(gè)重要細(xì)節(jié)這路參考時(shí)鐘必須是真實(shí)、穩(wěn)定、無(wú)毛刺的時(shí)鐘很多工程把這路時(shí)鐘和普通邏輯時(shí)鐘共用結(jié)果因?yàn)槊虒?dǎo)致延遲鏈完全不工作排查起來(lái)非常頭痛。建議單獨(dú)用一個(gè)全局時(shí)鐘資源或者從差分引腳直接接一個(gè)干凈的200M晶振進(jìn)去。另一個(gè)值得說(shuō)明的選項(xiàng)是TEACH Pattern。SelectIO IP核支持一個(gè)“TEACH”功能大致意思是你可以提供一個(gè)已知的輸入訓(xùn)練序列IP核會(huì)在硬件上自動(dòng)搜索最佳的延遲設(shè)置。這個(gè)功能對(duì)8B/10B類接口或者有前導(dǎo)碼的ADC鏈路非常實(shí)用但如果是普通無(wú)訓(xùn)練序列的數(shù)據(jù)流就只能在配置里先設(shè)置初始延遲值再通過(guò)硬件調(diào)試去手動(dòng)調(diào)整。我自己的項(xiàng)目里通常先把TEACH關(guān)掉用固定延遲把鏈路打通之后再看是否需要開(kāi)TEACH提高魯棒性。開(kāi)啟TEACH后需要在配置里額外指定參考Pattern和通道數(shù)量IP核會(huì)生成對(duì)應(yīng)的控制邏輯。3.3 生成IP后的工程集成與端口連接所有參數(shù)配置完成后點(diǎn)擊Generate生成IP核之后在工程里就能看到生成的示例例化模板。有一個(gè)習(xí)慣值得養(yǎng)成把生成的示例文件打開(kāi)看一眼尤其是頂層端口注釋里對(duì)每個(gè)信號(hào)的說(shuō)明。IP核生成后可以在Sources面板里點(diǎn)開(kāi)IP核的Instantiation TemplateVivado會(huì)自動(dòng)生成一個(gè)HDL例化模板。直接把模板端口復(fù)制到自己的模塊里例化不容易漏信號(hào)。如果是Input方向端口一般類似下面這種寫法不同配置下端口名可能略有差異lvds_rx_1to8 u_lvds_rx ( .data_in_from_pins_p (adc_d_p), .data_in_from_pins_n (adc_d_n), .data_in_to_device (adc_data_parallel), .clk_in_p (adc_clk_p), .clk_in_n (adc_clk_n), .clk_out (clk_parallel), .bitslip (bitslip_ctrl), .io_reset (io_reset), .delay_refclk (clk_200m), .delay_locked (delay_locked) );注意io_reset要接一個(gè)高有效的復(fù)位信號(hào)建議在系統(tǒng)時(shí)鐘穩(wěn)定之后至少再等幾百微秒釋放不要直接和全局復(fù)位綁在一起。delay_locked信號(hào)是延遲鏈鎖定指示上板調(diào)試時(shí)一定要接到ILA里監(jiān)控如果這個(gè)信號(hào)一直拉低那大概率是delay_refclk沒(méi)進(jìn)來(lái)或者頻率不對(duì)排查方向就有了。bitslip這個(gè)信號(hào)在非對(duì)齊場(chǎng)景下極為關(guān)鍵后面時(shí)序約束那一章會(huì)專門說(shuō)。Output方向的端口則是data_out_to_pins_p/n、data_out_from_device、clk_out這類整體思路一致。4. LVDS接口的時(shí)序約束與數(shù)據(jù)對(duì)齊方法4.1 時(shí)鐘約束input clock和data clock的關(guān)系SelectIO IP核能自動(dòng)生成一部分約束但并不會(huì)自動(dòng)幫你約束外部引腳到FPGA引腳的時(shí)序關(guān)系這部分需要自己在XDC里用set_input_delay和set_output_delay補(bǔ)全。否則Vivado雖然能跑通但時(shí)序報(bào)告里input delay默認(rèn)是0測(cè)出來(lái)結(jié)果對(duì)不上現(xiàn)實(shí)情況。以源同步LVDS輸入為例假設(shè)ADC輸出的LVDS數(shù)據(jù)時(shí)鐘頻率是200MHz數(shù)據(jù)在DDR模式下相對(duì)于時(shí)鐘邊沿的關(guān)系是上升沿對(duì)應(yīng)奇數(shù)位下降沿對(duì)應(yīng)偶數(shù)位數(shù)據(jù)在時(shí)鐘邊沿上變化。也就是所謂中心對(duì)齊或邊沿對(duì)齊需要根據(jù)ADC數(shù)據(jù)手冊(cè)里的時(shí)序參數(shù)來(lái)算。一般ADC數(shù)據(jù)手冊(cè)會(huì)給tcoclock to output delay范圍?;谶@個(gè)范圍可以計(jì)算create_clock -name adc_clk -period 5.000 [get_ports adc_clk_p] # 假設(shè)tco_min -1.5ns, tco_max 1.5ns 相對(duì)于的是時(shí)鐘的某個(gè)邊沿 set_input_delay -clock adc_clk -max 1.5 [get_ports adc_d_p] set_input_delay -clock adc_clk -min -1.5 [get_ports adc_d_p]DDR模式下還要用-clock_fall補(bǔ)充下降沿的約束這里要分兩條分別寫。如果偷懶只約束上升沿時(shí)序分析的結(jié)果就不完整硬件上偶爾采錯(cuò)位就很正常了。我第一次做這類約束時(shí)不理解為什么要把min設(shè)成負(fù)數(shù)后來(lái)才明白這是用來(lái)描述數(shù)據(jù)在時(shí)鐘邊沿之前就發(fā)生變化的時(shí)間窗口負(fù)值對(duì)應(yīng)的是數(shù)據(jù)提前翻轉(zhuǎn)的情況。更省事的辦法是直接用IP核內(nèi)部的輸入延遲接口比如在配置里開(kāi)了動(dòng)態(tài)延遲功能然后在硬件里以固定步長(zhǎng)掃描延遲值看哪個(gè)區(qū)間出數(shù)穩(wěn)定。這種方式對(duì)信號(hào)完整性好但約束依然不可少因?yàn)闀r(shí)序工具需要知道延遲鏈之外的外部路徑時(shí)間。4.2 數(shù)據(jù)對(duì)齊Bitslip、TEACH與延遲調(diào)整LVDS接收里最令人頭疼的往往不是時(shí)序約束而是數(shù)據(jù)在串并轉(zhuǎn)換之后錯(cuò)位。你可以想象一下發(fā)送端按1:8把并行數(shù)據(jù)變成串行流送過(guò)來(lái)接收端的ISERDES從任意一個(gè)比特位置開(kāi)始拼并第一次拼出來(lái)的8bit大概率不是原來(lái)發(fā)送端那個(gè)字節(jié)邊界里的8bit。你的并行數(shù)據(jù)和鏈路建立的初始相位之間差了一個(gè)偏移這個(gè)偏移可能是0到7個(gè)bit之間的任意值。解決這個(gè)問(wèn)題的機(jī)制就是bitslip。SelectIO IP核的Input方向幾乎一定會(huì)生成一個(gè)bitslip端口每拉高一拍ISERDES的并行輸出數(shù)據(jù)就被移位一個(gè)bit?;谶@個(gè)原理我常用的對(duì)齊方法是發(fā)送端先發(fā)送一個(gè)已知的8bit或16bit訓(xùn)練碼比如常見(jiàn)的0x5A或者0x3C然后接收端用狀態(tài)機(jī)檢測(cè)并行數(shù)據(jù)是否等于期望值不相等就拉一次bitslip直到相等為止。筆者的一個(gè)項(xiàng)目中曾用這種方式在1ms內(nèi)完成了8路LVDS通道的自動(dòng)對(duì)齊原理就是每個(gè)通道獨(dú)立檢測(cè)訓(xùn)練碼收到后再實(shí)時(shí)Insight整個(gè)邏輯代碼量也不大。如果不想自己寫狀態(tài)機(jī)也可以利用IP核的TEACH功能它本質(zhì)上也是在硬件上實(shí)現(xiàn)類似掃描只是自定義程度不如自己寫控制邏輯高。個(gè)人經(jīng)驗(yàn)是訓(xùn)練碼方式更透明可控TEACH適合那種鏈路特別多、自己寫狀態(tài)機(jī)容易出錯(cuò)的場(chǎng)景。對(duì)齊完成后如果發(fā)現(xiàn)某個(gè)通道偶爾誤碼可以考慮延遲值的動(dòng)態(tài)微調(diào)。開(kāi)了動(dòng)態(tài)延遲功能后RTL里可以通過(guò)一個(gè)總線把延遲值設(shè)置寫入IP核也可以用ILA在線調(diào)試時(shí)直接改輸入直到眼圖中央落在采樣點(diǎn)上。7系列的IDELAY單步分辨率大約是幾十皮秒實(shí)際調(diào)節(jié)的時(shí)候每步效果可能并不明顯但多調(diào)幾步就能看到邊界這個(gè)過(guò)程本質(zhì)上就是板級(jí)“找眼圖中央”的數(shù)字化實(shí)現(xiàn)。5. 工程調(diào)試實(shí)錄常見(jiàn)報(bào)錯(cuò)、信號(hào)質(zhì)量與排錯(cuò)速查表5.1 最典型的DRC/實(shí)現(xiàn)報(bào)錯(cuò)DRC RTSTAT-2這個(gè)報(bào)錯(cuò)在搜索熱詞里都出現(xiàn)了含義是某個(gè)信號(hào)的邏輯連接不是最優(yōu)。Vivado對(duì)IP核接口如果連接了不合適的邏輯比如IO輸出直接進(jìn)了普通LUT而不是IO資源就會(huì)報(bào)這種錯(cuò)誤。排查時(shí)回到原理圖和約束文件確認(rèn)IP核的引腳連接肯定是對(duì)應(yīng)的物理引腳并且沒(méi)有經(jīng)過(guò)額外的組合邏輯。Bank VCCO mismatch如果你在VCCO3.3V的bank上選了LVDS_25或者反過(guò)來(lái)在VCCO1.8V的bank上選了LVDS_25Vivado會(huì)在實(shí)現(xiàn)時(shí)給出警告甚至直接報(bào)錯(cuò)說(shuō)IOSTANDARD和bank電壓不匹配。這時(shí)候不是改約束就完事而是要從原理圖層面確認(rèn)這個(gè)bank的供電到底是多少曾經(jīng)有人把XDC里的IOSTANDARD改成IBUF_NOT_DIFF去繞過(guò)檢查結(jié)果硬件啥反應(yīng)都沒(méi)有。Bitslip/FIFO Overflow一定概率上板后ILA里看到數(shù)據(jù)顯示其實(shí)正確但內(nèi)部FIFO或者狀態(tài)機(jī)偶爾報(bào)溢出。這不是IP核的問(wèn)題而是你的內(nèi)部邏輯時(shí)鐘和并行數(shù)據(jù)時(shí)鐘不是同一個(gè)時(shí)鐘域跨時(shí)鐘域處理沒(méi)做對(duì)。建議把ILA的采樣時(shí)鐘直接接在IP核輸出的clk_out上先排除跨時(shí)鐘域因素。5.2 信號(hào)完整性問(wèn)題和硬件排查實(shí)錄LVDS調(diào)試還有個(gè)特點(diǎn)邏輯上全對(duì)物理上全錯(cuò)。所謂物理上全錯(cuò)主要是信號(hào)質(zhì)量相關(guān)最典型的場(chǎng)景就是用內(nèi)部DIFF_TERM時(shí)人眼看到ILA數(shù)據(jù)偶爾會(huì)跳變但示波器探針能測(cè)到振鈴和過(guò)沖。這種問(wèn)題在短距離幾厘米到幾十厘米通常不嚴(yán)重但線纜稍長(zhǎng)或者PCB層疊走線有問(wèn)題就麻煩了。判斷到底是FPGA內(nèi)部問(wèn)題還是外部信號(hào)問(wèn)題最直接的辦法是寫一個(gè)loopback測(cè)試把FPGA的LVDS輸出引腳用短跳線或板上走線直接連回輸入引腳然后發(fā)送PRBS數(shù)據(jù)統(tǒng)計(jì)誤碼率。如果loopback沒(méi)問(wèn)題說(shuō)明問(wèn)題在外部器件或鏈路如果loopback都有錯(cuò)那優(yōu)先檢查FPGA側(cè)的信號(hào)完整性和終端電阻。另外7系列里你可以用IBERT這個(gè)工具對(duì)一些高速收發(fā)器做眼圖掃描但普通LVDS引腳沒(méi)有專門的硬件眼圖掃描功能所以很多時(shí)候只能靠ILA抓數(shù)據(jù)和示波器看波形來(lái)交叉判斷。有一回我調(diào)試一塊ADC板ILA里看到數(shù)據(jù)低位偶爾翻轉(zhuǎn)檢查所有配置都沒(méi)發(fā)現(xiàn)問(wèn)題最后用示波器在引腳上量到時(shí)鐘信號(hào)邊沿有很明顯的振鈴原因是PCB走線跨了一個(gè)分割的地平面。后來(lái)把地平面補(bǔ)完整問(wèn)題就消失了。這類問(wèn)題用XDC去修是修不出來(lái)的必須回到硬件設(shè)計(jì)本身。5.3 常見(jiàn)問(wèn)題速查表現(xiàn)象可能原因排查建議delay_locked一直為低delay_refclk未注入或頻率不對(duì)用ILA或chipscope看參考時(shí)鐘頻率確認(rèn)穩(wěn)定且為200MHz附近輸入數(shù)據(jù)全是0或全1LVDS電平標(biāo)準(zhǔn)選錯(cuò)或P/N接反檢查VCCO、IOSTANDARD用示波器看P/N是否有差分波形數(shù)據(jù)能出但錯(cuò)位未做bitslip對(duì)齊發(fā)送訓(xùn)練碼用狀態(tài)機(jī)掃描bitslip某個(gè)通道偶爾翻轉(zhuǎn)延遲踩在數(shù)據(jù)邊沿上微調(diào)IDELAY步數(shù)或用TEACH重新訓(xùn)練Vivado報(bào)DRC RTSTAT-2IP核接口連接了非預(yù)期邏輯/引腳檢查引腳約束和RTL連接高低溫下誤碼率變化延遲鏈隨溫度漂移改用動(dòng)態(tài)延遲用訓(xùn)練碼定期校準(zhǔn)內(nèi)部DIFF_TERM打開(kāi)后功耗偏高終端電阻在傳輸時(shí)持續(xù)消耗評(píng)估鏈路長(zhǎng)度必要時(shí)改為外部100歐電阻6. 寫在實(shí)際項(xiàng)目后的一些建議我這幾年用SelectIO IP核做LVDS接口總體的心得是這個(gè)IP核只是把底層原語(yǔ)封裝得很好但它不能替代硬件設(shè)計(jì)層面的思考。VCCO匹配、差分對(duì)引腳成對(duì)、終端電阻位置、參考時(shí)鐘干凈、訓(xùn)練碼對(duì)齊這些才是決定一個(gè)LVDS鏈路能不能穩(wěn)定工作的基本盤。配置界面上點(diǎn)幾下鼠標(biāo)永遠(yuǎn)是最快的部分真正花時(shí)間的是后面的約束和調(diào)試驗(yàn)證。最后分享一個(gè)實(shí)際操作上的小訣竅頭一次調(diào)LVDS時(shí)BITSLIP狀態(tài)機(jī)不要做太復(fù)雜先手動(dòng)在ILA的VIO里逐個(gè)拉高bitslip觀察并行數(shù)據(jù)的變化規(guī)律確認(rèn)每個(gè)通道對(duì)bitslip的響應(yīng)和預(yù)期一致再寫自動(dòng)對(duì)齊邏輯。這樣既能把訓(xùn)練碼邏輯錯(cuò)誤和物理連接問(wèn)題分開(kāi)定位也能讓你更快理解bitslip的影響機(jī)制。7系列的老架構(gòu)雖然不像UltraScale那么花哨但勝在資料多、夠穩(wěn)定好好理解了這套LVDS實(shí)現(xiàn)路徑后面切任何平臺(tái)都會(huì)輕松很多。