基於FPGA的光纖數據傳輸

項目簡述

在這次的實驗中我們主要學習SFP接口的使用,該接口是高速接口主要是使用GTP接口來完成的。本次項目的簡述爲,一塊FPGA開發板通過光纖發送遞增數據,另一塊FPGA開發板通過光纖接收數據並且驗證數據的正確性。本次實驗所用到的軟硬件環境如下:
1、VIVIADO 2019.1軟件開發環境
2、米聯客MA7035FA開發板
3、米聯客MZ7015開發板

Aurora 8B10B的調用

我們接下來將對Aurora 8B10B IP進行講解
在這裏插入圖片描述
1、傳輸數據的位寬,這裏選擇4Byte,也就是說IP的用戶接口數據爲32位寬
2、GTP接口的串行傳輸速率,GTP幾口最大傳輸6.25Gbps,這裏我們直接選擇最大速率傳輸
3、Aurora 8B10B IP的GTP底層接口時鐘,這個與FPGA開發板的GTP時鐘有關,我使用的這兩款開發板都是125MHz,所以我們這裏選擇125MHz
4、Aurora 8B10B IP的初始化時鐘,我們選擇50MHz
5、DRP時鐘,我們在程序中沒有用到DRP有關的操作,這裏也給成50MHz
6、選擇該Aurora 8B10B IP的通信模式,這裏選擇雙工通信
7、數據傳輸的用戶接口,我們這裏使用簡單的AXI4-stream數據接口
8、這裏我們的數據使用小端模式。
大端模式,是指數據的高字節保存在內存的低地址中,而數據的低字節保存在內存的高地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;這和我們的閱讀習慣一致。
小端模式,是指數據的高字節保存在內存的高地址中,而數據的低字節保存在內存的低地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低。
在這裏插入圖片描述
1、這個按照GTP口的順序進行選擇,該款FPGA一共4對GTP接口,從左下角逆時針循環時0,1,2,3。具體選擇哪一個看FPGA開發板上面的GTP接口使用的第幾對。
在這裏插入圖片描述
1、這裏我們只使用1個IP核,不使用示例工程,所以我們選擇第一個
2、我們這個IP核的初始化時鐘是單端信號,參考時鐘是雙端時鐘,進行相應的選擇。

Aurora 8B10B接口的描述

接下來我們對我們使用的Aurora 8B10B接口進行簡單的描述。

aurora_8b10b_0 your_instance_name (
  .s_axi_tx_tdata               (s_axi_tx_tdata                 ),        // input wire [31 : 0] s_axi_tx_tdata
  .s_axi_tx_tvalid              (s_axi_tx_tvalid                ),      // input wire s_axi_tx_tvalid
  .s_axi_tx_tready              (s_axi_tx_tready                ),      // output wire s_axi_tx_tready
  .m_axi_rx_tdata               (m_axi_rx_tdata                 ),        // output wire [31 : 0] m_axi_rx_tdata
  .m_axi_rx_tvalid              (m_axi_rx_tvalid                ),      // output wire m_axi_rx_tvalid
  .hard_err                     (hard_err                       ),     // output wire hard_err
  .soft_err                     (soft_err                       ),     // output wire soft_err
  .channel_up                   (channel_up                     ),       // output wire channel_up
  .lane_up                      (lane_up                        ),  // output wire [0 : 0] lane_up
  .txp                          (txp                            ),     // output wire [0 : 0] txp
  .txn                          (txn                            ),     // output wire [0 : 0] txn
  .reset                        (reset                          ),     // input wire reset
  .gt_reset                     (gt_reset                       ),     // input wire gt_reset
  .loopback                     (loopback                       ),     // input wire [2 : 0] loopback
  .rxp                          (rxp                            ),      // input wire [0 : 0] rxp
  .rxn                          (rxn                            ),      // input wire [0 : 0] rxn
  .drpclk_in                    (drpclk_in                      ),  // input wire drpclk_in
  .drpaddr_in                   (drpaddr_in                     ),// input wire [8 : 0] drpaddr_in
  .drpen_in                     (drpen_in                       ),    // input wire drpen_in
  .drpdi_in                     (drpdi_in                       ),    // input wire [15 : 0] drpdi_in
  .drprdy_out                   (drprdy_out                     ),// output wire drprdy_out
  .drpdo_out                    (drpdo_out                      ),  // output wire [15 : 0] drpdo_out
  .drpwe_in                     (drpwe_in                       ),    // input wire drpwe_in
  .power_down                   (power_down                     ),// input wire power_down
  .tx_lock                      (tx_lock                        ),    // output wire tx_lock
  .tx_resetdone_out             (tx_resetdone_out               ),       // output wire tx_resetdone_out
  .rx_resetdone_out             (rx_resetdone_out               ), // output wire rx_resetdone_out
  .link_reset_out               (link_reset_out                 ),     // output wire link_reset_out
  .init_clk_in                  (init_clk_in                    ),       // input wire init_clk_in
  .user_clk_out                 (user_clk_out                   ),     // output wire user_clk_out
  .pll_not_locked_out           (pll_not_locked_out             ),    // output wire pll_not_locked_out
  .sys_reset_out                (sys_reset_out                  ),    // output wire sys_reset_out
  .gt_refclk1_p                 (gt_refclk1_p                   ),      // input wire gt_refclk1_p
  .gt_refclk1_n                 (gt_refclk1_n                   ),      // input wire gt_refclk1_n
  .sync_clk_out                 (sync_clk_out                   ),      // output wire sync_clk_out
  .gt_reset_out                 (gt_reset_out                   ),            // output wire gt_reset_out
  .gt_refclk1_out               (gt_refclk1_out                 ),        // output wire gt_refclk1_out
  .gt0_pll0refclklost_out       (gt0_pll0refclklost_out         ),  // output wire gt0_pll0refclklost_out
  .quad1_common_lock_out        (quad1_common_lock_out          ),    // output wire quad1_common_lock_out
  .gt0_pll0outclk_out           (gt0_pll0outclk_out             ),     // output wire gt0_pll0outclk_out
  .gt0_pll1outclk_out           (gt0_pll1outclk_out             ),     // output wire gt0_pll1outclk_out
  .gt0_pll0outrefclk_out        (gt0_pll0outrefclk_out          ),    // output wire gt0_pll0outrefclk_out
  .gt0_pll1outrefclk_out        (gt0_pll1outrefclk_out          )    // output wire gt0_pll1outrefclk_out
);

1、s_axi_tx_tdata、s_axi_tx_tvalid、s_axi_tx_tready、m_axi_rx_tdata、
m_axi_rx_tvalid信號:AXI4-stream協議的信號,具體的時序要求可以查找一下該協議特別容易理解,如果同學們對這個協議不熟悉,一定要學完這個協議繼續學習。
2、hard_err 、soft_err信號:Aurora 8B10B IP硬件、軟件出錯的提示信號。
3、channel_up 、lane_up信號:兩個Aurora 8B10B IP的初始化完成信號,只有將兩個信號拉高之後,我們纔可以進行進一步的操作。
4、txp、txn信號:GTP的寫差分接口,也就是我們綁引腳的接口。
5、reset、gt_reset信號:分別是Aurora 8B10B IP與GTP接口的復位信號,高有效,通常先復位reset再復位gt_reset,高電平復位。這裏需要注意的是Aurora 8B10B IP在正常使用前一定要復位一段時間。
6、loopback信號:環回[2:0]端口在收發機的正常工作和不同的環回模式之間進行選擇,這裏我們默認爲 0。在這裏插入圖片描述
7、rxp、rxn信號: GTP的讀差分接口,也是我們綁引腳的接口。
8、drpclk_in、drpaddr_in、drpen_in、drpdi_in、drprdy_out、drpdo_out、drpwe_in信號:DRP相關信號,與資源分配相關一般用不到,時鐘連接定製IP時選擇的50MHz時鐘,其餘的信號輸入寫0輸出忽視即可。
9、power_down信號:掉電信號,1表示IP掉電,正常工作的情況下該位是0信號。
10、init_clk_in信號:Aurora 8B10B IP的初始化時鐘信號。
11、user_clk_out信號:用戶操作的時鐘信號也就是前面AXI4-stream信號的時鐘信號,所有的數據操作都是在這個時鐘域裏面完成的。
其餘的輸出我們這裏用不到也就不進行詳細的詳解,感興趣的同學可以查閱技術手冊。

光纖項目的代碼設計

MZ7015開發板工程

gtp_top模塊:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : gtp_top.v
// Create Time  : 2019-12-01 14:20:41
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module gtp_top(
        input                   GTPQ0_P         ,
        input                   GTPQ0_N         ,
        output  wire            txp             ,
        output  wire            txn             ,
        input                   rxp             ,
        input                   rxn             ,
        input                   sclk            ,
        output  wire            sfp_tx_disable                 
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
reg         [31:0]          s_axi_tx_tdata      ;
reg                         s_axi_tx_tvalid     ;
wire                        s_axi_tx_tready     ;
wire        [31:0]          m_axi_rx_tdata      ;
wire                        m_axi_rx_tvalid     ; 
wire                        hard_err            ;
wire                        soft_err            ;
wire                        channel_up          ;
wire                        lane_up             ;
reg                         reset               ;
reg                         gt_reset            ;
wire        [ 3:0]          loopback            ;                      
wire                        drpclk_in           ;
wire        [ 8:0]          drpaddr_in          ;
wire                        drpen_in            ;
wire        [15:0]          drpdi_in            ;
wire                        drprdy_out          ;
wire        [15:0]          drpdo_out           ;
wire                        drpwe_in            ;
wire                        power_down          ;
wire                        tx_lock             ;
wire                        tx_resetdone_out    ;
wire                        rx_resetdone_out    ;
wire                        link_reset_out      ;
wire                        init_clk_in         ;
wire                        user_clk_out        ;  
wire                        pll_not_locked_out  ;  
wire                        sys_reset_out       ;   
wire                        sync_clk_out        ;  
wire                        gt_reset_out        ;  
wire                        gt_refclk1_out      ;  
wire                        gt0_pll0refclklost_out; 
wire                        quad1_common_lock_out;  
wire                        gt0_pll0outclk_out  ;    
wire                        gt0_pll1outclk_out  ;    
wire                        gt0_pll0outrefclk_out;  
wire                        gt0_pll1outrefclk_out;  
wire                        locked              ;
reg         [10:0]          gt_reset_cnt        ;
reg                         start_flag          ;
reg         [31:0]          data_cnt            ;
reg         [11:0]          err_cnt             ;            

//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign          drpaddr_in      =           9'b000;
assign          drpen_in        =           1'b0;
assign          drpdi_in        =           16'd0;
assign          drpwe_in        =           1'b0;
assign          loopback        =           3'b000;
assign          power_down      =           ~locked;
assign          sfp_tx_disable  =           1'b0;

always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        gt_reset            <=              1'b0;
    else if(gt_reset_cnt >= 'd500) 
        gt_reset            <=              1'b0;
    else if(gt_reset_cnt == 'd100)
        gt_reset            <=              1'b1;
        
always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        gt_reset_cnt        <=              11'd0;
    else if(gt_reset_cnt[10] == 1'b1)
        gt_reset_cnt        <=              gt_reset_cnt;
    else
        gt_reset_cnt        <=              gt_reset_cnt + 1'b1;

always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        reset               <=              1'b1;
    else if(gt_reset_cnt >= 'd200)
        reset               <=              1'b0;
    else
        reset               <=              1'b1; 

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        start_flag          <=              1'b0;
    else if(channel_up==1'b1 && lane_up==1'b1)
        start_flag          <=              1'b1;
    else
        start_flag         <=              1'b0;
          
always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        s_axi_tx_tdata      <=              32'd0;
    else if(s_axi_tx_tvalid==1'b1 && s_axi_tx_tready==1'b1 && start_flag==1'b1) 
        s_axi_tx_tdata      <=              s_axi_tx_tdata + 1'b1;
    else
        s_axi_tx_tdata      <=              s_axi_tx_tdata;

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        s_axi_tx_tvalid     <=              1'b0;
    else if(start_flag==1'b1) 
        s_axi_tx_tvalid     <=              1'b1;
    else
        s_axi_tx_tvalid     <=              1'b0;

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        data_cnt            <=              'd0;
    else if(m_axi_rx_tvalid == 1'b1)
        data_cnt            <=              data_cnt + 1'b1;

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        err_cnt             <=              'd0;
    else if(m_axi_rx_tvalid==1'b1 && data_cnt!=m_axi_rx_tdata)  
        err_cnt             <=              err_cnt + 1'b1;

clk_wiz_0  clk_wiz_0_inst(
    // Clock out ports
    .clk_out1               (drpclk_in              ),      
    .clk_out2               (init_clk_in            ),     
    .locked                 (locked                 ),       
    .clk_in1                (sclk                   )
);     

aurora_8b10b_0 aurora_8b10b_0_inst (
  .s_axi_tx_tdata           (s_axi_tx_tdata         ),                  // input wire [0 : 31] s_axi_tx_tdata
  .s_axi_tx_tvalid          (s_axi_tx_tvalid        ),                // input wire s_axi_tx_tvalid
  .s_axi_tx_tready          (s_axi_tx_tready        ),                // output wire s_axi_tx_tready
  .m_axi_rx_tdata           (m_axi_rx_tdata         ),                  // output wire [0 : 31] m_axi_rx_tdata
  .m_axi_rx_tvalid          (m_axi_rx_tvalid        ),                // output wire m_axi_rx_tvalid
  .hard_err                 (hard_err               ),                              // output wire hard_err
  .soft_err                 (soft_err               ),                              // output wire soft_err
  .channel_up               (channel_up             ),                          // output wire channel_up
  .lane_up                  (lane_up                ),                                // output wire [0 : 0] lane_up
  .txp                      (txp                    ),                                        // output wire [0 : 0] txp
  .txn                      (txn                    ),                                        // output wire [0 : 0] txn
  .reset                    (reset                  ),                                    // input wire reset
  .gt_reset                 (gt_reset               ),                              // input wire gt_reset
  .loopback                 (loopback               ),                              // input wire [2 : 0] loopback
  .rxp                      (rxp                    ),                                        // input wire [0 : 0] rxp
  .rxn                      (rxn                    ),                                        // input wire [0 : 0] rxn
  .drpclk_in                (drpclk_in              ),                            // input wire drpclk_in
  .drpaddr_in               (drpaddr_in             ),                          // input wire [8 : 0] drpaddr_in
  .drpen_in                 (drpen_in               ),                              // input wire drpen_in
  .drpdi_in                 (drpdi_in               ),                              // input wire [15 : 0] drpdi_in
  .drprdy_out               (drprdy_out             ),                          // output wire drprdy_out
  .drpdo_out                (drpdo_out              ),                            // output wire [15 : 0] drpdo_out
  .drpwe_in                 (drpwe_in               ),                              // input wire drpwe_in
  .power_down               (power_down             ),                          // input wire power_down
  .tx_lock                  (tx_lock                ),                                // output wire tx_lock
  .tx_resetdone_out         (tx_resetdone_out       ),              // output wire tx_resetdone_out
  .rx_resetdone_out         (rx_resetdone_out       ),              // output wire rx_resetdone_out
  .link_reset_out           (link_reset_out         ),                  // output wire link_reset_out
  .init_clk_in              (init_clk_in            ),                        // input wire init_clk_in
  .user_clk_out             (user_clk_out           ),                      // output wire user_clk_out
  .pll_not_locked_out       (pll_not_locked_out     ),          // output wire pll_not_locked_out
  .sys_reset_out            (sys_reset_out          ),                    // output wire sys_reset_out
  .gt_refclk1_p             (GTPQ0_P                ),                      // input wire gt_refclk1_p
  .gt_refclk1_n             (GTPQ0_N                ),                      // input wire gt_refclk1_n
  .sync_clk_out             (sync_clk_out           ),                      // output wire sync_clk_out
  .gt_reset_out             (gt_reset_out           ),                      // output wire gt_reset_out
  .gt_refclk1_out           (gt_refclk1_out         ),                  // output wire gt_refclk1_out
  .gt0_pll0refclklost_out   (gt0_pll0refclklost_out ),  // output wire gt0_pll0refclklost_out
  .quad1_common_lock_out    (quad1_common_lock_out  ),    // output wire quad1_common_lock_out
  .gt0_pll0outclk_out       (gt0_pll0outclk_out     ),          // output wire gt0_pll0outclk_out
  .gt0_pll1outclk_out       (gt0_pll1outclk_out     ),          // output wire gt0_pll1outclk_out
  .gt0_pll0outrefclk_out    (gt0_pll0outrefclk_out  ),    // output wire gt0_pll0outrefclk_out
  .gt0_pll1outrefclk_out    (gt0_pll1outrefclk_out  )    // output wire gt0_pll1outrefclk_out
);

 
//========================================================================================\
//*******************************   Debug  **********************************
//========================================================================================/

ila_0 ila_0_inst (
  .clk                      (user_clk_out           ), // input wire clk
                  
                  
  .probe0                   (s_axi_tx_tdata         ), // input wire [31:0]  probe0  
  .probe1                   (s_axi_tx_tvalid        ), // input wire [0:0]  probe1 
  .probe2                   (s_axi_tx_tready        ), // input wire [0:0]  probe2 
  .probe3                   (m_axi_rx_tdata         ), // input wire [31:0]  probe3 
  .probe4                   (m_axi_rx_tvalid        ), // input wire [0:0]  probe4 
  .probe5                   (channel_up             ), // input wire [0:0]  probe5 
  .probe6                   (lane_up                ), // input wire [0:0]  probe6
  .probe7                   (data_cnt               ), // input wire [0:0]  probe5 
  .probe8                   (err_cnt                ) // input wire [0:0]  probe6
);  

endmodule

上面的代碼並不複雜,只需要詳細的讀一下具體的代碼,相信大家可以學會這個接口的使用,因爲我們在程序中主要利用了aurora_8b10b IP核,大大減少了設計的複雜度。但是需要注意的是,我們定製IP與前面我們介紹的有所出入,因爲具體的開發板的不同

MZ7015開發板測試代碼

測試代碼如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2019/11/30 20:11:24
// Design Name: 
// Module Name: gtp_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module gtp_tb;

wire                            GTPQ0_P         ;
wire                            GTPQ0_N         ;
reg                             sclk            ;
reg                             GTPQ            ;
wire                            txp             ;
wire                            txn             ;
wire                            rxp             ;
wire                            rxn             ;

initial begin
        sclk            =              1'b0;
        GTPQ            =              1'b0;
end

always      #5          sclk            =          ~sclk;
always      #4          GTPQ            =          ~GTPQ;
assign      rxp             =           txp;
assign      rxn             =           txn;

OBUFDS #(
        .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
        .SLEW("SLOW")           // Specify the output slew rate
) OBUFDS_inst (
        .O(GTPQ0_P),     // Diff_p output (connect directly to top-level port)
        .OB(GTPQ0_N),   // Diff_n output (connect directly to top-level port)
        .I(GTPQ)      // Buffer input
);        


gtp_top gtp_top_inst(
        .GTPQ0_P            (GTPQ0_P            ),
        .GTPQ0_N            (GTPQ0_N            ),
        .txp                (txp                ),
        .txn                (txn                ),
        .rxp                (rxp                ),
        .rxn                (rxn                ),
        .sclk               (sclk               )               
);


endmodule

/*
module gtp_tb();
reg clk_m;//50Mhz
reg gtq0;
wire    gtq0_n,gtq0_p;
wire    txp,txn,rxn,rxp;
initial begin
    clk_m = 0;
    gtq0 =0;
end

always #5 clk_m = ~clk_m;
always #4 gtq0 = ~gtq0;

OBUFDS #(
      .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
      .SLEW("SLOW")           // Specify the output slew rate
   ) OBUFDS_inst (
      .O(gtq0_p),     // Diff_p output (connect directly to top-level port)
      .OB(gtq0_n),   // Diff_n output (connect directly to top-level port)
      .I(gtq0)      // Buffer input 
   );
assign  rxp=txp;
assign  rxn=txn;
gtp_top  top_aurora_inst(
        .GTPQ0_N        (gtq0_n),
        .GTPQ0_P        (gtq0_p),
        .txp            (txp),
        .txn            (txn),
        .rxp            (rxp),
        .rxn            (rxn),
        .sclk      (clk_m)

    );
endmodule
*/

MA7035FA開發板代碼

該工程的主要代碼如下:
gtp_top模塊

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : gtp_top.v
// Create Time  : 2019-12-01 14:20:31
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************


module gtp_top(
        input                   GTPQ0_P         ,
        input                   GTPQ0_N         ,
        output  wire            txp             ,
        output  wire            txn             ,
        input                   rxp             ,
        input                   rxn             ,
        input                   sclk            ,
        output  wire            sfp_tx_disable                 
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
wire        [31:0]          s_axi_tx_tdata      ;
reg                         s_axi_tx_tvalid     ;
wire                        s_axi_tx_tready     ;
wire        [31:0]          m_axi_rx_tdata      ;
wire                        m_axi_rx_tvalid     ; 
wire                        hard_err            ;
wire                        soft_err            ;
wire                        channel_up          ;
wire                        lane_up             ;
reg                         reset               ;
reg                         gt_reset            ;
wire        [ 3:0]          loopback            ;                      
wire                        drpclk_in           ;
wire        [ 8:0]          drpaddr_in          ;
wire                        drpen_in            ;
wire        [15:0]          drpdi_in            ;
wire                        drprdy_out          ;
wire        [15:0]          drpdo_out           ;
wire                        drpwe_in            ;
wire                        power_down          ;
wire                        tx_lock             ;
wire                        tx_resetdone_out    ;
wire                        rx_resetdone_out    ;
wire                        link_reset_out      ;
wire                        init_clk_in         ;
wire                        user_clk_out        ;  
wire                        pll_not_locked_out  ;  
wire                        sys_reset_out       ;   
wire                        sync_clk_out        ;  
wire                        gt_reset_out        ;  
wire                        gt_refclk1_out      ;  
wire                        gt0_pll0refclklost_out; 
wire                        quad1_common_lock_out;  
wire                        gt0_pll0outclk_out  ;    
wire                        gt0_pll1outclk_out  ;    
wire                        gt0_pll0outrefclk_out;  
wire                        gt0_pll1outrefclk_out;  
wire                        locked              ;
reg         [10:0]          gt_reset_cnt        ;
reg                         start_flag          ;
wire        [11:0]          data_count          ;

//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
assign          drpaddr_in      =           9'b000;
assign          drpen_in        =           1'b0;
assign          drpdi_in        =           16'd0;
assign          drpwe_in        =           1'b0;
assign          loopback        =           3'b000;
assign          power_down      =           ~locked;
assign          sfp_tx_disable  =           1'b0;

always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        gt_reset            <=              1'b0;
    else if(gt_reset_cnt >= 'd500) 
        gt_reset            <=              1'b0;
    else if(gt_reset_cnt == 'd100)
        gt_reset            <=              1'b1;
        
always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        gt_reset_cnt        <=              11'd0;
    else if(gt_reset_cnt[10] == 1'b1)
        gt_reset_cnt        <=              gt_reset_cnt;
    else
        gt_reset_cnt        <=              gt_reset_cnt + 1'b1;

always @(posedge init_clk_in or negedge locked)
    if(locked == 1'b0)
        reset               <=              1'b1;
    else if(gt_reset_cnt >= 'd200)
        reset               <=              1'b0;
    else
        reset               <=              1'b1; 

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        start_flag          <=              1'b0;
    else if(channel_up==1'b1 && lane_up==1'b1)
        start_flag          <=              1'b1;
    else
        start_flag          <=              1'b0;

always @(posedge user_clk_out or negedge locked)
    if(locked == 1'b0)
        s_axi_tx_tvalid     <=              1'b0;                      
    else if(data_count >= 'd500)
        s_axi_tx_tvalid     <=              1'b1;
    else if(data_count <= 'd10)
        s_axi_tx_tvalid     <=              1'b0;
    else
        s_axi_tx_tvalid     <=              s_axi_tx_tvalid;
        
    

fifo_generator_0 fifo_generator_0_inst (
    .clk                    (user_clk_out           ),                // input wire clk
    .srst                   (~locked                ),              // input wire srst
    .din                    (m_axi_rx_tdata         ),                // input wire [31 : 0] din
    .wr_en                  (m_axi_rx_tvalid        ),            // input wire wr_en
    .rd_en                  (s_axi_tx_tvalid && s_axi_tx_tready),            // input wire rd_en
    .dout                   (s_axi_tx_tdata         ),              // output wire [31 : 0] dout
    .full                   (                       ),              // output wire full
    .empty                  (                       ),            // output wire empty
    .data_count             (data_count             )  // output wire [11 : 0] data_count
);

clk_wiz_0  clk_wiz_0_inst(
    // Clock out ports
    .clk_out1               (drpclk_in              ),      
    .clk_out2               (init_clk_in            ),     
    .locked                 (locked                 ),       
    .clk_in1                (sclk                   )
);     

aurora_8b10b_0 aurora_8b10b_0_inst (
  .s_axi_tx_tdata           (s_axi_tx_tdata         ),                  // input wire [0 : 31] s_axi_tx_tdata
  .s_axi_tx_tvalid          (s_axi_tx_tvalid        ),                // input wire s_axi_tx_tvalid
  .s_axi_tx_tready          (s_axi_tx_tready        ),                // output wire s_axi_tx_tready
  .m_axi_rx_tdata           (m_axi_rx_tdata         ),                  // output wire [0 : 31] m_axi_rx_tdata
  .m_axi_rx_tvalid          (m_axi_rx_tvalid        ),                // output wire m_axi_rx_tvalid
  .hard_err                 (hard_err               ),                              // output wire hard_err
  .soft_err                 (soft_err               ),                              // output wire soft_err
  .channel_up               (channel_up             ),                          // output wire channel_up
  .lane_up                  (lane_up                ),                                // output wire [0 : 0] lane_up
  .txp                      (txp                    ),                                        // output wire [0 : 0] txp
  .txn                      (txn                    ),                                        // output wire [0 : 0] txn
  .reset                    (reset                  ),                                    // input wire reset
  .gt_reset                 (gt_reset               ),                              // input wire gt_reset
  .loopback                 (loopback               ),                              // input wire [2 : 0] loopback
  .rxp                      (rxp                    ),                                        // input wire [0 : 0] rxp
  .rxn                      (rxn                    ),                                        // input wire [0 : 0] rxn
  .drpclk_in                (drpclk_in              ),                            // input wire drpclk_in
  .drpaddr_in               (drpaddr_in             ),                          // input wire [8 : 0] drpaddr_in
  .drpen_in                 (drpen_in               ),                              // input wire drpen_in
  .drpdi_in                 (drpdi_in               ),                              // input wire [15 : 0] drpdi_in
  .drprdy_out               (drprdy_out             ),                          // output wire drprdy_out
  .drpdo_out                (drpdo_out              ),                            // output wire [15 : 0] drpdo_out
  .drpwe_in                 (drpwe_in               ),                              // input wire drpwe_in
  .power_down               (power_down             ),                          // input wire power_down
  .tx_lock                  (tx_lock                ),                                // output wire tx_lock
  .tx_resetdone_out         (tx_resetdone_out       ),              // output wire tx_resetdone_out
  .rx_resetdone_out         (rx_resetdone_out       ),              // output wire rx_resetdone_out
  .link_reset_out           (link_reset_out         ),                  // output wire link_reset_out
  .init_clk_in              (init_clk_in            ),                        // input wire init_clk_in
  .user_clk_out             (user_clk_out           ),                      // output wire user_clk_out
  .pll_not_locked_out       (pll_not_locked_out     ),          // output wire pll_not_locked_out
  .sys_reset_out            (sys_reset_out          ),                    // output wire sys_reset_out
  .gt_refclk1_p             (GTPQ0_P                ),                      // input wire gt_refclk1_p
  .gt_refclk1_n             (GTPQ0_N                ),                      // input wire gt_refclk1_n
  .sync_clk_out             (sync_clk_out           ),                      // output wire sync_clk_out
  .gt_reset_out             (gt_reset_out           ),                      // output wire gt_reset_out
  .gt_refclk1_out           (gt_refclk1_out         ),                  // output wire gt_refclk1_out
  .gt0_pll0refclklost_out   (gt0_pll0refclklost_out ),  // output wire gt0_pll0refclklost_out
  .quad1_common_lock_out    (quad1_common_lock_out  ),    // output wire quad1_common_lock_out
  .gt0_pll0outclk_out       (gt0_pll0outclk_out     ),          // output wire gt0_pll0outclk_out
  .gt0_pll1outclk_out       (gt0_pll1outclk_out     ),          // output wire gt0_pll1outclk_out
  .gt0_pll0outrefclk_out    (gt0_pll0outrefclk_out  ),    // output wire gt0_pll0outrefclk_out
  .gt0_pll1outrefclk_out    (gt0_pll1outrefclk_out  )    // output wire gt0_pll1outrefclk_out
);

endmodule

這裏因爲這個比較簡單,我們便不再給出相應的測試文件,想寫的同學可以試着書寫。

仿真結果

這裏給出我們MZ7015開發板的仿真結果如下:
在這裏插入圖片描述
從圖中可以看出,誤碼的個數爲零,所以證明了我們設計的準確性。

下板結果

由於在家的硬件條件不夠我們沒辦法進行下板測試,但是這個項目我們在學校的時候已經下板測試過了誤碼爲零,從而證明了我們實驗的正確性。

總結

創作不易,認爲文章有幫助的同學們可以關注、點贊、轉發支持。(txt文件、圖片文件在羣中)對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章