日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

Aurora8B10B IP使用 -05- 收發(fā)測試應用示例

前言

本文首先介紹了根據網上博文簡單介紹了8B/10B的原理,并根據Aurora IP的相關使用方法,參考IP手冊進行設計遞增數測試用例,并下板進行實際驗證。

8B/10B簡介

8B/10B,也叫做8比特/10比特或8b10b。8b/10b方式最初由IBM公司于1983年發(fā)明并應用于ESCON(200M互連系統(tǒng)),由Al Widmer和Peter Franaszek在IBM的刊物“研究與開發(fā)”上描述。

8b/10b編碼的特性之一是保證DC 平衡,采用8b/10b編碼方式,可使得發(fā)送的“0”、“1”數量保持基本一致,連續(xù)的“1”或“0”不超過5位,即每5個連續(xù)的“1”或“0”后必須插入一位“0”或“1”,從而保證信號DC平衡,它就是說,在鏈路超時時不致發(fā)生DC失調。通過8b/10b編碼,可以保證傳輸的數據串在接收端能夠被正確復原,除此之外,利用一些特殊的代碼( 在PCI-Express總線中為K碼) ,可以幫助接收端進行還原的工作,并且可以在早期發(fā)現(xiàn)數據位的傳輸錯誤,抑制錯誤繼續(xù)發(fā)生。

8b/10b編碼是將一組連續(xù)的8位數據分解成兩組數據,一組3位,一組5位,經過編碼后分別成為一組4位的代碼和一組6位的代碼,從而組成一組10位的數據發(fā)送出去。相反,解碼是將1組10位的輸入數據經過變換得到8位數據位。數據值可以統(tǒng)一的表示為DX.Y或KX.Y,其中D表示為數據代碼,K表示為特殊的命令代碼,X表示輸入的原始數據的低5位EDCBA,Y 表示輸入的原始數據的高3位HGF。

8b/10b編碼是目前許多高速串行總線采用的編碼機制,如 USB3.0、1394b、Serial ATA、PCI Express、Infini-band、Fibre Channel(光纖通道)、RapidIO等總線或網絡等。

工作原理

8B/10B編碼是目前高速串行通信中經常用到的一種編碼方式。將8bit編碼成10bit后,10B中0和1的位數只可能出現(xiàn)3種情況:

  1. 有5個0和5個1
  2. 有6個0和4個1
  3. 有4個0和6個1

這樣引出了一個新術語“不均等性(Disparity)”,就是1的位數和0的位數的差值,根據上面3種情況就有對應的3個Disparity 0、-2、+2。8bit原始數據會分成兩部分,其低5位會進行5B/6B編碼,高3位則進行3B/4B編碼,這兩種映射關系在當時已經成為了一個標準化的表格。人們喜歡把8bit數據表示成Dx.y的形式,其x=5LSB(least significant bit最低有效位),y=3MSB(most significant bit最高有效位)。

例如一個8bit數據101 10101,x=10101(21) y="101"(5),現(xiàn)在我們就把這8bit數據寫成D21.5。

對于8bit數據,它在表中的位序為HGFEDCBA,即H為最高位,A為最低位,EDCBA經過5B/6B編碼為abcdei,HGF經過3B/4B編碼為fghj。傳送10bit編碼的順序為abcdeifghj。

創(chuàng)建工程

新建一個空白工程,這里我選擇的芯片型號為xc7k160tffg676-2,米聯(lián)客MK7160FA。

配置Aurora IP

創(chuàng)建完工程,將Aurora IP添加到工程下,并修改相關配置。lane寬度設置為4,接口則生成32位寬的數據,若選擇2,則生成16位寬的數據。

由于只是進行傳輸測試,所以該界面的相關參數就根據板卡的相關時鐘進行配置即可,Link層選擇幀模式,其余默認即可。

米聯(lián)客的板卡在MGT的116對外引出,所以這里對應連接到GTXQ1上。

共享邏輯選擇包含在內核中,并使能初始化時鐘的單端口時鐘選項,Aurora IP配置完成。

程序架構設計

參考例程的思路,這里設計了Aurora發(fā)送遞增數的測試示例,主要包含四個模塊,復位模塊,Aurora發(fā)送數據生成模塊,Aurora接收數據模塊,Aurora IP。

  • 復位模塊主要用于對reset和gt_reset兩個信號進行初始化復位,確保Aurora IP能正常工作。
  • Aurora發(fā)送數據生成模塊,根據AXI總線協(xié)議進行生成遞增測試數據,然后通過Aurora IP將數據通過光口傳輸。
  • Aurora接收數據模塊,根據AXI總線協(xié)議接收數據,并通過接收計數信號進行比對遞增數傳輸是否存在錯誤,用于錯誤指示。

復位模塊

復位模塊使用start_en作為復位的指示信號,當檢測到start_en的上升沿時,模塊對系統(tǒng)復位信號和收發(fā)器的復位信號進行復位。reset和gt_reset根據手冊中推薦的復位時序進行復位。在該文中有詳細介紹,Aurora8B10B IP使用 -02- IP功能設計技巧。

`timescale 1ns / 1ps
module rst_ctrl(
 input wire    clk     ,
 input wire    start_en            ,
 output  wire    reset     ,// 系統(tǒng)復位
 output  wire    gt_reset      // 收發(fā)器復位
    );

//parameter define
parameter GT_RESET_START = 128  ;
parameter GT_RESET_END = 384 ;
parameter RESET_MAX = GT_RESET_END + GT_RESET_START;

//reg define 
reg             reset_r          ;
reg             gt_reset_r       ;
reg             reset_busy     =0;//復位忙指示信號
reg  [1:0] start_flag_dly =0;//復位使能信號延時
reg  [10:0] cnt_rst        =0;//用于產生復位信號的計數器

//wire define
assign    reset = reset_r   ;
assign gt_reset = gt_reset_r;

//起始信號邊沿
wire link_up_n = !start_flag_dly[1]&&start_flag_dly[0];
//start_flag_dly
always @(posedge clk) begin
 start_flag_dly <= {start_flag_dly[0], start_en};
end

//復位忙指示信號
always @(posedge clk) begin
 if(link_up_n==1) begin
  reset_busy <= 1;
 end
 else if(cnt_rst== RESET_MAX - 1)begin
  reset_busy <= 0;
 end
end

//復位計數器
always @(posedge clk) begin
 if (reset_busy == 'd1) begin
  if(reset_busy == 'd1 && (cnt_rst == RESET_MAX - 1))
   cnt_rst <= 'd0;
  else
   cnt_rst <= cnt_rst + 1'b1;
 end
 else begin
  cnt_rst <= 'd0;
 end
end

//gt_reset
always @(posedge clk) begin
 if (reset_busy == 'd1) begin
  if(cnt_rst == GT_RESET_START - 1) begin
   gt_reset_r <= 1'b1;
  end
  else if (cnt_rst == GT_RESET_END - 1|| cnt_rst == 0 ) begin
   gt_reset_r <= 1'b0;
  end
  else begin
   gt_reset_r <= gt_reset_r;
  end
 end
 else begin
  gt_reset_r <= 1'b0;
 end
end

//reset
always @(posedge clk) begin
 if (reset_busy == 'd1) begin
  reset_r <= 1'b1;
 end
 else begin
  reset_r <= 1'b0;
 end
end
endmodule

發(fā)送模塊

發(fā)送部分就是簡單的模擬AXI總線協(xié)議進行發(fā)送,這里指定了幾個參數,方便后期移植修改,同時又例化了一個ILA IP用于檢測上板時數據正確性。

`timescale 1ns / 1ps
module Aurora_Tx #(
    parameter            DATA_WIDTH         = 32, // DATA bus width
    parameter            TKEEP_WIDTH        = DATA_WIDTH/8, // TKEEP  width
    parameter           STREAM_LEN         = 1024 ,
    parameter            REG_MAX_BURST      = 15
)
(
 input wire   clk     , 
 input wire   rst     , 
 output  wire [0 : DATA_WIDTH-1]  s_axi_tx_tdata ,
 output  wire [0 : TKEEP_WIDTH-1]  s_axi_tx_tkeep ,
 output  wire    s_axi_tx_tlast  ,
 output  wire    s_axi_tx_tvalid  ,
 input  wire    s_axi_tx_tready   
    );

//reg define 
reg  [0:DATA_WIDTH-1] axi_tx_tdata ;
reg    axi_tx_tlast    ;
reg    axi_tx_tvalid       ;
reg  [REG_MAX_BURST:0] cnt_data     ;

//wire define
wire    cnt_data_tlast    ;
assign s_axi_tx_tdata     = axi_tx_tdata;
assign s_axi_tx_tkeep     = 4'hF        ;
assign s_axi_tx_tlast     = axi_tx_tlast;
assign s_axi_tx_tvalid    = axi_tx_tvalid;
assign cnt_data_tlast = (s_axi_tx_tready==1) && (axi_tx_tvalid==1) && (cnt_data == STREAM_LEN - 1);
//cnt_data 
always @(posedge clk) begin
 if(rst==1)begin
  cnt_data <= 'd0;
 end
 else if ((s_axi_tx_tready==1) && (axi_tx_tvalid==1)) begin
  if(cnt_data_tlast==1)
   cnt_data <= 'd0;
  else
   cnt_data <= cnt_data + 1'b1;
 end
end

//axi_tx_tlast
always @(*) begin
 axi_tx_tlast = cnt_data_tlast;
end

//axi_tx_tvalid
always @(posedge clk) begin
 if(rst==1)begin
  axi_tx_tvalid <= 1'b0;
 end
 else if (cnt_data_tlast == 1'b1) begin
  axi_tx_tvalid <= 1'b0;
 end
 else if (axi_tx_tvalid == 1'b0 && s_axi_tx_tready == 1'b1) begin
  axi_tx_tvalid <= 1'b1;
 end
end

//axi_tx_tdata
always @(*) begin
 axi_tx_tdata = cnt_data;
end

wire [63:0] probe0;
assign probe0 = {
 s_axi_tx_tdata  ,//32
 s_axi_tx_tkeep  ,//4
 s_axi_tx_tlast  ,//1
 s_axi_tx_tvalid  ,//1
 s_axi_tx_tready  ,//1
 cnt_data            //16

};

ila_0 u_tx (
 .clk(clk), // input wire clk
 .probe0(probe0) // input wire [63:0] probe0
);

endmodule

接收模塊

接收部分就是簡單的模擬AXI總線協(xié)議接收數據,這里也指定了幾個參數,方便后期移植修改,同時又例化了一個ILA IP用于檢測上板時數據正確性。

module Aurora_Rx #(
    parameter            DATA_WIDTH         = 32, // DATA bus width
    parameter            TKEEP_WIDTH        = DATA_WIDTH/8, // TKEEP  width
    parameter           STREAM_LEN         = 1024 ,
    parameter            REG_MAX_BURST      = 15
)(
 input  wire   clk     ,
 input  wire   rst     ,
 input wire [0 : DATA_WIDTH-1]  m_axi_rx_tdata  ,
 input wire [0 : TKEEP_WIDTH-1]  m_axi_rx_tkeep  ,
 input wire    m_axi_rx_tlast  ,
 input wire    m_axi_rx_tvalid  
    );
//reg define
reg  [REG_MAX_BURST:0] cnt_burst ;
reg     error_r ;

always @(posedge clk) begin
 if(rst==1)begin
  cnt_burst <= 'd0;
 end
 else if (m_axi_rx_tvalid == 1) begin
  if(m_axi_rx_tvalid == 1 && cnt_burst == STREAM_LEN - 1)
   cnt_burst <= 'd0;
  else
   cnt_burst <= cnt_burst + 1'b1;
 end
end

//check
always @(posedge clk) begin
 if(rst==1)begin
  error_r <= 'd0;
 end
 else if (m_axi_rx_tvalid==1 && (m_axi_rx_tdata != cnt_burst)) begin
  error_r <= 1'b1;
 end
end

wire [63:0] probe0;
assign probe0 = {
 m_axi_rx_tdata  ,
 m_axi_rx_tkeep  ,
 m_axi_rx_tlast  ,
 m_axi_rx_tvalid  ,
 error_r             ,
 cnt_burst
};
ila_0 u_rx (
 .clk(clk), // input wire clk
 .probe0(probe0) // input wire [63:0] probe0
);
endmodule

頂層連接

根據前面繪制的框圖連接上述各個模塊,例化了一個VIO IP進行檢測和控制復位。

`timescale 1ns / 1ps
module Aurora_Top(
    //clock---------------------------------
    input clk_in,          //系統(tǒng)鐘
    input gt_refclk116_p , //差分參考鐘
    input gt_refclk116_n , //差分參考鐘
    //Serial I/O----------------------------
    input  rxp   ,
 input  rxn   ,
 output txp   ,
 output txn   ,
    //--------------------------------------
    output  tx_dis  ,
    output  led_link_up 
    );

    //==========================================
    //wire define
    wire start;
     //------------------------------SEND--------------------------------------------
    // AXI TX Interface
    wire [0 : 31] s_axi_tx_tdata  ;
    wire [0 : 3]  s_axi_tx_tkeep  ;
    wire s_axi_tx_tlast  ;
    wire s_axi_tx_tvalid ;
    wire s_axi_tx_tready ;
    //------------------------------RECEIVE-----------------------------------------
    // AXI RX Interface
    wire [0 : 31] m_axi_rx_tdata  ;
    wire [0 : 3]  m_axi_rx_tkeep  ;
    wire m_axi_rx_tlast  ;
    wire m_axi_rx_tvalid ;
    //------------------------------SYSTEM------------------------------------------
    // reset IO,test
    wire reset;
    wire gt_reset;
    wire [2 : 0] loopback;
    //------------------------------clock-------------------------------------------
    // GT Reference Clock Interface
    wire gt_refclk1_p;                       
    wire gt_refclk1_n;                       
    wire init_clk_in ;         
    wire user_clk_out;
    wire sync_clk_out;                       
    wire gt_refclk1_out;                               
    //--------------------------------drp-------------------------------------------
    //drp Interface
    wire drpclk_in ;  
    //-----------------------------Status Detection--------------------------------
    // Error Detection Interface                       
    wire hard_err ;
    wire soft_err ;
    wire frame_err;
    // Status link 
    wire channel_up;
    wire lane_up;
    wire sys_reset_out;
    //==========================================
    //wire assign
    assign tx_dis = 0;
    assign gt_refclk116_p =gt_refclk1_p;
    assign gt_refclk116_n =gt_refclk1_n;
    assign led_link_up = channel_up & lane_up;
    assign init_clk_in = clk_in;
    assign drpclk_in = clk_in; 

    wire sys_rst = ~(channel_up & lane_up & (~sys_reset_out));
    
    rst_ctrl u_rst_ctrl(
        .clk              ( init_clk_in   ),
        .start_en         (     start     ),  
        .reset            ( reset         ),
        .gt_reset         ( gt_reset      )
    );

    Aurora_Tx u_Aurora_Tx(
        .clk              ( user_clk_out     ),
        .rst              (     start        ),
        .s_axi_tx_tdata   ( s_axi_tx_tdata   ),
        .s_axi_tx_tkeep   ( s_axi_tx_tkeep   ),
        .s_axi_tx_tlast   ( s_axi_tx_tlast   ),
        .s_axi_tx_tvalid  ( s_axi_tx_tvalid  ),
        .s_axi_tx_tready  ( s_axi_tx_tready  )
    );

    Aurora_Rx u_Aurora_Rx(
        .clk              ( user_clk_out     ),
        .rst              (       start      ),
        .m_axi_rx_tdata   ( m_axi_rx_tdata   ),
        .m_axi_rx_tkeep   ( m_axi_rx_tkeep   ),
        .m_axi_rx_tlast   ( m_axi_rx_tlast   ),
        .m_axi_rx_tvalid  ( m_axi_rx_tvalid  )
    );

    aurora_8b10b_0 u_aurora(
        //------------------------------SEND--------------------------------------------
        // AXI TX Interface
        .s_axi_tx_tdata (s_axi_tx_tdata ),                    // input wire [0 : 31] s_axi_tx_tdata
        .s_axi_tx_tkeep (s_axi_tx_tkeep ),                    // input wire [0 : 3] s_axi_tx_tkeep
        .s_axi_tx_tlast (s_axi_tx_tlast ),                    // input wire s_axi_tx_tlast
        .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
        //------------------------------RECEIVE-----------------------------------------
        // AXI RX Interface
        .m_axi_rx_tdata (m_axi_rx_tdata ),                    // output wire [0 : 31] m_axi_rx_tdata
        .m_axi_rx_tkeep (m_axi_rx_tkeep ),                    // output wire [0 : 3] m_axi_rx_tkeep
        .m_axi_rx_tlast (m_axi_rx_tlast ),                    // output wire m_axi_rx_tlast
        .m_axi_rx_tvalid(m_axi_rx_tvalid),                  // output wire m_axi_rx_tvalid  
        //------------------------------SYSTEM------------------------------------------
        // reset IO,test
        .reset(reset),                                      // input wire reset
        .gt_reset(gt_reset),                                // input wire gt_reset
        .loopback(loopback),                                // input wire [2 : 0] loopback
        //--------------------------------Serial I/O------------------------------------
        .txp(txp),                                          // output wire [0 : 0] txp
        .txn(txn),                                          // output wire [0 : 0] txn
        .rxp(rxp),                                          // input wire [0 : 0] rxp
        .rxn(rxn),                                          // input wire [0 : 0] rxn
        //------------------------------clock-------------------------------------------
        // GT Reference Clock Interface
        .gt_refclk1_p(gt_refclk1_p),                        // input wire gt_refclk1_p
        .gt_refclk1_n(gt_refclk1_n),                        // input wire gt_refclk1_n
        .init_clk_in(init_clk_in),                          // input wire init_clk_in
        //--------------------------------drp-------------------------------------------
        //drp Interface
        .drpclk_in(drpclk_in),                              // input wire drpclk_in
        .drpaddr_in(0),                            // input wire [8 : 0] drpaddr_in
        .drpen_in(0),                                // input wire drpen_in
        .drpdi_in(0),                                // input wire [15 : 0] drpdi_in
        .drprdy_out(),                            // output wire drprdy_out
        .drpdo_out(),                              // output wire [15 : 0] drpdo_out
        .drpwe_in(0),                                // input wire drpwe_in  
        //-----------------------------Status Detection--------------------------------
        // Error Detection Interface
        .hard_err (hard_err ),                                // output wire hard_err
        .soft_err (soft_err ),                                // output wire soft_err
        .frame_err(frame_err),                              // output wire frame_err
        // Status 
        .power_down(0),                            // input wire power_down
        .channel_up(channel_up),                            // output wire channel_up
        .lane_up(lane_up),                                  // output wire [0 : 0] lane_up
        //-----------------------------------------------------------------------------
        //-----------------------------------------------------------------------------
        .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
        .pll_not_locked_out(pll_not_locked_out),            // output wire pll_not_locked_out
        //reset_out
        .gt_reset_out(gt_reset_out),                        // output wire gt_reset_out
        .link_reset_out(link_reset_out),                    // output wire link_reset_out
        .sys_reset_out(sys_reset_out),                      // output wire sys_reset_out
        //clk_out
        .user_clk_out(user_clk_out),                        // output wire user_clk_out
        .sync_clk_out(),                        // output wire sync_clk_out
        .gt_refclk1_out(),                    // output wire gt_refclk1_out
        //qplllock_out
        .gt0_qplllock_out(),                // output wire gt0_qplllock_out
        .gt0_qpllrefclklost_out(),    // output wire gt0_qpllrefclklost_out
        .gt_qpllclk_quad2_out(),        // output wire gt_qpllclk_quad2_out
        .gt_qpllrefclk_quad2_out()   // output wire gt_qpllrefclk_quad2_out
    );
    
    vio_0 Status_dect (
        .clk(user_clk_out),                // input wire clk
        .probe_in0(hard_err),    // input wire [0 : 0] probe_in0
        .probe_in1(soft_err),    // input wire [0 : 0] probe_in1
        .probe_in2(frame_err),    // input wire [0 : 0] probe_in2
        .probe_in3(channel_up),    // input wire [0 : 0] probe_in3
        .probe_in4(lane_up),    // input wire [0 : 0] probe_in4
        .probe_out0(loopback),  // output wire [2 : 0] probe_out0
        .probe_out1(start)  // output wire [0 : 0] probe_out1
    );
endmodule

下板測試

設置loopback的默認值為0,或者不為0的先設置為0,然后設置為0 ,然后設置模式為近端回環(huán)測試,1或2都可。則可以看到channel_up和lane_up都拉高,連接建立。start信號拉高復位,然后置零可去發(fā)送接收的窗口觀察信號收發(fā)是否正確。

發(fā)送部分的ILA窗口抓取到數據正常發(fā)送,同時滿足AXI的協(xié)議。

接收部分的ILA窗口抓取到數據正常接收,同時滿足AXI的協(xié)議,error指示信號常為低,證明數據傳輸正常,鏈路穩(wěn)定。

reference

  1. PG046
  2. Aurora例程
  3. 8B/10B編碼基本原理
  4. 8B/10B編碼
  5. 8B/10B百度百科
聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 2
收藏 2
關注 15
成為作者 賺取收益
全部留言
0/200
成為第一個和作者交流的人吧