Aurora8B10B(二) 从手册和仿真学习Aurora8B10B

一. 简介

在上篇文章中,主要结合IP配置界面介绍了一下Aurora8B10B,这篇文章将结合文档来学习一下Aurora8B10B内部的一些细节 和 相关的时序吧。文档主要是参考的是这个 pg046-aurora-8b10b-en-us-11.1

二. Aurora8B10B内部细节

在手册上,对Aurora8B10B的内部并没有做非常信息的说明,所以我们也不用纠结的特别深入,大概的了解一下有效带宽延时大概是多少就可以了,重点还是放在如何使用上。

  1. 数据: 在用户发送每一帧数据的时候,Aurora8B10都会在数据的开始位置增加2byte的SCP和末尾增加2btye的EOF来表示数据帧的开始和结束标志(如果用户的数据btye数为奇数的话,会为其增加额外的一个PAD byte来使数据为偶数)。所以为了最大传输带宽,用户每次传输的数据byte数最好为偶数。
  2. 时钟补偿: 传输通道每10000 bytes需要进行一次时钟补偿,每次时钟补偿需要发送12 bytes的数据,需要消耗6个或者3个时钟周期,在这期间用户是不能进行数据传输的,有效带宽又进一步减少了。
  3. 传输延时:从发送端发送第一个数据开始,到接收端接收到第一个数据结束所消耗的时间,最小的延时为41个用户时钟周期,对时延有要求的话,这里需要着重注意。

需要注意的点,就以上三点,其它更细节的地方可以去研究官方文档。

微信公众号 : FPGA之旅 出品

三. Aurora8B10B 模块信号

这部分才是学习的重点,同样对于一些不重要的信号,或者这个信号很重要,但是在我使用的过程中,这个重要的信号我不care的,在下面的介绍中就一笔带过了,有对应需求的可以在官方文档里快速查找对应信号的功能(这样介绍起来,毕竟太费键盘了O(∩_∩)O)。

本次设计的IP配置如下(上篇文章中 已经对IP的配置进行了详细的讲解):

  1. 数据位宽4Btyes,线速率6.25,GT Refclk 125M,INT(DRP) CLk 50,数据模式双向,接口是Framing,其它都没有选
  2. GT 收发器选择一个Lane,Shared Logic选择 in core,其它的都不勾选。

最后得到的端口信号如下,接口信号挺多的,但是设计上使用到的却只有那么几个而已,和DDR MIG IP差不多,下面就按类别进行介绍。

Aurora8B10B(二) 从手册和仿真学习Aurora8B10B_第1张图片

  1. IO信号: 连接到对应bank的IO Pin上
// GT Serial I/O
.rxp                                (       aurora_rxp_pin_i            ),
.rxn                                (       aurora_rxn_pin_i            ),
.txp                                (       aurora_txp_pin_o            ),
.txn                                (       aurora_txn_pin_o            ),

  1. GT的参考时钟: 由外部差分时钟输入,引脚相对固定

    // GT Reference Clock Interface
    .gt_refclk1_p                       (       gt_refclk1_p_i              ),
    .gt_refclk1_n                       (       gt_refclk1_n_i              ),
    .gt_refclk1_out                     (       gt_refclk1_out              ),
    
  2. 错误标识信号: 当出现错误时,对应信号会拉高

 // Error Detection Interface
.frame_err                          (       aurora_error[0]             ),
.hard_err                           (       aurora_error[1]             ),
.soft_err                           (       aurora_error[2]             ),
  1. IP初始化成功信号: 当IP初始化成功,并且接收方与发送方握手成功后拉高,只需要对channel_up信号进行判断即可
 // Status
.lane_up                            (                                   ),
.channel_up                         (       channel_up                  ),
  1. 系统接口: 只需要操作gt复位和系统复位两个信号即可,初始化时钟自行输入即可,可以是单端信号(IP配置时勾选即可)。这个两个复位信号是在初始化时钟域下进行的。

​ loopback用来设置回环模式的,power_down设置0即可正常工作

复位说明:
请添加图片描述
Aurora8B10B(二) 从手册和仿真学习Aurora8B10B_第2张图片

    // System Interface
.sync_clk_out                       (                                   ),
.gt_reset                           (       gt_reset                    ),
.reset                              (       reset                       ),
.sys_reset_out                      (                                   ),
.gt_reset_out                       (                                   ),
.power_down                         (       'd0                         ),
.loopback                           (       'd0                         ),
.tx_lock                            (                                   ),
.init_clk_p                         (       init_clk_p_i                ),
.init_clk_n                         (       init_clk_n_i                ),
.init_clk_out                       (       init_clk_out                ),
.tx_resetdone_out                   (                                   ),
.rx_resetdone_out                   (                                   ),
.link_reset_out                     (                                   ),
  1. 动态配置信号,在IP运行过程中,可以对其进行动态配置,一般来说,用不到,可以不用管
//DRP Ports
.drpclk_in                          (   init_clk_out                    ),  
.drpaddr_in                         (   'd0                             ), 
.drpen_in                           (   'd0                             ), 
.drpdi_in                           (   'd0                             ), 
.drprdy_out                         (                                   ), 
.drpdo_out                          (                                   ), 
.drpwe_in                           (   1'b0                            ), 
  1. GT COMMON信号输出: 由于我们选择的是in core,所以在IP里面包含了这个模块,输出的信号可以给其他收发器使用。
//____________________________COMMON PORTS_______________________________{
.gt0_pll0refclklost_out             (                                   ),
.quad1_common_lock_out              (                                   ),
//----------------------- Channel - Ref Clock Ports ------------------------
.gt0_pll0outclk_out                 (                                   ),
.gt0_pll1outclk_out                 (                                   ),
.gt0_pll0outrefclk_out              (                                   ),
.gt0_pll1outrefclk_out              (                                   ),
//____________________________COMMON PORTS_______________________________}
.pll_not_locked_out                 (                                   )
  1. 用户接口: 最后就是我们的用户接口了,是一个非常简单的AXI stream接口 ,直接看时序图吧
.user_clk_out                           (   user_clk_out                    ),
    // AXI TX Interface
.s_axi_tx_tdata                         (   s_axi_tx_tdata                  ),
.s_axi_tx_tkeep                         (   s_axi_tx_tkeep                  ),
.s_axi_tx_tvalid                        (   s_axi_tx_tvalid                 ),
.s_axi_tx_tlast                         (   s_axi_tx_tlast                  ),
.s_axi_tx_tready                        (   s_axi_tx_tready                 ),
    
    // AXI RX Interface
.m_axi_rx_tdata                         (   m_axi_rx_tdata                  ),
.m_axi_rx_tkeep                         (   m_axi_rx_tkeep                  ),
.m_axi_rx_tvalid                        (   m_axi_rx_tvalid                 ),
.m_axi_rx_tlast                         (   m_axi_rx_tlast                  ),

Aurora8B10B(二) 从手册和仿真学习Aurora8B10B_第3张图片
Aurora8B10B(二) 从手册和仿真学习Aurora8B10B_第4张图片

其中tlast和tkeep两个信号需要注意一下,在发送接收一帧数据时,在最后一个数据需要tlast会拉高,同时tkeep会指示最后一个数据中有效的byte数是多少。

四. 仿真

仿真的时候,我们只需要给时钟和复位信号就可以了,主要观察到channel_up信号拉高了,就说名IP可以正常使用了, tb如下:

    reg gt_reset;
    reg reset;
    reg aurora_rst_n_i;
    reg gt_refclk1_p    ;
    reg gt_refclk1_n    ;
    reg init_clk_p      ;
    reg init_clk_n      ;
    wire aurora_rxp_pin  ;
    wire aurora_rxn_pin  ;
    wire aurora_txp_pin  ;
    wire aurora_txn_pin  ;


    assign aurora_rxp_pin = aurora_txp_pin;
    assign aurora_rxn_pin = aurora_txn_pin;
    always@(*) #2.5 gt_refclk1_p <= ~gt_refclk1_p;
    always@(*) gt_refclk1_n <= ~gt_refclk1_p;
    always@(*) #10 init_clk_p <= ~init_clk_p;
    always@(*) init_clk_n <= ~init_clk_p;
    initial begin
        gt_refclk1_p = 1'b1;
        gt_refclk1_n = 1'b0;
        init_clk_p   = 1'b1;
        init_clk_n   = 1'b0;
        aurora_rst_n_i = 1'b1;
        gt_reset = 1'b0;
        reset    = 1'b0;
   
        #10
        reset = 1'b1;
        #100
        gt_reset = 1'b1;
        #1000
        gt_reset = 1'b0;
        #200
        reset = 1'b0;
    end

请添加图片描述

仿真到360us的时候,channel_up拉高了。就可以根据时序图正常进行读写操作了。到这里就结束了,可以根据自己需要进行读写设计了。

你可能感兴趣的:(高速接口,FPGA,学习,fpga开发)