Xilinx FPGA平台GTX简易使用教程(五)

gtx ip配置完了,你不得搞个回环测试一番?
前言
理解一个ip的用法,最好的办法就是打开官方的example design。
所以本文首先介绍example design,然后再替换成我们自己的收发测试模块,对比印证学习,差不多就能勉强把gtx给玩起来了。
一、示例工程example design
接上一讲(四)gtx ip核的配置:
我们配置gtx为:3.125g , 参考时钟156.25mhz ,然后生成了gtx的ip。
首先,右键ip打开example design。
打开示例工程后,看到如下图所示的工程结构:
先简单概括下,示例工程的组成结构,如下图所示的拓扑图:
ok,接下来我们对每个子模块进行分别介绍。
1.1 gtx_support模块
support子模块为gtx主要模块。包含gtx的时钟、复位以及对原语/ip的例化使用。
xilinx为了ip核的通用性,将每个ip的端口设置非常完善也意味着非常复杂。端口信号众多,导致我们一阵头大,不知从何下手,所以这里直接上干货,简要解析各个端口信号,哪些是使用的,哪些是不用的。
ps:很多端口都没有使用,要么置0,要么置1 。
所以,引用b站名言:“消除恐惧的最好办法就是面对恐惧,奥利给!”
直接上代码: 详见后面注释内容!
注:很多功能我们没有用上,所以给的0,实际使用根据具体需求而定。
ip_gtx ip_gtx_init_i
(
.sysclk_in (sysclk_in_i), //系统时钟
.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), //系统时钟
.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), //参考时钟
//-------------------------- channel - drp ports --------------------------
.gt0_drpaddr_in (gt0_drpaddr_in), //0
.gt0_drpclk_in (sysclk_in_i), //系统时钟
.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), // 接收数据
//----------------- 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), // 发生数据
//-------------- 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的时钟子模块。
学习官方例程除了学习ip的用法外,另外一点就是学习官方大佬的代码,学习优秀的代码!包括代码规范、实现方式以及模块划分。
我们自己做项目的时候也要注意这一点,时钟最好单独设计为一个时钟子模块,提供整个工程所需的全部逻辑内部时钟。
用个框图来表示这个模块的功能:
至于具体实现方式,也很简单,用了两个原语:ibufds 、bufg。
后面空了会详细出一个系列专讲xilinx原语。
想要更多了解gtx的时钟,欢迎翻阅本系列第二篇(二)gtx时钟篇。
xilinx fpga平台gtx简易使用教程(二)gtx时钟篇
​​​​​​​1.1.2 gt_common
这个模块主要是对gtxe2_common原语的例化。
原语内容较多,这里不进行介绍。保持默认就好。
​​​​​​​1.1.3 gt_common_reset
顾名思义,这个模块是对common的复位,也就是对qpll的复位。保持默认就好。
实际上,我们进一步研究示例就会发现,该复位根本没有使用!为什么呢?不复位也能正常工作?对复位有兴趣的欢迎翻阅系列第三篇(三)gtx复位与初始化。
xilinx fpga平台gtx简易使用教程(三)gtx复位与初始化​​​​​
1.2 frame_gen
开门见山的说,这就是一个数据产生模块。只用于仿真测试,仔细研究你就发现它数据产生的方式比较有意思:从文件中读取!我们再回到工程结构目录,会看到有两个data files:
gt_rom_init_rx.dat、gt_rom_init_tx.dat
一个发送数据的文件,一个接收数据的文件。
再打开发送这个文件,如下图所示:
至于具体怎么实现文件数据读取,后面空了笔者也会出一篇文章,介绍在仿真中,对文件的读和写。
​​​​​​​1.3 frame_check
数据检查模块,将接收到的数据和发送的数据进行比对,如果有误,就给error信号。可以学习这种设计思路,保障数据收发的准确性。
二、gtx收发测试
gtx的示例工程基本介绍完毕,但是那毕竟是别人的。如果我们自己想把gtx跑起来呢?很简单,把示例工程的frame_gen数据产生模块删掉,换上我们自己的发送数据模块packet_send;将frame_check数据检查模块删掉,换上我们自己的接收数据模块packet_recv。最后加个top顶层,将packet_send、packet_recv、gt_support三个模块连起来就好。
注:测试工程为回环,发送端口直接怼到接收端口。
2.1 对support模块的整合
support模块前面已经介绍过,是使用gtx的核心。所以我们对gtx的使用也是基于该模块。
直接上干货吧,需要做以下改动:
将发送/接收数据端口开放到外层,top才能模块连接;包含数据总线tx/rx_data和控制总线tx/rx_charisk;
将gt0_data_valid_in信号直接置1;
2.2发送模块
添加我们需要发送的数据,可以加上帧头(sof)、帧尾(eof)信号便于接收模块判断。
发送模块需要输出两个信号(这里的位宽由gtx ip配置决定):
tx_data[31:0] :需要发送的数据
tx_char[3:0] :k码指示,每1bit对应1个字节的数据;0:表示发送的是数据;1:表示发送的是k码。
需要注意的是,在发送数据之前要先发一个k码,以便接收数据对齐。
2.3接收模块
对gtx接收到的数据进一步处理,可通过检测帧头(sof)、帧尾(eof)信号,来接收一个完整的帧数据。也可以对接收的数据与发送数据比对,检查是否有误。
没什么好讲的,略过吧。
2.4仿真验证
仿真tb文件主要产生时钟激励,和产生需要发送的数据。
因为我们是回环,所以记得tb里面将tx / rx进行短接,注意_n对_n,_p对_p。
另外值得一提的是,我们参考时候为差分输入,这里简单提供一种差分时钟的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;
最后,我们来看一下仿真结果:
输入: 0-100的累加数(只截取了0-7)
输出:0-100的累加数(只截取了0-7)
ok,回环完成。
后记
整个gtx的介绍到这里暂告一段落,待笔者对齐有进一步更深的理解时再做补充。补充内容可能包括具体项目应用、gt高速接口的底层原理等。
按照笔者的习惯,基本以原理介绍、系统组成、方案设计为主,而对于具体的代码,笔者是不会在文章中具体写出来的。所以,这些测试工程我后面会以文件的形式放上来。
下一个系列,我们将开始srio。
随笔者一起,将接口撸个遍吧!


美格智能携手高通 “进5G,博前沿,会天下”
苹果 iPhone 8 销售量将破纪录将远超 iPhone 6
SemiLEDs公布2019年财年第一季度的财务业绩 收入为97.2万美元毛利率为负23%
小米提交2种不同样式的折叠屏专利 摄像头采用升降式五摄设计
第十二届中国制造业产品创新数字化国际峰会即将盛大开幕
Xilinx FPGA平台GTX简易使用教程(五)
多家厂商展示Micro及MiniLED新品
快速PCB制版的方法有哪些
云服务是智能升级的必由之路,打造全场景智慧的硬科技西安
液压电磁阀符号_怎么控制液压电磁阀
【曦哥论币】3.27主流货币比特币行情分析总结一下有策略但还是赚不到钱!
光伏汇流采集装置是什么,它有什么作用
Nordic超低功耗窄带蜂窝nRF9160的典型应用
差分探头的具体用法以及在什么情况下使用差分探头
高性能模拟前端信号链解决方案,助力医疗超声系统发展
变压器输出电压过高如何调节
特斯拉如何执行最后的交车过程
CTA200高精度电流互感器参数指标介绍
5G商用带动基站建设通信领域PCB核心供应商将受益
巴航工业的E195-E2飞机已获得了三家监管机构颁发的型号认证