Xilinx IP Aurora 8B/10B 多级光纤串联复位时序

一、Xilinx官方文档 pg046 复位时序

按照官方文件显示,时序顺序:

① RESET和GT_RESET为0;

②拉高RESET;

③最少128use_clk(程序设为1000个clk)后拉高GT_RESET;

④1s(程序设为49999999个clk)后拉低GT_RESET;

⑤最少128use_clk后拉低RESET(程序设为1000个use_clk)。

初始设计代码:设计思路,上电后重复上述复位时序一次,时钟使用的不是use_clk,使用的init_clk,50MHz。

复制代码
module aurora_rst(
    input  wire clk     ,
    input  wire rstn    ,

    output reg  reset   ,
    output reg  gtreset 
    );
    localparam  IDEL        =   0   ,
                SYS_RESET   =   1   ,
                GT_RESET    =   2   ,
                GT_ASSERT   =   3   ,
                SYS_ASSERT  =   4   ,
                OVER        =   5   ;
    reg [31:0]  cnt   = 0           ;
    reg [4 :0]  cur_state           ;
    always @(posedge clk or negedge rstn) begin
        if(!rstn)
        begin
            cnt         <=  32'd0   ;
            cur_state   <=  IDEL    ;
            reset       <=  0       ;
            gtreset     <=  0       ;
        end
        else
        begin
            case (cur_state)
                IDEL       :
                begin
                    reset       <=  1               ;
                    gtreset     <=  0               ;
                    cur_state   <=  SYS_RESET       ;
                end
                SYS_RESET  :
                begin
                    if(cnt == 1000)
                    begin
                        cnt         <=  0               ;
                        cur_state   <=  GT_RESET        ;
                    end
                    else
                    begin
                        cnt         <=  cnt + 1         ;
                        cur_state   <=  SYS_RESET       ;
                    end
                end
                GT_RESET   :
                begin
                    gtreset         <=  1               ;
                    cur_state       <=  GT_ASSERT       ;
                end
                GT_ASSERT  :
                begin
                    if(cnt == 32'd49999999)
                    begin
                        cnt         <=  0                ;
                        cur_state   <=  SYS_ASSERT       ;
                        gtreset     <=  0                ;
                    end
                    else
                    begin
                        cnt         <=  cnt + 1          ;
                        cur_state   <=  GT_ASSERT        ;
                        gtreset     <=  1                ;
                    end
                end
                SYS_ASSERT :
                begin
                    if(cnt == 1000)
                    begin
                        cnt         <= 0                 ;
                        reset       <= 0                 ;
                        cur_state   <= OVER              ;
                    end
                    else
                    begin
                        cnt         <= cnt + 1           ;
                        reset       <= 1                 ;
                        cur_state   <= SYS_ASSERT        ;
                    end
                end
                OVER       :
                begin
                    reset           <= reset             ;
                    gtreset         <= gtreset           ;
                    cur_state       <= OVER              ;
                end  
                default 
                begin
                    reset           <= reset             ;
                    gtreset         <= gtreset           ;
                    cur_state       <= OVER              ;
                end    
            endcase
        end
    end 
endmodule

二:上述程序问题:

一对一通信,或者五个模块通信,则没问题,但是因为只复位一次,如果级数过多,上电时间不一致,则会出现CHANNEL_UP,LANE_UP不稳现象。

三:解决问题:

如果LANE_UP上升沿重新启动复位逻辑,能保证再上电稳定后,多个板子的IP同时启动复位时序,同时在GT_RESET拉低后延时3S后再拉低RESET,给系统足够多的恢复时间。

复制代码
module aurora_reset_with_laneup (
    input  			clk			, 	// 50MHz
    input  			ext_reset_n	, 	// 外部复位(低有效)
    input  			lane_up		, 	// Aurora IP的lane_up信号
    output reg 		reset		,  	// Aurora RESET(高有效)
    output reg 		gt_reset      	// Aurora GT_RESET(高有效)
);

	// 时序参数(50MHz时钟)
	localparam	RESET_HOLD_1      	=	1000			;	// RESET拉高后保持1000个clk
	localparam	GT_RESET_HOLD     	=	49_999_999		;	// GT_RESET保持49,999,999个clk(约1秒)
	localparam	RESET_HOLD_2      	=	1000			;	// GT_RESET拉低后RESET再保持1000个clk
	localparam	LANEUP_WAIT       	=	1_000_000		;	// lane_up稳定等待20ms
	localparam	TIMEOUT_MAX       	=	150_000_000		;   // 3秒超时
	
	// 状态编码
	localparam	ST_IDLE            	=	4'd0			;
	localparam	ST_RESET_HIGH_1    	=	4'd1			;   // RESET拉高阶段1
	localparam	ST_GT_RESET_HIGH   	=	4'd2			;   // GT_RESET拉高阶段
	localparam	ST_GT_RESET_LOW    	=	4'd3			;   // 等待GT_RESET拉低后的延时
	localparam	ST_RESET_HIGH_2    	=	4'd4			;   // RESET拉高阶段2
	localparam	ST_WAIT_LANEUP     	=	4'd5			;   // 等待lane_up稳定
	localparam	ST_RELEASE_RESET   	=	4'd6			;   // 释放RESET
	localparam	ST_RUNNING         	=	4'd7			;   // 正常运行
	
	reg 		[3:0] 		state						;
	reg 		[31:0] 		timer						;           // 足够大的计数器
	reg 		[19:0] 		laneup_cnt					;
	reg 		[2:0] 		retry_cnt					;

// 状态机时序逻辑
always @(posedge clk or negedge ext_reset_n) begin
    if (!ext_reset_n) begin
        // 外部复位有效(低电平),进入复位状态
        state 				<=	ST_RESET_HIGH_1			;
        reset 				<=	1'b1					;	// RESET拉高
        gt_reset 			<=	1'b0					;	// GT_RESET初始为低
        timer 				<=	0						;
        laneup_cnt 			<=	0						;
        retry_cnt 			<=	0						;
    end else begin
        case (state)
		ST_RESET_HIGH_1: begin
			// 阶段1:RESET拉高,保持1000个clk
			reset 			<=	1'b1					;
			gt_reset 		<=	1'b0					;
			if (timer >= RESET_HOLD_1 - 1) begin
				timer 		<= 	0						;
				state 		<= 	ST_GT_RESET_HIGH		;
			end else begin	
				timer 		<= 	timer + 1				;
			end
		end
		
		ST_GT_RESET_HIGH: begin
			// 阶段2:拉高GT_RESET,保持49,999,999个clk
			reset 			<=	1'b1					;
			gt_reset 		<=	1'b1					;
			if (timer >= GT_RESET_HOLD) begin
				timer 		<= 	0						;
				state 		<= 	ST_GT_RESET_LOW			;
			end else begin
				timer 		<=	timer + 1				;
			end
		end
		
		ST_GT_RESET_LOW: begin
			// 阶段3:拉低GT_RESET,等待一段时间(可选)
			reset 			<= 	1'b1					;
			gt_reset 		<= 	1'b0					;
			if (timer >= 1000) begin  // 额外等待1000个clk
				timer 		<=	0						;
				state 		<=	ST_RESET_HIGH_2			;
			end else begin	
				timer 		<=	timer + 1				;
			end
		end
		
		ST_RESET_HIGH_2: begin
			// 阶段4:RESET保持高,再等1000个clk
			reset 			<= 	1'b1					;
			gt_reset 		<= 	1'b0					;
			if (timer >= RESET_HOLD_2 - 1) begin	
				timer 		<=	0						;
				state 		<=	ST_WAIT_LANEUP			;
				laneup_cnt 	<=	0						;
			end else begin		
				timer 		<=	timer + 1				;
			end
		end
		
		ST_WAIT_LANEUP: begin
			// 阶段5:等待lane_up稳定(此时RESET仍为高)
			reset <= 1'b1;
			gt_reset <= 1'b0;
			
			if (lane_up) begin
				if (laneup_cnt < LANEUP_WAIT) begin
					laneup_cnt <= laneup_cnt + 1;
				end else begin
					// lane_up稳定,可以释放RESET
					state <= ST_RELEASE_RESET;
				end
			end else begin
				laneup_cnt <= 0;
				// 超时重试机制
				if (timer >= TIMEOUT_MAX) begin
					if (retry_cnt < 3) begin
						retry_cnt <= retry_cnt + 1;
						state <= ST_RESET_HIGH_1;  // 重新开始
						timer <= 0;
					end
					// 超过重试次数,保持等待
				end else begin
					timer <= timer + 1;
				end
			end
		end
		
		ST_RELEASE_RESET: begin
			// 阶段6:释放RESET
			reset <= 1'b0;
			gt_reset <= 1'b0;
			state <= ST_RUNNING;
		end
		
		ST_RUNNING: begin
			// 正常运行,监控链路状态
			reset <= 1'b0;
			gt_reset <= 1'b0;
			if (!lane_up) begin
				// 链路意外断开,重新进入复位流程
				state <= ST_RESET_HIGH_1;
				timer <= 0;
				retry_cnt <= 0;
			end
		end
		
		default: begin
			state <= ST_RESET_HIGH_1;
			reset <= 1'b1;
			gt_reset <= 1'b0;
			timer <= 0;
		end
        endcase
    end
end

endmodule

四:结语:

此操作可以使多板子串行通信,在上电时间不一致,以及中途断电再上电后,可以比上电只复位一次程序,恢复更快。但是时间也不确定,有时候十几秒,有时候一分多钟有时候两分多钟,似乎问题还没解决,但是比只复位一次好一些。

相关推荐
是大强4 小时前
数字 IC 设计
fpga开发
十年一梦实验室5 小时前
【Gemini+Claude】根据(工业级智能3D相机)系统描述创建软硬件架构图、爆炸图 +多线程主程序、主循环
数码相机·fpga开发
tiantianuser5 小时前
RDMA设计63:怎么进行网络嗅探功能测试
网络·fpga开发·rdma·高速传输·cmac·roce v2
Risehuxyc5 小时前
Verilog语言的标准发展历程及核心要点
fpga开发
maverick_1111 天前
【FPGA】关于两个数相加的“坑”
c语言·matlab·fpga开发
碎碎思1 天前
经典复活:3dfx Voodoo 显卡,正在被 FPGA“重做一遍”
fpga开发
listhi5201 天前
基于FPGA的电压表与串口通信系统设计
fpga开发
rit84324991 天前
基于FPGA的数字秒表设计(Verilog实现)
fpga开发
tiantianuser1 天前
RDMA设计64:数据吞吐量性能测试分析
网络·fpga开发·rdma·fpga设计·高速传输·roce v2