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

四:结语:

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

相关推荐
LCMICRO-133108477467 小时前
长芯微LCMDC7616完全P2P替代AD7616,16通道16位模数转换器(ADC)
stm32·嵌入式硬件·fpga开发·硬件工程·模数转换器adc·电力线监测
又菜又爱玩的东哥10 小时前
【Verilog 3-8译码器设计与仿真:深入理解case语句与组合逻辑】
fpga开发
Risehuxyc10 小时前
<= 是Verilog中的非阻塞赋值操作符
fpga开发
扣脑壳的FPGAer10 小时前
傅里叶级数、傅里叶变换、Z变换、数字滤波器
fpga开发·信号处理
Risehuxyc12 小时前
HDL中assigned 与 always 有什么区别?
fpga开发
我爱C编程14 小时前
【3.5】固定旋转因子系数乘法模块的FPGA实现1——45°旋转因子和高阶蝶形修正因子
fpga开发·固定旋转因子·旋转因子
Terasic友晶科技1 天前
答疑解惑 | DE25-Nano开发板串口在访问FPGA端外设LED时卡死,无任何反应
fpga开发·串口·led·de25-nano
尤老师FPGA1 天前
LVDS系列46:Xilinx Ultrascale系 ADC LVDS接口参考方法(八)
fpga开发
何如呢1 天前
uw_inserter
fpga开发
何如呢1 天前
SC-FDE_tx_comb_part
fpga开发