高速接口----使用Aurora8b10b完成光口收发数据(2)

1 Aurora复位

  从手册上可以得知,Aurora的IP的复位需要关注的信号有reset,gt_reset等,在不同模式下,IP和生成的复位信号是不一样的。

模式 信号
全双工 reset : 系统复位
gt_reset :收发器复位
单工模式 tx_system_reset :发送端口复位
rx_system_reset :接收端口复位

  在设计复位的时候,是需要遵守相关的时序才可以的。

1.1 全双工模式下的复位

1.1.1 reset复位时序

  在全双工模式的复位下,reset信号必须保持断言6个user_clk的时钟周期,在reset取消断言后的三个时钟周期,channel_up就被置为无效。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第1张图片

1.1.2 gt_reset复位时序

  gt_reset 必须保持6个init_clk时钟周期的断言,在一段时间后呢,这个user_clk就是停止,因为此时收发器已经被复位了,收发器不会向外提供时钟,从而导致channel_up被置为无效。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第2张图片

1.1.3 全双工模式下的上电时序和复位时序

  在全双工模式下,给FPGA上电时,gt_reset和reset信号都必须保持为高电平,与此同时收发器的参考时钟gt_clk和初始化时钟init_clk都必须保持稳定。这样才能上电成功。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第3张图片
  复位操作的具体执行过程可以按照下面的时序图进行:

  1. 在gt_reset断言之前,reset信号必须稳定保持128个user_clk时钟周期的断言
  2. gt_reset断言保持一段时间(图中所示为1s)
  3. 在gt_reset取消断言一段时间后,reset取消断言

高速接口----使用Aurora8b10b完成光口收发数据(2)_第4张图片

1.2 单工模式下的复位

  单工模式下的复位和全双工模式下的复位类似,具体可以参照数据手册,在这里不做过多介绍。



2 配置Aurora 8b10b IP

  在ZYNQ7000系列FPGA中,含有一个QUAD的高速收发器,通过配置Aurora 8B10B IP可以使用到具体高速收发器的通道。首先,在IP Catalog中搜索 Aurora,然后双击该IP,进入到配置界面。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第5张图片
  core option界面中按照如下配置:

高速接口----使用Aurora8b10b完成光口收发数据(2)_第6张图片

参数(物理层) 含义
Lane Width 表示高速收发器一个Lane传输的数据的位宽,这里选择4表示一个lane传输的数据位宽是32bit
若选择2表示igeLane传输的数据是16bit
Line Rate 线速率,是值高速收发器最大的传输速率由于Aurora采用了8B10B的编码,因此实际传输数据
的效率只有最大线速率的4/5以下
GT Refclk 收发器的参考时钟,可以根据原理图上,光口所在收发器来确定其频率
INIT clk 初始化时钟,选定的范围只能在后面标定的范围内,这里设置为50M,这个时钟在初始化阶段会
使用到
DRP clk DRP总线上的时钟
参数(链路层) 含义
Data flow mode 工作模式,可以配置为全双工模式,或者单工模式,单工模式下可以值配置为接收或者发送,在本次实验中选择全双工模式
Interface 用户接口类型,可以是数据帧类型:framing也可以是数据流类型:streaming。在本次实验中选则framing
Flow control 流控接口,可以在数据传输的过程中插入一些控制字,可以选择UFC(User Flow Control Interface),或者其他类型接口(Native flow control )等。本次实验选择UFC
Back Channel 只有在单工模式下才可以选择
Scrambler/Descrambler 添加加扰器或者解扰器,在本次实验中不选择
Little Endian Support 选择该选项,数据将会以小印第安序的方式组成。在本次实验中不选择
CRC 选项该选项,将会在接收数据时,对接收数据进行校验

  在GT Selection界面,可以选择配置收发器所处的位置,并且将对应位,置一表示使用该收发器。

高速接口----使用Aurora8b10b完成光口收发数据(2)_第7张图片

高速接口----使用Aurora8b10b完成光口收发数据(2)_第8张图片

3 程序设计

  本次实验的整体结构如下图所示,在顶层模块中需要设计如下三个模块,分别是用户数据发送模块,用户数据接收模块,和复位模块。
  其中用户数据发送模块,使用AXI-stram接口将用户数据和UFC信号发送给Aurora IP,Aurora IP将这些信号通过高速串行接口发送出去。
  用户数据接收模块,使用AXI-Stram接口从Aurora IP接收数据,并且判断接收回来的数据是否正确。
  复位模块负责向Auroa 8B10B模块提供复位信号,使得高速收发器链路能够正常链接。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第9张图片
高速接口----使用Aurora8b10b完成光口收发数据(2)_第10张图片

3.1 复位模块设计

`timescale 1ns / 1ps

module gtp_reset_control(
	input	wire 			clk 				,
	input 	wire 			rst 				,

	input 	wire 			channel_link_up 	,// 通道链接信号
	input 	wire 			lane_link_up 		,// lane 链接信号 

	output 	wire 			reset 				,// 系统复位
	output 	wire 			gt_reset 	 		 // 收发器复位
    );

//==========================================
//parameter define
//==========================================
parameter IDLE = 3'b001; //上电状态
parameter RESET = 3'b010; //GTP复位状态
parameter DETECT = 3'b100; //检测LINK状态

parameter RESET_MAX = 384 ;
parameter GT_RESET_MAX = 128  ;


//==========================================
//internal signals
//==========================================
reg 	[2:0]	state 			;
reg 			reset_r 		;//系统复位信号
reg 			gt_reset_r 		;//收发器复位信号

wire 			link_flag 		;//用于判断当前是否链接
reg 	[1:0]	link_flag_dd 	;//link 延时信号
reg 	[10:0]	cnt_rst 		;//用于产生复位信号的计数器
wire			add_cnt_rst		;
wire 			end_cnt_rst 	;

assign link_flag = channel_link_up & lane_link_up;
assign reset = reset_r;
assign gt_reset = gt_reset_r;


//----------------state machine describe------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		state <= IDLE ;
	end
	else begin
		case(state )
			IDLE : begin
				state <= RESET;
			end

			RESET : begin
				if (end_cnt_rst == 1'b1) begin
					state <= DETECT;
				end
				else begin
					state <= RESET;
				end
			end

			DETECT : begin
				//检测到link状态出现下降沿
				if (link_flag_dd[0] == 1'b0 && link_flag_dd[1] == 1'b1) begin
					state <= RESET;
				end
				else begin
					state <= DETECT;
				end
			end

			default : begin
				state <= IDLE ;
			end
		endcase
	end
end

//----------------cnt_rst ------------------
always @(posedge clk) begin
	if (rst == 1'b1) begin
		cnt_rst <= 'd0;
	end
	else if (add_cnt_rst) begin
		if(end_cnt_rst)
			cnt_rst <= 'd0;
		else
			cnt_rst <= cnt_rst + 1'b1;
	end
	else begin
		cnt_rst <= 'd0;
	end
end

assign add_cnt_rst = state == RESET;
assign end_cnt_rst = add_cnt_rst &&	cnt_rst == RESET_MAX - 1;

//----------------link_flag_dd------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		link_flag_dd <= 'd0;
	end
	else begin
		link_flag_dd <= {link_flag_dd[0], link_flag};
	end
end

//----------------gt_reset_r------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		gt_reset_r <= 1'b1;
	end
	else if (link_flag_dd[0] == 1'b0 && link_flag_dd[1] == 1'b1) begin
		gt_reset_r <= 1'b1;
	end
	else if (state == RESET && cnt_rst == GT_RESET_MAX - 1) begin
		gt_reset_r <= 1'b0;
	end
end

//----------------reset_r------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		reset_r <= 1'b1;
	end
	else if (link_flag_dd[0] == 1'b0 && link_flag_dd[1] == 1'b1) begin
		reset_r <= 1'b1;
	end
	else if (state == RESET && cnt_rst == RESET_MAX - 1) begin
		reset_r <= 1'b0;
	end
end
endmodule

3.2 发送数据模块

module gtp_tx(
	input	wire			clk 				,		
	input 	wire 			rst 				,		
	output 	wire [0 : 31] 	s_axi_tx_tdata		,
	output 	wire [0 : 3] 	s_axi_tx_tkeep		,
	output 	wire 			s_axi_tx_tlast		,
	output 	wire 			s_axi_tx_tvalid		,
	input 	wire 			s_axi_tx_tready		,

	output 	wire 			s_axi_ufc_tx_tvalid	,	
	output 	wire [0 : 2] 	s_axi_ufc_tx_tdata	,
	input 	wire 			s_axi_ufc_tx_tready		
    );

//==========================================
//parameter defien
//==========================================
parameter 	STREAM_LEN = 1024 	;


reg 	[0:31]	axi_tx_tdata			;
reg 			axi_tx_tlast			;
reg 			axi_tx_tvalid			;
reg 			axi_ufc_tx_tvalid		;

reg 	[15:0]	cnt_burst 				;
wire 			add_cnt_burst 			;
wire 			end_cnt_burst 			;

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 s_axi_ufc_tx_tvalid = axi_ufc_tx_tvalid;
assign s_axi_ufc_tx_tdata = 3'b001;

//----------------cnt_burst ------------------
always @(posedge clk) begin
	if (rst == 1'b1) begin
		cnt_burst <= 'd0;
	end
	else if (add_cnt_burst) begin
		if(end_cnt_burst)
			cnt_burst <= 'd0;
		else
			cnt_burst <= cnt_burst + 1'b1;
	end
end

assign add_cnt_burst = s_axi_tx_tready & axi_tx_tvalid;
assign end_cnt_burst = add_cnt_burst &&	cnt_burst == STREAM_LEN - 1;

//-----------------axi_tx_tlast-----------------
always @(*) begin
	axi_tx_tlast = end_cnt_burst;
end

//----------------axi_tx_tvalid------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		axi_tx_tvalid <= 1'b0;
	end
	else if (end_cnt_burst == 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_burst;
end

//----------------axi_ufc_tx_tvalid------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		axi_ufc_tx_tvalid <= 1'b0;
	end
	else if (end_cnt_burst == 1'b1) begin
		axi_ufc_tx_tvalid <= 1'b1;
	end
	else if (axi_ufc_tx_tvalid == 1'b1 && s_axi_ufc_tx_tready == 1'b1)begin
		axi_ufc_tx_tvalid <= 1'b0;
	end
end
wire [127:0]	probe0;
assign probe0 = {
	s_axi_tx_tdata		,
	s_axi_tx_tkeep		,
	s_axi_tx_tlast		,
	s_axi_tx_tvalid		,
	s_axi_tx_tready		,
	s_axi_ufc_tx_tvalid	,
	s_axi_ufc_tx_tdata	,
	s_axi_ufc_tx_tready	,
	cnt_burst

};
ila_0 inst_tx (
	.clk(clk), // input wire clk


	.probe0(probe0) // input wire [127:0] probe0
);
endmodule

3.3 接收模块

`timescale 1ns / 1ps
module gtp_rx(
	input 	wire			clk 				,
	input 	wire 			rst 				,

	input	wire [0 : 31] 	m_axi_rx_tdata		,
	input	wire [0 : 3] 	m_axi_rx_tkeep		,
	input	wire 			m_axi_rx_tlast		,
	input	wire 			m_axi_rx_tvalid		,
	input	wire [0 : 31] 	m_axi_ufc_rx_tdata	,	
	input	wire [0 : 3] 	m_axi_ufc_rx_tkeep	,	
	input	wire 			m_axi_ufc_rx_tlast	,	
	input	wire 			m_axi_ufc_rx_tvalid	,

	output  wire 			error 
    );
//==========================================
//parameter define
//==========================================
parameter STREAM_LEN = 1024;


reg 	[15:0]	cnt_burst 		;
wire 			add_cnt_burst 	;
wire 			end_cnt_burst 	;

reg 			error_r 		;

assign error  = error_r;


always @(posedge clk) begin
	if (rst == 1'b1) begin
		cnt_burst <= 'd0;
	end
	else if (add_cnt_burst) begin
		if(end_cnt_burst)
			cnt_burst <= 'd0;
		else
			cnt_burst <= cnt_burst + 1'b1;
	end
end

assign add_cnt_burst = m_axi_rx_tvalid;
assign end_cnt_burst = add_cnt_burst &&	cnt_burst == STREAM_LEN - 1;

//----------------error_r------------------
always @(posedge clk) begin
	if (rst==1'b1) begin
		error_r <= 1'b0;
	end
	else if (m_axi_rx_tvalid && (m_axi_rx_tdata != cnt_burst)) begin
		error_r <= 1'b1;
	end
end
wire [127:0]	probe0;
assign probe0 = {
	m_axi_rx_tdata		,
	m_axi_rx_tkeep		,
	m_axi_rx_tlast		,
	m_axi_rx_tvalid		,
	m_axi_ufc_rx_tdata	,
	m_axi_ufc_rx_tkeep	,
	m_axi_ufc_rx_tlast	,
	m_axi_ufc_rx_tvalid	,
	error_r,
	cnt_burst
};
ila_0 inst_rx (
	.clk(clk), // input wire clk


	.probe0(probe0) // input wire [127:0] probe0
);
endmodule

顶层模块

`timescale 1ns / 1ps
module top_aurora_loop(
	input	wire		clk 		,
	input 	wire 		rst_n 		,
	output 	wire 		led 		,
	output 	wire 		tx_dis		,

	input 	wire 		REF_CLK_P 	,
	input 	wire 		REF_CLK_N 	,

	input 	wire 		RXP 		,
	input 	wire 		RXN 		,
	output 	wire 		TXP 		,
	output 	wire 		TXN 		
    );



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		;
wire 			s_axi_ufc_tx_tvalid	;// 发送流控端口			
wire [0 : 2] 	s_axi_ufc_tx_tdata	;				
wire 			s_axi_ufc_tx_tready	;			
wire [0 : 31] 	m_axi_rx_tdata		;// 接收数据端口				
wire [0 : 3] 	m_axi_rx_tkeep		;			
wire 			m_axi_rx_tlast		;	
wire 			m_axi_rx_tvalid		;		
wire [0 : 31] 	m_axi_ufc_rx_tdata	;// 接收流控数据端口					
wire [0 : 3] 	m_axi_ufc_rx_tkeep	;				
wire 			m_axi_ufc_rx_tlast	;		
wire 			m_axi_ufc_rx_tvalid	;			

wire 			hard_err			;// 物理层错误
wire 			soft_err			;// 链路层错误
wire 			frame_err			;// 帧错误

wire 			reset				;// 复位信号,正确的复位才能使收发器正常工作
wire 			gt_reset			;

wire 			channel_up			;// 链接信号
wire [0 : 0] 	lane_up				;		
wire 			crc_valid			;
wire 			crc_pass_fail_n		;


// GTP 收发通道
wire [0 : 0] 	txp					;	
wire [0 : 0] 	txn					;	
wire [0 : 0] 	rxp					;
wire [0 : 0] 	rxn					;

wire 			tx_lock					;		
wire 			tx_resetdone_out		;			
wire 			rx_resetdone_out		;			
wire 			link_reset_out			;			
wire 			init_clk_in				;// GTP初始化时钟		
wire 			user_clk_out			;// 系统稳定的时钟			
wire 			pll_not_locked_out		;			
wire 			sys_reset_out			;// 系统复位信号
wire 			gt_refclk1_p			;// GTP 通道参考时钟	
wire 			gt_refclk1_n			;	
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 			sys_rst 				;//用户模块复位信号(高有效),当前已经链接上,并且系统复位结束
wire 			rst 					;
wire 			error 					;


assign rst  = ~rst_n;
assign led = ~error;
assign tx_dis = 1'b0;
assign {TXP, TXN} = {txp, txn};
assign {rxp, rxn} = {RXP, RXN};
assign {gt_refclk1_p, gt_refclk1_n} = {REF_CLK_P, REF_CLK_N};

assign sys_rst = ~(channel_up & lane_up & (~sys_reset_out));
assign init_clk_in = clk;
assign drpclk_in = clk;

gtp_reset_control  inst_gtp_reset_control (
	.clk             (init_clk_in),
	.rst             (rst),
	.channel_link_up (channel_up),
	.lane_link_up    (lane_up),
	.reset           (reset),
	.gt_reset        (gt_reset)
);

gtp_tx inst_gtp_tx (
	.clk                 (user_clk_out),
	.rst                 (sys_rst),
	.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),
	.s_axi_ufc_tx_tvalid (s_axi_ufc_tx_tvalid),
	.s_axi_ufc_tx_tdata  (s_axi_ufc_tx_tdata),
	.s_axi_ufc_tx_tready (s_axi_ufc_tx_tready)
);

gtp_rx  inst_gtp_rx (
	.clk                 (user_clk_out),
	.rst                 (sys_rst),
	.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),
	.m_axi_ufc_rx_tdata  (m_axi_ufc_rx_tdata),
	.m_axi_ufc_rx_tkeep  (m_axi_ufc_rx_tkeep),
	.m_axi_ufc_rx_tlast  (m_axi_ufc_rx_tlast),
	.m_axi_ufc_rx_tvalid (m_axi_ufc_rx_tvalid),
	.error               (error)
);

aurora inst_aurora (
  	.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
  	.s_axi_ufc_tx_tvalid(s_axi_ufc_tx_tvalid),        // input wire s_axi_ufc_tx_tvalid
  	.s_axi_ufc_tx_tdata(s_axi_ufc_tx_tdata),          // input wire [0 : 2] s_axi_ufc_tx_tdata
  	.s_axi_ufc_tx_tready(s_axi_ufc_tx_tready),        // output wire s_axi_ufc_tx_tready
  	.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
  	.m_axi_ufc_rx_tdata(m_axi_ufc_rx_tdata),          // output wire [0 : 31] m_axi_ufc_rx_tdata
  	.m_axi_ufc_rx_tkeep(m_axi_ufc_rx_tkeep),          // output wire [0 : 3] m_axi_ufc_rx_tkeep
  	.m_axi_ufc_rx_tlast(m_axi_ufc_rx_tlast),          // output wire m_axi_ufc_rx_tlast
  	.m_axi_ufc_rx_tvalid(m_axi_ufc_rx_tvalid),        // output wire m_axi_ufc_rx_tvalid
  	.hard_err(hard_err),                              // output wire hard_err
  	.soft_err(soft_err),                              // output wire soft_err
  	.frame_err(frame_err),                            // output wire frame_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(3'b000),                                // input wire [2 : 0] loopback
  	.rxp(rxp),                                        // input wire [0 : 0] rxp
  	.rxn(rxn),                                        // input wire [0 : 0] rxn
  	.crc_valid(crc_valid),                            // output wire crc_valid
  	.crc_pass_fail_n(crc_pass_fail_n),                // output wire crc_pass_fail_n
  	.drpclk_in(drpclk_in),                            // input wire drpclk_in
  	.drpaddr_in('d0),                          // input wire [8 : 0] drpaddr_in
  	.drpen_in(1'b0),                              	  // input wire drpen_in
  	.drpdi_in('d0),                              // 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(1'b0), 	                              // input wire drpwe_in
  	.power_down(1'b0 ),                          	  // 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
);
endmodule

4 测试结果

  由于手上的光电转换模块,不是光纤,因此不能做一个单个的回环,那么手上有两块带光口的FPGA(别问,问就是老板的是),那么就可以使用这两块开发板来完成通信。
同样的板子,下载同样的程序,观察同样的现象。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第11张图片

4.1 发送模块

  可以看到用户发送模块正在发送数据。仔细康康可以发现,发送的是0~1023的递增数据。符合设计要求。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第12张图片
高速接口----使用Aurora8b10b完成光口收发数据(2)_第13张图片

4.2 用户接收模块

  可以看到用户接收模块也接收到了数据,并且error信号为低,那么就说明传输的数据是正确的,接收到的数据,也是0~1023的递增数据哦。
高速接口----使用Aurora8b10b完成光口收发数据(2)_第14张图片
高速接口----使用Aurora8b10b完成光口收发数据(2)_第15张图片
  如果把下载器接到另外一块板子上,同样也能观察到这个现象哦。


参考资料:
pg046-aurora-8b10b.pdf
Aurora8b10b IP example design

你可能感兴趣的:(高速接口)