本文转载自:十年老鸟的CSDN博客
注:本文由作者授权转发,如需转载请联系作者本人
前言
高速串行Transceiver是FPGA的精华所在,没用过它都不好意思说自己是玩FPGA的。但其复杂的结构确实劝退了一大波人。尽管目前xilinx的example已经做的很牛逼了,可以帮我们把大部分不关系的逻辑和时序都封装起来不用我们管。但有时候还是希望能够学习的更深入点,更多的了解其架构。
接下来,我们就看图说话——从IP核的时钟配置来学习transceiver的参考时钟架构细节。
IP核的部分设置
这里使用的是Serdes系列总结——Xilinx serdes IP使用(一)——3G serdes这篇文章中的例子,我们来详细看一下参考时钟部分的设置
1、这是器件所有transceiver的一个指示图,包含了Quad0、Quad1、Quad2、Quad3。在我们的实例中我们使用的是Quad3
2、Quad3中的四条lane我们都用上了
3、PLL可以选择CPLL和QPLL,这里我们使用的是QPLL
TX/RX Clock Source时钟源使用的是REFCLK0 Q3。实际上我们还可以选择
REFCLK0 Q2、REFCLK1 Q2、REFCLK0 Q3、REFCLK1 Q3
Xilinx的example实在是比较强大,我们不需要太理解transceiver里面的细节我们就能用起来了,但是呢,不出问题还好。一出问题的话也就无从下手了。transceiver模块中引出来的引脚虽然正常情况下大部分都用不上。但异常的时候定位的问题的时候可能就需要他们来进行排查了。
好了,以上就是transceiver的时钟源的设置。我们带着以下问题。
1、 Quad0、Quad1、Quad2、Quad3的定义是什么?
2、 REFCLK0 Q2、REFCLK1 Q2这些时钟输入的架构?
3、 QPLL输入为什么可以选择4个 输入源?
4、 使用QPLL还是CPLL?
这一节,我们就搞清楚参考时钟的方方面面。
Quad 的定义是什么?
我们假定我们的收发器类型是GTX。
Quad是由以下一些元件构成:
1、 4个GTXE2_CHANNEL 原语
2、 1个GTXE2_COMMON 原语
3、 2对专用外部参考时钟输入差分管脚
4、 专用参考时钟路由
使用QPLL还是CPLL
数据手册中对于QPLL和CPLL有比较详细的说明,这边就不在详细的阐述了,因为这个东西似乎对于我们关系不太大,因为只要你在transceiver wizard设置好之后就行了,具体细节就算了解也用处不大。
我们只要知道的是
QPLL支持的线速率是大于CPLL的,因此我一般来说都是直接用QPLL。
REFCLK0 Q2、REFCLK1 Q2这些时钟输入的架构?
参考时钟输入架构如下图所示,其使用IBUFDS_GTE2原语进行例化。
原语模型:
IBUFDS_GTE2 #( .CLKCM_CFG("TRUE"), // Refer to Transceiver User Guide .CLKRCV_TRST("TRUE"), // Refer to Transceiver User Guide .CLKSWING_CFG(2'b11) // Refer to Transceiver User Guide ) IBUFDS_GTE2_inst ( .O(O), // 1-bit output: Refer to Transceiver User Guide .ODIV2(ODIV2), // 1-bit output: Refer to Transceiver User Guide .CEB(CEB), // 1-bit input: Refer to Transceiver User Guide .I(I), // 1-bit input: Refer to Transceiver User Guide .IB(IB) // 1-bit input: Refer to Transceiver User Guide );
实际使用:
assign Q3_CLK0_GTREFCLK_OUT = q3_clk0_gtrefclk; //IBUFDS_GTE2 IBUFDS_GTE2 ibufds_instQ3_CLK0 ( .O (q3_clk0_gtrefclk), .ODIV2 (), .CEB (tied_to_ground_i), .I (Q3_CLK0_GTREFCLK_PAD_P_IN), .IB (Q3_CLK0_GTREFCLK_PAD_N_IN) );
QPLL输入为什么可以选择4个 输入源?
GTXE2_common中QPLL的输入可以选择
本Quad的两对输入时钟差分对,也可以选择相临近的(手册定义为南和北)两对输入时钟差分对。因为我们使用的是Quad3,已经属于最北边,因此只能使用本地Quad的专用差分输入对REFCLK0 Q3、REFCLK1 Q3、或者南边的输入对REFCLK0 Q2、REFCLK1 Q2
代码中从 IBUFDS_GTE2 的O端口输出后的时钟输入到了GTXE2_COMMON原语中的GTREFCLK0端口,这与我们Wizard上设置的一致。
GTXE2_COMMON # ( // Simulation attributes .SIM_RESET_SPEEDUP (WRAPPER_SIM_GTRESET_SPEEDUP), .SIM_QPLLREFCLK_SEL (SIM_QPLLREFCLK_SEL), .SIM_VERSION ("4.0"), //----------------COMMON BLOCK Attributes--------------- .BIAS_CFG (64'h0000040000001000), .COMMON_CFG (32'h00000000), .QPLL_CFG (27'h06801C1), .QPLL_CLKOUT_CFG (4'b0000), .QPLL_COARSE_FREQ_OVRD (6'b010000), .QPLL_COARSE_FREQ_OVRD_EN (1'b0), .QPLL_CP (10'b0000011111), .QPLL_CP_MONITOR_EN (1'b0), .QPLL_DMONITOR_SEL (1'b0), .QPLL_FBDIV (QPLL_FBDIV_IN), .QPLL_FBDIV_MONITOR_EN (1'b0), .QPLL_FBDIV_RATIO (QPLL_FBDIV_RATIO), .QPLL_INIT_CFG (24'h000006), .QPLL_LOCK_CFG (16'h21E8), .QPLL_LPF (4'b1111), .QPLL_REFCLK_DIV (1) ) gtxe2_common_i ( //----------- Common Block - Dynamic Reconfiguration Port (DRP) ----------- .DRPADDR (tied_to_ground_vec_i[7:0]), .DRPCLK (tied_to_ground_i), .DRPDI (tied_to_ground_vec_i[15:0]), .DRPDO (), .DRPEN (tied_to_ground_i), .DRPRDY (), .DRPWE (tied_to_ground_i), //-------------------- Common Block - Ref Clock Ports --------------------- .GTGREFCLK (GTGREFCLK_IN), .GTNORTHREFCLK0 (GTNORTHREFCLK0_IN), .GTNORTHREFCLK1 (GTNORTHREFCLK1_IN), .GTREFCLK0 (GTREFCLK0_IN), .GTREFCLK1 (GTREFCLK1_IN), .GTSOUTHREFCLK0 (GTSOUTHREFCLK0_IN), .GTSOUTHREFCLK1 (GTSOUTHREFCLK1_IN), //----------------------- Common Block - QPLL Ports ----------------------- .QPLLDMONITOR (), //--------------------- Common Block - Clocking Ports ---------------------- .QPLLOUTCLK (QPLLOUTCLK_OUT), .QPLLOUTREFCLK (QPLLOUTREFCLK_OUT), .REFCLKOUTMONITOR (), //----------------------- Common Block - QPLL Ports ------------------------ .QPLLFBCLKLOST (), .QPLLLOCK (QPLLLOCK_OUT), .QPLLLOCKDETCLK (QPLLLOCKDETCLK_IN), .QPLLLOCKEN (tied_to_vcc_i), .QPLLOUTRESET (tied_to_ground_i), .QPLLPD (tied_to_ground_i), .QPLLREFCLKLOST (QPLLREFCLKLOST_OUT), .QPLLREFCLKSEL (QPLLREFCLKSEL_IN), .QPLLRESET (QPLLRESET_IN), .QPLLRSVD1 (16'b0000000000000000), .QPLLRSVD2 (5'b11111), //------------------------------- QPLL Ports ------------------------------- .BGBYPASSB (tied_to_vcc_i), .BGMONITORENB (tied_to_vcc_i), .BGPDB (tied_to_vcc_i), .BGRCALOVRD (5'b11111), .PMARSVD (8'b00000000), .RCALENB (tied_to_vcc_i) );
注意一些比较重要的信号:
QPLLLOCKDETCLK ,这是用于检测QPLL一些状态的信号,外部连到了drp_clk_i。 QPLLLOCK_OUT:判定QPLL是否锁定 QPLLREFCLKSEL: IN 3’b001,选择的是 GTREFCLK0口作为参考时钟输入 QPLLOUTREFCLK:这是QPLL输入的时钟 QPLLOUTCLK:这是QPLL输出的时钟 QPLLRESET:这是QPLL的复位信号
总结
最后,自己通过画一个参考时钟输入框图,加深印象,并标出其主要输入输出结构,作为结束。