GTX IP配置完了,你不得搞個(gè)回環(huán)測試一番?
前言
理解一個(gè)IP的用法,最好的辦法就是打開官方的Example Design。
所以本文首先介紹Example Design,然后再替換成我們自己的收發(fā)測試模塊,對比印證學(xué)習(xí),差不多就能勉強(qiáng)把GTX給玩起來了。
一、示例工程Example Design
接上一講(四)GTX IP核的配置:
我們配置GTX為:3.125G , 參考時(shí)鐘156.25Mhz ,然后生成了GTX的IP。
首先,右鍵IP打開Example Design。
打開示例工程后,看到如下圖所示的工程結(jié)構(gòu):
先簡單概括下,示例工程的組成結(jié)構(gòu),如下圖所示的拓?fù)鋱D:
OK,接下來我們對每個(gè)子模塊進(jìn)行分別介紹。
1.1 gtx_support模塊
support子模塊為GTX主要模塊。包含GTX的時(shí)鐘、復(fù)位以及對原語/IP的例化使用。
Xilinx為了IP核的通用性,將每個(gè)IP的端口設(shè)置非常完善也意味著非常復(fù)雜。端口信號眾多,導(dǎo)致我們一陣頭大,不知從何下手,所以這里直接上干貨,簡要解析各個(gè)端口信號,哪些是使用的,哪些是不用的。
PS:很多端口都沒有使用,要么置0,要么置1 。
所以,引用B站名言:“消除恐懼的最好辦法就是面對恐懼,奧利給!”
直接上代碼: 詳見后面注釋內(nèi)容!
注:很多功能我們沒有用上,所以給的0,實(shí)際使用根據(jù)具體需求而定。
ip_gtx ip_gtx_init_i
(
.sysclk_in (sysclk_in_i), //系統(tǒng)時(shí)鐘
.soft_reset_tx_in (soft_reset_tx_in), //0
.soft_reset_rx_in (soft_reset_rx_in), //0
.dont_reset_on_data_error_in (dont_reset_on_data_error_in), //0
.gt0_tx_fsm_reset_done_out (gt0_tx_fsm_reset_done_out), //output
.gt0_rx_fsm_reset_done_out (gt0_rx_fsm_reset_done_out), //output
.gt0_data_valid_in (gt0_data_valid_in), //1
//GT0 (X1Y0)
//------------------------------- CPLL Ports -------------------------------
.gt0_cpllfbclklost_out (gt0_cpllfbclklost_out),
.gt0_cplllock_out (gt0_cplllock_out),
.gt0_cplllockdetclk_in (sysclk_in_i), //系統(tǒng)時(shí)鐘
.gt0_cpllreset_in (gt0_cpllreset_in), //0
//------------------------ Channel - Clocking Ports ------------------------
.gt0_gtrefclk0_in (tied_to_ground_i), //0
.gt0_gtrefclk1_in (q0_clk1_refclk_i), //參考時(shí)鐘
//-------------------------- Channel - DRP Ports --------------------------
.gt0_drpaddr_in (gt0_drpaddr_in), //0
.gt0_drpclk_in (sysclk_in_i), //系統(tǒng)時(shí)鐘
.gt0_drpdi_in (gt0_drpdi_in), //0
.gt0_drpdo_out (gt0_drpdo_out), //0
.gt0_drpen_in (gt0_drpen_in), //0
.gt0_drprdy_out (gt0_drprdy_out), //0
.gt0_drpwe_in (gt0_drpwe_in), //0
//------------------------- Digital Monitor Ports --------------------------
.gt0_dmonitorout_out (gt0_dmonitorout_out), // output
//----------------------------- Loopback Ports -----------------------------
.gt0_loopback_in (gt0_loopback_in), //0
//---------------------------- Power-Down Ports ----------------------------
.gt0_rxpd_in (gt0_rxpd_in), //0
.gt0_txpd_in (gt0_txpd_in), //0
//------------------- RX Initialization and Reset Ports --------------------
.gt0_eyescanreset_in (gt0_eyescanreset_in), //0
.gt0_rxuserrdy_in (gt0_rxuserrdy_in), //1
//------------------------ RX Margin Analysis Ports ------------------------
.gt0_eyescandataerror_out (gt0_eyescandataerror_out), // output
.gt0_eyescantrigger_in (gt0_eyescantrigger_in), //0
//----------------------- Receive Ports - CDR Ports ------------------------
.gt0_rxcdrhold_in (gt0_rxcdrhold_in), //0
//----------------- Receive Ports - Clock Correction Ports -----------------
.gt0_rxclkcorcnt_out (gt0_rxclkcorcnt_out), // output
//---------------- Receive Ports - FPGA RX Interface Ports -----------------
.gt0_rxusrclk_in (gt0_rxusrclk_i), // rxusrclk
.gt0_rxusrclk2_in (gt0_rxusrclk2_i), // rxusrclk2
//---------------- Receive Ports - FPGA RX interface Ports -----------------
.gt0_rxdata_out (gt0_rxdata_out), // 接收數(shù)據(jù)
//----------------- Receive Ports - Pattern Checker Ports ------------------
.gt0_rxprbserr_out (gt0_rxprbserr_out), // output
.gt0_rxprbssel_in (gt0_rxprbssel_in), // 0
//----------------- Receive Ports - Pattern Checker ports ------------------
.gt0_rxprbscntreset_in (gt0_rxprbscntreset_in), // 0
//---------------- Receive Ports - RX 8B/10B Decoder Ports -----------------
.gt0_rxdisperr_out (gt0_rxdisperr_out), // output
.gt0_rxnotintable_out (gt0_rxnotintable_out), // output
//------------------------- Receive Ports - RX AFE -------------------------
.gt0_gtxrxp_in (gt0_gtxrxp_in), // 管腳RXP
//---------------------- Receive Ports - RX AFE Ports ----------------------
.gt0_gtxrxn_in (gt0_gtxrxn_in), // 管腳RXN
//------------------- Receive Ports - RX Equalizer Ports -------------------
.gt0_rxdfelpmreset_in (gt0_rxdfelpmreset_in), // 0
.gt0_rxmonitorout_out (gt0_rxmonitorout_out), // 0
.gt0_rxmonitorsel_in (gt0_rxmonitorsel_in), // 0
//------------- Receive Ports - RX Fabric Output Control Ports -------------
.gt0_rxoutclkfabric_out (gt0_rxoutclkfabric_out), // output
//----------- Receive Ports - RX Initialization and Reset Ports ------------
.gt0_gtrxreset_in (gt0_gtrxreset_in), // 0
.gt0_rxpmareset_in (gt0_rxpmareset_in), // 0
//----------------- Receive Ports - RX8B/10B Decoder Ports -----------------
.gt0_rxchariscomma_out (gt0_rxchariscomma_out), // output
.gt0_rxcharisk_out (gt0_rxcharisk_out), // rxcharisk
//------------ Receive Ports -RX Initialization and Reset Ports ------------
.gt0_rxresetdone_out (gt0_rxresetdone_out), // output
//------------------- TX Initialization and Reset Ports --------------------
.gt0_gttxreset_in (gt0_gttxreset_in), // 0
.gt0_txuserrdy_in (gt0_txuserrdy_in), // 1
//-------------- Transmit Ports - 8b10b Encoder Control Ports --------------
.gt0_txchardispmode_in (gt0_txchardispmode_in), // 0
.gt0_txchardispval_in (gt0_txchardispval_in), // 0
//---------------- Transmit Ports - FPGA TX Interface Ports ----------------
.gt0_txusrclk_in (gt0_txusrclk_i), // txusrclk
.gt0_txusrclk2_in (gt0_txusrclk2_i), // txusrclk2
//---------------- Transmit Ports - Pattern Generator Ports ----------------
.gt0_txprbsforceerr_in (gt0_txprbsforceerr_in), // 0
//-------------------- Transmit Ports - TX Buffer Ports --------------------
.gt0_txbufstatus_out (gt0_txbufstatus_out), // output
//---------------- Transmit Ports - TX Data Path interface -----------------
.gt0_txdata_in (gt0_txdata_in), // 發(fā)生數(shù)據(jù)
//-------------- Transmit Ports - TX Driver and OOB signaling --------------
.gt0_gtxtxn_out (gt0_gtxtxn_out), // 管腳TXN
.gt0_gtxtxp_out (gt0_gtxtxp_out), // 管腳TXP
//--------- Transmit Ports - TX Fabric Clock Output Control Ports ----------
.gt0_txoutclk_out (gt0_txoutclk_i), // output
.gt0_txoutclkfabric_out (gt0_txoutclkfabric_out), // output
.gt0_txoutclkpcs_out (gt0_txoutclkpcs_out), // output
//------------------- Transmit Ports - TX Gearbox Ports --------------------
.gt0_txcharisk_in (gt0_txcharisk_in), // txcharisk
//----------- Transmit Ports - TX Initialization and Reset Ports -----------
.gt0_txresetdone_out (gt0_txresetdone_out), // output
//---------------- Transmit Ports - pattern Generator Ports ----------------
.gt0_txprbssel_in (gt0_txprbssel_in), // 0
.gt0_qplloutclk_in (gt0_qplloutclk_i), // from common
.gt0_qplloutrefclk_in (gt0_qplloutrefclk_i) // from common
);
1.1.1 gt_usrclk_source
GTX的時(shí)鐘子模塊。
學(xué)習(xí)官方例程除了學(xué)習(xí)IP的用法外,另外一點(diǎn)就是學(xué)習(xí)官方大佬的代碼,學(xué)習(xí)優(yōu)秀的代碼!包括代碼規(guī)范、實(shí)現(xiàn)方式以及模塊劃分。
我們自己做項(xiàng)目的時(shí)候也要注意這一點(diǎn),時(shí)鐘最好單獨(dú)設(shè)計(jì)為一個(gè)時(shí)鐘子模塊,提供整個(gè)工程所需的全部邏輯內(nèi)部時(shí)鐘。
用個(gè)框圖來表示這個(gè)模塊的功能:
至于具體實(shí)現(xiàn)方式,也很簡單,用了兩個(gè)原語:IBUFDS 、BUFG。
后面空了會詳細(xì)出一個(gè)系列專講Xilinx原語。
想要更多了解GTX的時(shí)鐘,歡迎翻閱本系列第二篇(二)GTX時(shí)鐘篇。
Xilinx FPGA平臺GTX簡易使用教程(二)GTX時(shí)鐘篇
???????1.1.2 gt_common
這個(gè)模塊主要是對GTXE2_COMMON原語的例化。
原語內(nèi)容較多,這里不進(jìn)行介紹。保持默認(rèn)就好。
???????1.1.3 gt_common_reset
顧名思義,這個(gè)模塊是對common的復(fù)位,也就是對QPLL的復(fù)位。保持默認(rèn)就好。
實(shí)際上,我們進(jìn)一步研究示例就會發(fā)現(xiàn),該復(fù)位根本沒有使用!為什么呢?不復(fù)位也能正常工作?對復(fù)位有興趣的歡迎翻閱系列第三篇(三)GTX復(fù)位與初始化。
Xilinx FPGA平臺GTX簡易使用教程(三)GTX復(fù)位與初始化?????
1.2 frame_gen
開門見山的說,這就是一個(gè)數(shù)據(jù)產(chǎn)生模塊。只用于仿真測試,仔細(xì)研究你就發(fā)現(xiàn)它數(shù)據(jù)產(chǎn)生的方式比較有意思:從文件中讀取!我們再回到工程結(jié)構(gòu)目錄,會看到有兩個(gè)Data Files:
gt_rom_init_rx.dat、gt_rom_init_tx.dat
一個(gè)發(fā)送數(shù)據(jù)的文件,一個(gè)接收數(shù)據(jù)的文件。
再打開發(fā)送這個(gè)文件,如下圖所示:
至于具體怎么實(shí)現(xiàn)文件數(shù)據(jù)讀取,后面空了筆者也會出一篇文章,介紹在仿真中,對文件的讀和寫。
???????1.3 frame_check
數(shù)據(jù)檢查模塊,將接收到的數(shù)據(jù)和發(fā)送的數(shù)據(jù)進(jìn)行比對,如果有誤,就給error信號??梢詫W(xué)習(xí)這種設(shè)計(jì)思路,保障數(shù)據(jù)收發(fā)的準(zhǔn)確性。
二、GTX收發(fā)測試
GTX的示例工程基本介紹完畢,但是那畢竟是別人的。如果我們自己想把GTX跑起來呢?很簡單,把示例工程的frame_gen數(shù)據(jù)產(chǎn)生模塊刪掉,換上我們自己的發(fā)送數(shù)據(jù)模塊packet_send;將frame_check數(shù)據(jù)檢查模塊刪掉,換上我們自己的接收數(shù)據(jù)模塊packet_recv。最后加個(gè)TOP頂層,將packet_send、packet_recv、gt_support三個(gè)模塊連起來就好。
注:測試工程為回環(huán),發(fā)送端口直接懟到接收端口。
2.1 對support模塊的整合
support模塊前面已經(jīng)介紹過,是使用GTX的核心。所以我們對GTX的使用也是基于該模塊。
直接上干貨吧,需要做以下改動:
將發(fā)送/接收數(shù)據(jù)端口開放到外層,TOP才能模塊連接;包含數(shù)據(jù)總線tx/rx_data和控制總線tx/rx_charisk;
將gt0_data_valid_in信號直接置1;
2.2發(fā)送模塊
添加我們需要發(fā)送的數(shù)據(jù),可以加上幀頭(sof)、幀尾(eof)信號便于接收模塊判斷。
發(fā)送模塊需要輸出兩個(gè)信號(這里的位寬由GTX IP配置決定):
tx_data[31:0] :需要發(fā)送的數(shù)據(jù)
tx_char[3:0] :K碼指示,每1bit對應(yīng)1個(gè)字節(jié)的數(shù)據(jù);0:表示發(fā)送的是數(shù)據(jù);1:表示發(fā)送的是K碼。
需要注意的是,在發(fā)送數(shù)據(jù)之前要先發(fā)一個(gè)K碼,以便接收數(shù)據(jù)對齊。
2.3接收模塊
對GTX接收到的數(shù)據(jù)進(jìn)一步處理,可通過檢測幀頭(sof)、幀尾(eof)信號,來接收一個(gè)完整的幀數(shù)據(jù)。也可以對接收的數(shù)據(jù)與發(fā)送數(shù)據(jù)比對,檢查是否有誤。
沒什么好講的,略過吧。
2.4仿真驗(yàn)證
仿真tb文件主要產(chǎn)生時(shí)鐘激勵,和產(chǎn)生需要發(fā)送的數(shù)據(jù)。
因?yàn)槲覀兪腔丨h(huán),所以記得tb里面將TX / RX進(jìn)行短接,注意_N對_N,_P對_P。
另外值得一提的是,我們參考時(shí)候?yàn)椴罘州斎?,這里簡單提供一種差分時(shí)鐘的testbench寫法:
wire Q0_CLK1_GTREFCLK_PAD_N_IN;
reg Q0_CLK1_GTREFCLK_PAD_P_IN;
wire DRP_CLK_IN_N;
reg DRP_CLK_IN_P;
initial begin
Q0_CLK1_GTREFCLK_PAD_P_IN = 0;
DRP_CLK_IN_P = 0;
end
always #3.2 Q0_CLK1_GTREFCLK_PAD_P_IN = ~Q0_CLK1_GTREFCLK_PAD_P_IN;
always #5 DRP_CLK_IN_P = ~DRP_CLK_IN_P;
assign Q0_CLK1_GTREFCLK_PAD_N_IN = ~Q0_CLK1_GTREFCLK_PAD_P_IN;
assign DRP_CLK_IN_N = ~DRP_CLK_IN_P;
最后,我們來看一下仿真結(jié)果:
輸入: 0-100的累加數(shù)(只截取了0-7)
輸出:0-100的累加數(shù)(只截取了0-7)
OK,回環(huán)完成。
后記
整個(gè)GTX的介紹到這里暫告一段落,待筆者對齊有進(jìn)一步更深的理解時(shí)再做補(bǔ)充。補(bǔ)充內(nèi)容可能包括具體項(xiàng)目應(yīng)用、GT高速接口的底層原理等。
按照筆者的習(xí)慣,基本以原理介紹、系統(tǒng)組成、方案設(shè)計(jì)為主,而對于具體的代碼,筆者是不會在文章中具體寫出來的。所以,這些測試工程我后面會以文件的形式放上來。
下一個(gè)系列,我們將開始SRIO。
隨筆者一起,將接口擼個(gè)遍吧!
審核編輯:湯梓紅
-
FPGA
+關(guān)注
關(guān)注
1629文章
21759瀏覽量
604271 -
GTX
+關(guān)注
關(guān)注
0文章
35瀏覽量
10924
發(fā)布評論請先 登錄
相關(guān)推薦
評論