Xilinx FPGA资源解析与使用系列——Transceiver(一)参考时钟解析

本文转载自:十年老鸟的CSDN博客

注:本文由作者授权转发,如需转载请联系作者本人

前言

高速串行Transceiver是FPGA的精华所在,没用过它都不好意思说自己是玩FPGA的。但其复杂的结构确实劝退了一大波人。尽管目前xilinx的example已经做的很牛逼了,可以帮我们把大部分不关系的逻辑和时序都封装起来不用我们管。但有时候还是希望能够学习的更深入点,更多的了解其架构。

接下来,我们就看图说话——从IP核的时钟配置来学习transceiver的参考时钟架构细节。

IP核的部分设置

这里使用的是Serdes系列总结——Xilinx serdes IP使用(一)——3G serdes这篇文章中的例子,我们来详细看一下参考时钟部分的设置

1、这是器件所有transceiver的一个指示图,包含了Quad0、Quad1、Quad2、Quad3。在我们的实例中我们使用的是Quad3

1.png

2、Quad3中的四条lane我们都用上了

2.png

3、PLL可以选择CPLL和QPLL,这里我们使用的是QPLL
TX/RX Clock Source时钟源使用的是REFCLK0 Q3。实际上我们还可以选择
REFCLK0 Q2、REFCLK1 Q2、REFCLK0 Q3、REFCLK1 Q3

3.png

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、 专用参考时钟路由

4.png

使用QPLL还是CPLL

数据手册中对于QPLL和CPLL有比较详细的说明,这边就不在详细的阐述了,因为这个东西似乎对于我们关系不太大,因为只要你在transceiver wizard设置好之后就行了,具体细节就算了解也用处不大。

我们只要知道的是

QPLL支持的线速率是大于CPLL的,因此我一般来说都是直接用QPLL。

5.png

REFCLK0 Q2、REFCLK1 Q2这些时钟输入的架构?

参考时钟输入架构如下图所示,其使用IBUFDS_GTE2原语进行例化。

6.png

原语模型:

  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
   );

7.png

实际使用:

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

8.png

代码中从 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的复位信号

总结

最后,自己通过画一个参考时钟输入框图,加深印象,并标出其主要输入输出结构,作为结束。

9.png

最新文章