当前位置:网站首页>Aurora8b10b IP usage-05-transceiver test application example

Aurora8b10b IP usage-05-transceiver test application example

2022-06-21 06:07:00 Vuko-wxh

Preface

This article first introduces a brief introduction to 8B/10B Principle , And according to Aurora IP How to use it , Reference resources IP Manual to design incremental test cases , And lower the plate for actual verification .

8B/10B brief introduction

8B/10B, It's also called 8 The bit /10 Bit or 8b10b.8b/10b The way was originally by IBM The company 1983 Invented and applied in ESCON(200M Interconnection system ), from Al Widmer and Peter Franaszek stay IBM The Journal of “ Research and development ” It describes .

**8b/10b One of the features of coding is to guarantee DC Balance ,** use 8b/10b Encoding mode , May cause to be sent “0”、“1” The quantity is basically the same , Successive “1” or “0” No more than 5 position , That is, every 5 A continuous “1” or “0” You have to insert a “0” or “1”, So that the signal DC Balance , It means , It doesn't happen when the link is out of time DC imbalance . adopt 8b/10b code , It can ensure that the transmitted data string can be correctly recovered at the receiving end , besides , Use some special code ( stay PCI-Express In the bus is K code ) , It can help the receiver to restore , And we can find the transmission error of data bit in the early stage , Suppression errors continue to occur .

8b/10b Coding is a continuous set of 8 Bit data is decomposed into two groups of data , A group of 3 position , A group of 5 position , After coding, they become a group 4 Bit code and a set of 6 Bit code , To form a group 10 Bit data is sent out . contrary , Decoding is to 1 Group 10 The input data of bit is transformed to 8 Digit bit . Data values can be uniformly expressed as DX.Y or KX.Y, among D Expressed as data code ,K Expressed as special command code ,X Indicates the low of the input raw data 5 position EDCBA,Y Indicates the height of the input raw data 3 position HGF.

8b/10b Coding is the coding mechanism adopted by many high-speed serial buses , Such as USB3.0、1394b、Serial ATA、PCI Express、Infini-band、Fibre Channel( Fibre channel )、RapidIO Wait for bus or network etc .

working principle

8B/10B Coding is a kind of coding method often used in high-speed serial communication . take 8bit Code as 10bit after ,10B in 0 and 1 The number of digits can only appear 3 In this case :

  1. Yes 5 individual 0 and 5 individual 1
  2. Yes 6 individual 0 and 4 individual 1
  3. Yes 4 individual 0 and 6 individual 1

This leads to a new term “ Inequality (Disparity)”, Namely 1 The number of digits and 0 The difference in the number of digits , According to the above 3 There is a corresponding 3 individual Disparity 0、-2、+2.8bit The raw data will be divided into two parts , Its low 5 Bit will be 5B/6B code , high 3 Who has to 3B/4B code , At that time, these two mapping relationships had become a standardized table . People like to put 8bit The data is expressed as Dx.y In the form of , Its x=5LSB(least significant bit Least significant bit ),y=3MSB(most significant bit Most significant bit ).

For example, one 8bit data 101 10101,x=10101(21) y=“101”(5), Now let's put this 8bit Write the data as D21.5.

about 8bit data , Its bit order in the table is HGFEDCBA, namely H Is the highest position ,A It's the lowest point ,EDCBA after 5B/6B Encoded as abcdei,HGF after 3B/4B Encoded as fghj. delivery 10bit The order of coding is abcdeifghj.

image-20220607153814522

Create a project

Build a new blank project , The chip model I selected here is xc7k160tffg676-2, Milac MK7160FA.

To configure Aurora IP

Create the project , take Aurora IP Add to project , And modify the relevant configuration .lane The width is set to 4, Interfaces generate 32 Bit wide data , If choose 2, Generate a 16 Bit wide data .

image-20220608211027526

Because it is only for transmission test , Therefore, the relevant parameters of the interface can be configured according to the relevant clock of the board ,Link Layer select frame mode , Other defaults are OK .

The board of milanko is stuck in MGT Of 116 Export , So here is the corresponding connection to GTXQ1 On .

image-20220608211147617

The shared logic selection is contained in the kernel , And enable the single port clock option to initialize the clock ,Aurora IP Configuration complete .

image-20220608211349863

Program architecture design

Refer to the idea of routine , It's designed here Aurora Send a test example of an incrementing number , It mainly consists of four modules , Reset module ,Aurora Send data generation module ,Aurora Receiving data module ,Aurora IP.

  • The reset module is mainly used to reset reset and gt_reset Two signals are used for initialization and reset , Make sure Aurora IP Can work normally .
  • Aurora Send data generation module , according to AXI The bus protocol generates incremental test data , And then through Aurora IP Transmit data through optical port .
  • Aurora Receiving data module , according to AXI The bus protocol receives data , And compare whether there is an error in the incremental number transmission by receiving the counting signal , For error indication .

image-20220608205921846

Reset module

Reset module uses start_en As an indication signal for reset , When detected start_en When the rising edge of , The module resets the system reset signal and the transceiver reset signal .reset and gt_reset Reset according to the reset sequence recommended in the manual . It is introduced in detail in this article ,Aurora8B10B IP Use -02- IP Functional design skills .

`timescale 1ns / 1ps
module rst_ctrl(
	input	wire 			clk 				,
	input	wire 			start_en            ,
	output 	wire 			reset 				,//  System reset 
	output 	wire 			gt_reset 	 		 //  Transceiver reset 
    );

//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;// Reset busy indication signal 
reg 	[1:0]	start_flag_dly =0;// Reset enable signal delay 
reg 	[10:0]	cnt_rst        =0;// A counter for generating a reset signal 

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

// Start signal edge 
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

// Reset busy indication signal 
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

// Reset counter 
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

Sending module

The sending part is a simple simulation AXI Bus protocol , Several parameters are specified here , It is convenient for later migration and modification , At the same time, it also exemplifies a ILA IP It is used to detect the correctness of data when loading the board .

`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

Receiving module

The receiving part is a simple simulation AXI The bus protocol receives data , Several parameters are also specified here , It is convenient for later migration and modification , At the same time, it also exemplifies a ILA IP It is used to detect the correctness of data when loading the board .

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

Top level connection

Connect the above modules according to the block diagram drawn above , Instantiated a VIO IP Perform detection and control reset .

`timescale 1ns / 1ps
module Aurora_Top(
    //clock---------------------------------
    input clk_in,          // System clock 
    input gt_refclk116_p , // Differential reference clock 
    input gt_refclk116_n , // Differential reference clock 
    //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

Lower plate test

Set up loopback The default value is 0, Or not for 0 Of is set to 0, Then set it to 0 , Then set the mode to near end loopback test ,1 or 2 All right . You can see channel_up and lane_up Durgao , Connection is established .start Signal pull-up reset , Then set zero to go to the transmission and reception window to observe whether the signal is transmitted and received correctly .

image-20220608214400111

Send partial ILA The window grabs the data and sends it normally , At the same time satisfy AXI The agreement .

image-20220608214333374

Of the receiving part ILA The window grabs the data and receives it normally , At the same time satisfy AXI The agreement ,error The indication signal is usually low , Prove that the data transmission is normal , Link stability .

image-20220608214531853

reference

  1. PG046
  2. Aurora routine
  3. 8B/10B Basic principle of coding
  4. 8B/10B code
  5. 8B/10B Baidu Encyclopedia
原网站

版权声明
本文为[Vuko-wxh]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/172/202206210557325685.html