当前位置:   article > 正文

基于8B10B的GT收发器PHY层设计(2)GT_module模块设计

基于8B10B的GT收发器PHY层设计(2)GT_module模块设计

前言

根据官方的example design设计一个自定义协议的高速PHY设计

一、设计框图

在这里插入图片描述
设计思路及代码思路参考FPGA奇哥系列网课
IP核解析参考xilinx文档PG168 7 Series FPGAs Transceiver Wizard v3.6

二、例化IP核端口

即框图当中的gtwizard_0模块
所有端口含义都可以在PG168当中进行了解
需要特别关注的在代码里进行了简单的注释

gtwizard_0  gtwizard_0_i
(
    .sysclk_in                      (i_sysclk               ), //SYSCLK是一个自由运行的系统/板载时钟,用于驱动示例设计中的FPGA逻辑。当启用DRP接口时,DRP_CLK连接到示例设计中的SYSCLK。需要在XDC中对此时钟进行约束。
    .soft_reset_tx_in               (i_tx_rst               ), 
    .soft_reset_rx_in               (i_rx_rst               ), 
    .dont_reset_on_data_error_in    (0                      ), 
    .gt0_tx_fsm_reset_done_out      (o_tx_done              ),
    .gt0_rx_fsm_reset_done_out      (),     
    .gt0_data_valid_in              (1                      ), 
    .gt0_tx_mmcm_lock_in            (gt0_txmmcm_lock_i      ), 
    .gt0_tx_mmcm_reset_out          (gt0_txmmcm_reset_i     ), 
    .gt0_rx_mmcm_lock_in            (gt0_rxmmcm_lock_i      ),
    .gt0_rx_mmcm_reset_out          (gt0_rxmmcm_reset_i     ), 
    .gt0_drpaddr_in                 (i_drpaddr              ),     
    .gt0_drpclk_in                  (i_sysclk               ),     
    .gt0_drpdi_in                   (i_drpdi                ),     
    .gt0_drpdo_out                  (o_drpdo                ),     
    .gt0_drpen_in                   (i_drpen                ),     
    .gt0_drprdy_out                 (o_drprdy               ),     
    .gt0_drpwe_in                   (i_drpwe                ),     

    .gt0_dmonitorout_out            (),     
    .gt0_loopback_in                (i_loopback             ),  
    .gt0_eyescanreset_in            (0                      ), 
    .gt0_rxuserrdy_in               (1                      ),
    .gt0_eyescandataerror_out       (), 
    .gt0_eyescantrigger_in          (0                      ),
    .gt0_rxclkcorcnt_out            (                       ),
    .gt0_rxusrclk_in                (gt0_rxusrclk_i         ), 
    .gt0_rxusrclk2_in               (gt0_rxusrclk2_i        ), 
    .gt0_rxdata_out                 (o_rx_data              ),//接收数据,位宽为IP配置的用户位宽
    .gt0_rxdisperr_out              (), 
    .gt0_rxnotintable_out           (), 
    .gt0_gtxrxp_in                  (i_gt_rx_p              ),//输入差分引脚    
    .gt0_gtxrxn_in                  (i_gt_rx_n              ),//输入差分引脚    
    .gt0_rxbyteisaligned_out        (o_rx_ByteAlign         ),//接收数据字节对齐指示信号
    .gt0_rxdfelpmreset_in           (0                      ), 
    .gt0_rxmonitorout_out           (),     
    .gt0_rxmonitorsel_in            (0                      ), 
    .gt0_rxoutclkfabric_out         (),     
    .gt0_gtrxreset_in               (i_rx_rst               ), 
    .gt0_rxpmareset_in              (i_rx_rst               ), 
    .gt0_rxpolarity_in              (i_rx_polarity          ), 
    .gt0_rxcharisk_out              (o_rx_char              ),//标记接收的有效的8B/10BK字符。高位比特对应数据路径的高位字节。
    .gt0_rxresetdone_out            (o_rx_done              ), 
    .gt0_txpostcursor_in            (i_txpostcursor         ), 
    .gt0_txprecursor_in             (i_txpercursor          ), 
    .gt0_gttxreset_in               (i_tx_rst               ), 
    .gt0_txuserrdy_in               (1                      ), 
    .gt0_txusrclk_in                (gt0_txusrclk_i         ), 
    .gt0_txusrclk2_in               (gt0_txusrclk2_i        ), 
    .gt0_txdiffctrl_in              (i_tx_diffctrl          ), 
    .gt0_txdata_in                  (i_tx_data              ),//与接收同理 
    .gt0_gtxtxn_out                 (o_gt_tx_n              ),//与接收同理     
    .gt0_gtxtxp_out                 (o_gt_tx_p              ),//与接收同理     
    .gt0_txoutclk_out               (gt0_txoutclk_i         ), 
    .gt0_txoutclkfabric_out         (),     
    .gt0_txoutclkpcs_out            (),     
    .gt0_txcharisk_in               (i_tx_char              ),//与接收同理  
    .gt0_txresetdone_out            (),     
    .gt0_txpolarity_in              (i_tx_polarity          ), 

    .gt0_qplllock_in                (i_qplllock             ),
    .gt0_qpllrefclklost_in          (i_qpllrefclklost       ),
    .gt0_qpllreset_out              (w_gt_qpll_reset        ),
    .gt0_qplloutclk_in              (i_qplloutclk           ),
    .gt0_qplloutrefclk_in           (i_qplloutrefclk        ) 
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70

三、common_reset_i模块

用于产生QPLL的复位信号

assign w_qpll_reset = w_commonreset | w_gt_qpll_reset   ;
  • 1
gtwizard_0_common_reset # 
(
    .STABLE_CLOCK_PERIOD            (                       )    
)
common_reset_i
(    
    .STABLE_CLOCK                   (i_sysclk               ),           
    .SOFT_RESET                     (i_tx_rst               ),      
    .COMMON_RESET                   (w_commonreset          )          
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

四、gt_usrclk_source模块

用户时钟的产生模块,发送端和接收端的逻辑需要通过gt0_txusrclk2_igt0_rxusrclk2_i驱动。这里对示例工程里面的gt_usrclk_source进行了简单的修改,在原本的example design里,IBUFDS_GTE2原语被放到了gt_usrclk_source模块里,该模块就是用来将外部差分参考时钟转为单端时钟信号。在原本的gt_usrclk_source里,它将输入的外部差分参考时钟信号转化为单端后又从该模块输出了出去,所以完全可以直接放到顶层去。

gtwizard_0_GT_USRCLK_SOURCE gt_usrclk_source
(
 
    .GT0_TXUSRCLK_OUT           (gt0_txusrclk_i         ),
    .GT0_TXUSRCLK2_OUT          (gt0_txusrclk2_i        ),
    .GT0_TXOUTCLK_IN            (gt0_txoutclk_i         ),
    .GT0_TXCLK_LOCK_OUT         (gt0_txmmcm_lock_i      ),
    .GT0_TX_MMCM_RESET_IN       (gt0_txmmcm_reset_i     ),
    .GT0_RXUSRCLK_OUT           (gt0_rxusrclk_i         ),
    .GT0_RXUSRCLK2_OUT          (gt0_rxusrclk2_i        ),
    .GT0_RXCLK_LOCK_OUT         (gt0_rxmmcm_lock_i      ),
    .GT0_RX_MMCM_RESET_IN       (gt0_rxmmcm_reset_i     )
);  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

五、IBUFDS_GTE2和gtwizard_0_common模块

gtwizard_0_common 就是QPLL,里面例化了一个GTXE2_COMMON原语
gtwizard_0_common 只需要例化一次,因为一个QUAD只有一个QPLL

IBUFDS_GTE2 IBUFDS_GTE2_u0  
(
    .O               (w_gtrefclk    ),
    .ODIV2           (),
    .CEB             (0),
    .I               (i_gtrefclk_p  ),
    .IB              (i_gtrefclk_n  )
);

gtwizard_0_common #
(
    .WRAPPER_SIM_GTRESET_SPEEDUP(),
    .SIM_QPLLREFCLK_SEL         (3'b010)
)
common0_i
(
    .QPLLREFCLKSEL_IN           (3'b010             ),//参考时钟选择如下图所示,具体看自己的板卡接入了哪一路参考时钟
    .GTREFCLK0_IN               (0                  ),
    .GTREFCLK1_IN               (w_gtrefclk         ),
    .QPLLLOCK_OUT               (w_qplllock         ),
    .QPLLLOCKDETCLK_IN          (i_sysclk           ),
    .QPLLOUTCLK_OUT             (w_qplloutclk       ),
    .QPLLOUTREFCLK_OUT          (w_qplloutrefclk    ),
    .QPLLREFCLKLOST_OUT         (w_qpllrefclklost   ),    
    .QPLLRESET_IN               (w_qpllreset        ) 
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在这里插入图片描述

六、顶层模块gt_module

在该模块里我们可以例化多个gt_channel模块,需要注意的一点是w_qpllreset信号只需要一个gt_channel的信号即可。

module gt_module(
    input                   i_sysclk                    ,
    input                   i_gtrefclk_p                ,
    input                   i_gtrefclk_n                ,
    input                   i_rx0_rst                   ,
    input                   i_tx0_rst                   ,
    output                  o_tx0_done                  ,
    output                  o_rx0_done                  ,
    input                   i_tx0_polarity              ,
    input  [3 :0]           i_tx0_diffctrl              ,
    input  [4 :0]           i_tx0postcursor             ,
    input  [4 :0]           i_tx0percursor              ,     
    input                   i_rx0_polarity              ,
    input  [2 :0]           i_loopback0                 ,
    input  [8 :0]           i_0_drpaddr                 , 
    input                   i_0_drpclk                  ,
    input  [15:0]           i_0_drpdi                   , 
    output [15:0]           o_0_drpdo                   , 
    input                   i_0_drpen                   ,
    output                  o_0_drprdy                  , 
    input                   i_0_drpwe                   ,
    output                  o_rx0_ByteAlign             ,
    output                  o_rx0_clk                   ,
    output [31:0]           o_rx0_data                  ,
    output [3 :0]           o_rx0_char                  ,
    output                  o_tx0_clk                   ,
    input  [31:0]           i_tx0_data                  ,
    input  [3 :0]           i_tx0_char                  ,

    input                   i_rx1_rst                   ,
    input                   i_tx1_rst                   ,
    output                  o_tx1_done                  ,
    output                  o_rx1_done                  ,
    input                   i_tx1_polarity              ,
    input  [3 :0]           i_tx1_diffctrl              ,
    input  [4 :0]           i_tx1postcursor             ,
    input  [4 :0]           i_tx1percursor              ,     
    input                   i_rx1_polarity              ,
    input  [2 :0]           i_loopback1                 ,
    input  [8 :0]           i_1_drpaddr                 , 
    input                   i_1_drpclk                  ,
    input  [15:0]           i_1_drpdi                   , 
    output [15:0]           o_1_drpdo                   , 
    input                   i_1_drpen                   ,
    output                  o_1_drprdy                  , 
    input                   i_1_drpwe                   ,
    output                  o_rx1_ByteAlign             ,
    output                  o_rx1_clk                   ,
    output [31:0]           o_rx1_data                  ,
    output [3 :0]           o_rx1_char                  ,
    output                  o_tx1_clk                   ,
    input  [31:0]           i_tx1_data                  ,
    input  [3 :0]           i_tx1_char                  ,

    output                  o_gt_tx0_p                  ,
    output                  o_gt_tx0_n                  ,
    input                   i_gt_rx0_p                  ,
    input                   i_gt_rx0_n                  ,
    output                  o_gt_tx1_p                  ,
    output                  o_gt_tx1_n                  ,
    input                   i_gt_rx1_p                  ,
    input                   i_gt_rx1_n                    
);

wire    w_gtrefclk          ;

wire    w_qplllock          ;
wire    w_qpllrefclklost    ;
wire    w_qpllreset         ;
wire    w_qplloutclk        ;
wire    w_qplloutrefclk     ;

IBUFDS_GTE2 IBUFDS_GTE2_u0  
(
    .O               (w_gtrefclk    ),
    .ODIV2           (),
    .CEB             (0),
    .I               (i_gtrefclk_p  ),
    .IB              (i_gtrefclk_n  )
);

gtwizard_0_common #
(
    .WRAPPER_SIM_GTRESET_SPEEDUP(),
    .SIM_QPLLREFCLK_SEL         (3'b010)
)
common0_i
(
    .QPLLREFCLKSEL_IN           (3'b010             ),//1:参考时钟0;2:参考时钟1 3:北时钟 4:南时钟
    .GTREFCLK0_IN               (0                  ),
    .GTREFCLK1_IN               (w_gtrefclk         ),
    .QPLLLOCK_OUT               (w_qplllock         ),
    .QPLLLOCKDETCLK_IN          (i_sysclk           ),
    .QPLLOUTCLK_OUT             (w_qplloutclk       ),
    .QPLLOUTREFCLK_OUT          (w_qplloutrefclk    ),
    .QPLLREFCLKLOST_OUT         (w_qpllrefclklost   ),    
    .QPLLRESET_IN               (w_qpllreset        ) 
);

gt_channel gt_channel_u0(
    .i_sysclk                    (i_sysclk          ),
    .i_gtrefclk                  (w_gtrefclk        ),
    .i_rx_rst                    (i_rx0_rst         ),
    .i_tx_rst                    (i_tx0_rst         ),
    .o_tx_done                   (o_tx0_done        ),
    .o_rx_done                   (o_rx0_done        ),
    .i_tx_polarity               (i_tx0_polarity    ),
    .i_tx_diffctrl               (i_tx0_diffctrl    ),
    .i_txpostcursor              (i_tx0postcursor   ),
    .i_txpercursor               (i_tx0percursor    ),     
    .i_rx_polarity               (i_rx0_polarity    ),
    .i_loopback                  (i_loopback0       ),
    .i_drpaddr                   (i_0_drpaddr       ), 
    .i_drpclk                    (i_0_drpclk        ),
    .i_drpdi                     (i_0_drpdi         ), 
    .o_drpdo                     (o_0_drpdo         ), 
    .i_drpen                     (i_0_drpen         ),
    .o_drprdy                    (o_0_drprdy        ), 
    .i_drpwe                     (i_0_drpwe         ),
    .i_qplllock                  (w_qplllock        ), 
    .i_qpllrefclklost            (w_qpllrefclklost  ), 
    .o_qpllreset                 (w_qpllreset       ),
    .i_qplloutclk                (w_qplloutclk      ), 
    .i_qplloutrefclk             (w_qplloutrefclk   ), 
    .o_rx_ByteAlign              (o_rx0_ByteAlign   ),
    .o_rx_clk                    (o_rx0_clk         ),
    .o_rx_data                   (o_rx0_data        ),
    .o_rx_char                   (o_rx0_char        ),
    .o_tx_clk                    (o_tx0_clk         ),
    .i_tx_data                   (i_tx0_data        ),
    .i_tx_char                   (i_tx0_char        ),

    .o_gt_tx_p                   (o_gt_tx0_p        ),
    .o_gt_tx_n                   (o_gt_tx0_n        ),
    .i_gt_rx_p                   (i_gt_rx0_p        ),
    .i_gt_rx_n                   (i_gt_rx0_n        )
);

gt_channel gt_channel_u1(
    .i_sysclk                    (i_sysclk          ),
    .i_gtrefclk                  (w_gtrefclk        ),
    .i_rx_rst                    (i_rx1_rst         ),
    .i_tx_rst                    (i_tx1_rst         ),
    .o_tx_done                   (o_tx1_done        ),
    .o_rx_done                   (o_rx1_done        ),
    .i_tx_polarity               (i_tx1_polarity    ),
    .i_tx_diffctrl               (i_tx1_diffctrl    ),
    .i_txpostcursor              (i_tx1postcursor   ),
    .i_txpercursor               (i_tx1percursor    ),     
    .i_rx_polarity               (i_rx1_polarity    ),
    .i_loopback                  (i_loopback1       ),
    .i_drpaddr                   (i_1_drpaddr       ), 
    .i_drpclk                    (i_1_drpclk        ),
    .i_drpdi                     (i_1_drpdi         ), 
    .o_drpdo                     (o_1_drpdo         ), 
    .i_drpen                     (i_1_drpen         ),
    .o_drprdy                    (o_1_drprdy        ), 
    .i_drpwe                     (i_1_drpwe         ),
    .i_qplllock                  (w_qplllock        ), 
    .i_qpllrefclklost            (w_qpllrefclklost  ), 
    .o_qpllreset                 (                  ),
    .i_qplloutclk                (w_qplloutclk      ), 
    .i_qplloutrefclk             (w_qplloutrefclk   ), 
    .o_rx_ByteAlign              (o_rx1_ByteAlign   ),
    .o_rx_clk                    (o_rx1_clk         ),
    .o_rx_data                   (o_rx1_data        ),
    .o_rx_char                   (o_rx1_char        ),
    .o_tx_clk                    (o_tx1_clk         ),
    .i_tx_data                   (i_tx1_data        ),
    .i_tx_char                   (i_tx1_char        ),

    .o_gt_tx_p                   (o_gt_tx1_p        ),
    .o_gt_tx_n                   (o_gt_tx1_n        ),
    .i_gt_rx_p                   (i_gt_rx1_p        ),
    .i_gt_rx_n                   (i_gt_rx1_n        )
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178

总结

那么现在我们需要进行GT设计的时候,只需要正确配置时钟信号,然后控制输入输出数据以及K码指示信号等用户数据接口即可,需要例化多个GT channel的话就再gt_module当中例化多个gt_channel模块即可,不可以例化多次gt_module,因为gtwizard_0_common 包含在gt_module中,而gtwizard_0_common 只能例化一次

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/563629
推荐阅读
相关标签
  

闽ICP备14008679号