GT收发器PHY层设计(2)GT_module模块设计

文章目录

前言

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

一、设计框图


设计思路及代码思路 参考FPGA奇哥系列网课
IP核解析参考xilinx文档PG168 7 Series FPGAs Transceiver Wizard v3.6

二、例化IP核端口

即框图当中的gtwizard_0 模块

所有端口含义都可以在PG168 当中进行了解

需要特别关注的在代码里进行了简单的注释

c 复制代码
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

三、common_reset_i模块

用于产生QPLL的复位信号

c 复制代码
assign w_qpll_reset = w_commonreset | w_gt_qpll_reset   ;
c 复制代码
gtwizard_0_common_reset # 
(
    .STABLE_CLOCK_PERIOD            (                       )    
)
common_reset_i
(    
    .STABLE_CLOCK                   (i_sysclk               ),           
    .SOFT_RESET                     (i_tx_rst               ),      
    .COMMON_RESET                   (w_commonreset          )          
);

四、gt_usrclk_source模块

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

c 复制代码
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     )
);  

五、IBUFDS_GTE2和gtwizard_0_common模块

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

c 复制代码
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        ) 
);

六、顶层模块gt_module

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

c 复制代码
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

总结

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

相关推荐
viperrrrrrrrrr75 小时前
大数据学习(105)-Hbase
大数据·学习·hbase
行思理7 小时前
go语言应该如何学习
开发语言·学习·golang
oceanweave8 小时前
【k8s学习之CSI】理解 LVM 存储概念和相关操作
学习·容器·kubernetes
吴梓穆10 小时前
UE5学习笔记 FPS游戏制作43 UI材质
笔记·学习·ue5
学会870上岸华师10 小时前
c语言学习16——内存函数
c语言·开发语言·学习
XYN6110 小时前
【嵌入式面试】
笔记·python·单片机·嵌入式硬件·学习
啊哈哈哈哈哈啊哈哈10 小时前
R3打卡——tensorflow实现RNN心脏病预测
人工智能·深度学习·学习
KangkangLoveNLP11 小时前
深度探索:策略学习与神经网络在强化学习中的应用
人工智能·深度学习·神经网络·学习·机器学习·自然语言处理
穷儒公羊12 小时前
第一部分——Docker篇 第六章 容器监控
运维·后端·学习·docker·云原生·容器
CAE虚拟与现实12 小时前
记录一下学习docker的命令(不断补充中)
学习·docker·容器·容器化·docker部署·docker命令