⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt_window_monitor.v

📁 FPGA之间的LVDS传输
💻 V
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////
//
//    File Name:  RT_WINDOW_MONITOR.v
//      Version:  1.0
//         Date:  08/07/06
//        Model:  Channel Alignment Module
//
//      Company:  Xilinx, Inc.
//  Contributor:  APD Applications Group
//
//   Disclaimer:  XILINX IS PROVIDING THIS DESIGN, CODE, OR
//                INFORMATION "AS IS" SOLELY FOR USE IN DEVELOPING
//                PROGRAMS AND SOLUTIONS FOR XILINX DEVICES.  BY
//                PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
//                ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
//                APPLICATION OR STANDARD, XILINX IS MAKING NO
//                REPRESENTATION THAT THIS IMPLEMENTATION IS FREE
//                FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE
//                RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY
//                REQUIRE FOR YOUR IMPLEMENTATION.  XILINX
//                EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH
//                RESPECT TO THE ADEQUACY OF THE IMPLEMENTATION,
//                INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
//                REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
//                FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES
//                OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//                PURPOSE.
//
//                (c) Copyright 2006 Xilinx, Inc.
//                All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
// 
// Summary:
//
// The RT_WINDOW_MONITOR module adjusts the data sampling window in real-time
// to constantly keep the sampling point at the center of the data eye. To do this,
// every data channel has two parallel (and ideally identical) paths in the receiver.
// One of the paths is the master path carrying user data; the other path is a monitor
// that can be interrogated to determine the position of the sampling point. If the monitor
// shows that the window has drifted toward the hold edge, then the master can be 
// adjusted accordingly.  
//
//----------------------------------------------------------------

module RT_WINDOW_MONITOR
	(
	CLOCK,
	RESET,
	TRAINING_DONE,
	START,
	DATA_MASTER,
	DATA_MONITOR,
	
	INC_MONITOR,
	ICE_MONITOR,
	INC_DATABUS,
	ICE_DATABUS,
	
	DATA_ALIGNED_RT
	);

input		CLOCK;			//RECEIVER CLOCK DOMAIN
input		RESET;			//RESET
input		START;			//FLAG INDICATING THAT CHANNEL SWITCH HAS BEEN MADE
input		TRAINING_DONE;		//FLAG INDICATING THAT INITIAL ALIGNMENT IS COMPLETE
input	[5:0]	DATA_MASTER;		//USER DATA CHANNEL
input	[5:0]	DATA_MONITOR;		//MONITOR DATA CHANNEL

output		INC_MONITOR;		//INCREMENT/DECREMENT DELAY CONTROL FOR MONITOR DATA CHANNEL 
output		ICE_MONITOR;            //INCREMENT/DECREMENT DELAY CONTROL FOR MONITOR DATA CHANNEL
output		INC_DATABUS;		//INCREMENT/DECREMENT DELAY CONTROL FOR USER DATA CHANNEL
output		ICE_DATABUS;            //INCREMENT/DECREMENT DELAY CONTROL FOR USER DATA CHANNEL
output		DATA_ALIGNED_RT;	//FLAG INDICATING THAT PROCEDURE ON CURRENT CHANNEL COMPLETED 

wire	[6:0]	COUNT_VALUE0;
wire	[6:0]	COUNT_VALUE1;
wire	[4:0]	SAMPLE_WINDOW;		//{-2, -1, CENTER, +1, +2}, WHERE "0" IS ERRORS AND "1" IS ERROR FREE AT THAT POSITION
wire		DATA_ALIGNED_RTx;	

reg	[4:0] 	CURRENT_STATE;
reg	[4:0]	NEXT_STATE;
reg		INC_MONITOR;
reg		ICE_MONITOR;
reg		INC_DATABUS;	
reg		ICE_DATABUS;
reg		COUNT0; 
reg		UD0; 
reg		COUNT1; 
reg		UD1; 
reg	[4:0]	STORE_STATUS;
reg		STATUS;


parameter	INIT		= 5'b00000;
parameter	WAIT128		= 5'b00001;
parameter	COMPARE_0	= 5'b00010;
parameter	RECORD_0_0	= 5'b00011;
parameter	RECORD_1_0	= 5'b00100;
parameter	DEC_1_0		= 5'b00101;
parameter	WAIT7_0		= 5'b00110;
parameter	COMPARE_MINUS1	= 5'b00111;
parameter	RECORD_0_1	= 5'b01000;
parameter	RECORD_1_1	= 5'b01001;
parameter	DEC_1_1		= 5'b01010;
parameter	WAIT7_1		= 5'b01011;
parameter	COMPARE_MINUS2	= 5'b01100;
parameter	RECORD_0_2	= 5'b01101;
parameter	RECORD_1_2	= 5'b01110;
parameter	INC_3		= 5'b01111;
parameter	WAIT7_2		= 5'b10000;
parameter	COMPARE_PLUS1	= 5'b10001;
parameter	RECORD_0_3	= 5'b10010;
parameter	RECORD_1_3	= 5'b10011;
parameter	INC_1		= 5'b10100;
parameter	WAIT7_3		= 5'b10101;
parameter	COMPARE_PLUS2	= 5'b10110;
parameter	RECORD_0_4	= 5'b10111;
parameter	RECORD_1_4	= 5'b11000;
parameter	IDLE		= 5'b11001;
parameter	BEGIN_ADJUST	= 5'b11010; 
parameter	INC_ALL		= 5'b11011;
parameter	DEC_ALL		= 5'b11100;
parameter	DEC_2		= 5'b11101;
parameter	DONE		= 5'b11110;

assign 		DATA_ALIGNED_RTx = CURRENT_STATE[4] & CURRENT_STATE[3] & CURRENT_STATE[2] & CURRENT_STATE[1] & ~CURRENT_STATE[0];

FDR count_reg(.Q(DATA_ALIGNED_RT), .C(CLOCK), .D(DATA_ALIGNED_RTx), .R(RESET));
count_to_128 counter0(.clk(CLOCK), .rst(RESET), .count(COUNT0), .ud(UD0), .counter_value(COUNT_VALUE0));
count_to_128 counter1(.clk(CLOCK), .rst(RESET), .count(COUNT1), .ud(UD1), .counter_value(COUNT_VALUE1));

FDRE bit2(.Q(SAMPLE_WINDOW[0]), .C(CLOCK), .CE(STORE_STATUS[0]), .D(STATUS), .R(RESET));
FDRE bit1(.Q(SAMPLE_WINDOW[1]), .C(CLOCK), .CE(STORE_STATUS[1]), .D(STATUS), .R(RESET));
FDRE bit0(.Q(SAMPLE_WINDOW[2]), .C(CLOCK), .CE(STORE_STATUS[2]), .D(STATUS), .R(RESET));
FDRE bitN1(.Q(SAMPLE_WINDOW[3]), .C(CLOCK), .CE(STORE_STATUS[3]), .D(STATUS), .R(RESET));
FDRE bitN2(.Q(SAMPLE_WINDOW[4]), .C(CLOCK), .CE(STORE_STATUS[4]), .D(STATUS), .R(RESET));

//CURRENT STATE LOGIC
always@(posedge CLOCK or posedge RESET)
begin
if(RESET == 1'b1)
	CURRENT_STATE = 5'b00000;
else
	CURRENT_STATE = NEXT_STATE;
end

//NEXT STATE LOGIC
//NOTE: DATA_MONITOR IS INVERTED WITH RESPECT TO DATA_MASTER, SO DURING COMPARISONS
//IN THE NEXT STATE LOGIC, DATA_MONITOR IS ALWAYS USED AS (~DATA_MONITOR) 
always@(CURRENT_STATE or DATA_MASTER or DATA_MONITOR or START or COUNT_VALUE0 or COUNT_VALUE1 or SAMPLE_WINDOW or TRAINING_DONE)
begin
	case (CURRENT_STATE)
	
	INIT:		begin					//REMAIN HERE UNTIL TRAINING COMPLETES
			if (TRAINING_DONE == 1'b0)
				NEXT_STATE <= INIT;
			else if (START == 1'b0)
				NEXT_STATE <= WAIT128;
			else
				NEXT_STATE <= INIT;
			end
	
	WAIT128:	begin					//WAIT 128 CYCLES BEFORE BEGINNING COMPARISON
			if (COUNT_VALUE0 > 7'b1111100)
				NEXT_STATE <= COMPARE_0;
			else
				NEXT_STATE <= WAIT128;
			end 	
	
	COMPARE_0:	begin					//COMPARE THE INITIAL POSITION (0)
			if (DATA_MASTER != (~DATA_MONITOR))
				NEXT_STATE <= RECORD_0_0;
			else
			if (COUNT_VALUE1 < 7'b1111110)
				NEXT_STATE <= COMPARE_0; 
			else
			if (DATA_MASTER == (~DATA_MONITOR))
				NEXT_STATE <= RECORD_1_0;
			else	
				NEXT_STATE <= RECORD_0_0;
			end
	
	RECORD_0_0:	NEXT_STATE <= DEC_1_0;			//INITIAL POSITION HAD ERRORS
	RECORD_1_0:	NEXT_STATE <= DEC_1_0;			//INITIAL POSITION WAS ERROR FREE
	
	DEC_1_0:	NEXT_STATE <= WAIT7_0;			//DECREMENT THE MONITOR TO ONE IDELAY TAP LESS (-1)
	
	WAIT7_0:	begin					//WAIT FOR LATENCY TO SETTLE
			if (COUNT_VALUE0 > 7'b0000111)
				NEXT_STATE <= COMPARE_MINUS1;
			else
				NEXT_STATE <= WAIT7_0;
			end

	COMPARE_MINUS1:	begin					//COMPARE THE -1 POSITION
			if (DATA_MASTER != (~DATA_MONITOR))
				NEXT_STATE <= RECORD_0_1;
			else
			if (COUNT_VALUE1 < 7'b1111110)
				NEXT_STATE <= COMPARE_MINUS1; 
			else
			if (DATA_MASTER == (~DATA_MONITOR))
				NEXT_STATE <= RECORD_1_1;
			else	
				NEXT_STATE <= RECORD_0_1;
			end

	RECORD_0_1:	NEXT_STATE <= DEC_1_1;			// -1 POSITION HAD ERRORS    
	RECORD_1_1:	NEXT_STATE <= DEC_1_1;                  // -1 POSITION WAS ERROR FREE
	
	DEC_1_1:	NEXT_STATE <= WAIT7_1;			//DECREMENT THE MONITOR TO ONE IDELAY TAP LESS (-2)
	
	WAIT7_1:	begin					
			if (COUNT_VALUE0 > 7'b0000111)		//WAIT FOR LATENCY TO SETTLE
				NEXT_STATE <= COMPARE_MINUS2;
			else
				NEXT_STATE <= WAIT7_1;
			end	

	COMPARE_MINUS2:	begin					//COMPARE THE -2 POSITION
			if (DATA_MASTER != (~DATA_MONITOR))
				NEXT_STATE <= RECORD_0_2;
			else
			if (COUNT_VALUE1 < 7'b1111110)
				NEXT_STATE <= COMPARE_MINUS2; 
			else
			if (DATA_MASTER == (~DATA_MONITOR))
				NEXT_STATE <= RECORD_1_2;
			else	
				NEXT_STATE <= RECORD_0_2;
			end
	
	RECORD_0_2:	NEXT_STATE <= INC_3;			// -2 POSITION HAD ERRORS    
	RECORD_1_2:	NEXT_STATE <= INC_3;                    // -2 POSITION WAS ERROR FREE
	
	INC_3:		begin					//INCREMENT THE MONITOR TO THREE IDELAY TAPS MORE (+1)
			if (COUNT_VALUE1 == 7'b0000010)
				NEXT_STATE <= WAIT7_2;
			else 
				NEXT_STATE <= INC_3;
			end
	
	WAIT7_2:	begin					//WAIT FOR LATENCY TO SETTLE 
			if (COUNT_VALUE0 > 7'b0000111)
				NEXT_STATE <= COMPARE_PLUS1;
			else
				NEXT_STATE <= WAIT7_2;
			end
	
	COMPARE_PLUS1:	begin					//COMPARE THE +1 POSITION
			if (DATA_MASTER != (~DATA_MONITOR))
				NEXT_STATE <= RECORD_0_3;
			else
			if (COUNT_VALUE1 < 7'b1111110)
				NEXT_STATE <= COMPARE_PLUS1; 
			else
			if (DATA_MASTER == (~DATA_MONITOR))
				NEXT_STATE <= RECORD_1_3;
			else	
				NEXT_STATE <= RECORD_0_3;
			end
	
	RECORD_0_3:	NEXT_STATE <= INC_1;			// +1 POSITION HAD ERRORS    
	RECORD_1_3:	NEXT_STATE <= INC_1;                    // +1 POSITION WAS ERROR FREE
	
	INC_1:		NEXT_STATE <= WAIT7_3;			//INCREMENT THE MONITOR TO 1 IDELAY TAP MORE (+2)
	
	WAIT7_3:	begin					//WAIT FOR LATENCY TO SETTLE
			if (COUNT_VALUE0 > 7'b0000111)
				NEXT_STATE <= COMPARE_PLUS2;
			else
				NEXT_STATE <= WAIT7_3;
			end
	
	COMPARE_PLUS2:	begin					//COMPARE THE +2 POSITION
			if (DATA_MASTER != (~DATA_MONITOR))
				NEXT_STATE <= RECORD_0_4;
			else
			if (COUNT_VALUE1 < 7'b1111110)
				NEXT_STATE <= COMPARE_PLUS2; 
			else
			if (DATA_MASTER == (~DATA_MONITOR))
				NEXT_STATE <= RECORD_1_4;
			else	
				NEXT_STATE <= RECORD_0_4;
			end
	
	RECORD_0_4:	NEXT_STATE <= IDLE;			// +2 POSITION HAD ERRORS    
	RECORD_1_4:	NEXT_STATE <= IDLE;                     // +2 POSITION WAS ERROR FREE
	
	IDLE:		NEXT_STATE <= BEGIN_ADJUST;
	
	BEGIN_ADJUST:	begin					//BASED ON THE 5 POSITION SAMPLING WINDOW, ADJUST DATA CHANNEL
			case(SAMPLE_WINDOW)
				5'b00001:	NEXT_STATE <= INC_ALL;	//INCREMENT ENTIRE DATA BUS BY 1
				5'b00011:	NEXT_STATE <= INC_ALL;	//INCREMENT ENTIRE DATA BUS BY 1
				5'b00111:	NEXT_STATE <= INC_ALL;	//INCREMENT ENTIRE DATA BUS BY 1
				5'b01111:	NEXT_STATE <= INC_ALL;	//INCREMENT ENTIRE DATA BUS BY 1
				5'b10000:	NEXT_STATE <= DEC_ALL;	//DECREMENT ENTIRE DATA BUS BY 1
				5'b11000:	NEXT_STATE <= DEC_ALL;	//DECREMENT ENTIRE DATA BUS BY 1
				5'b11100:	NEXT_STATE <= DEC_ALL;	//DECREMENT ENTIRE DATA BUS BY 1
				5'b11110:	NEXT_STATE <= DEC_ALL;	//DECREMENT ENTIRE DATA BUS BY 1
				default:	NEXT_STATE <= DEC_2;	//DO NOT ADJUST DATA BUS AT ALL; RETURN MONITOR TO CENTER
			endcase
			end
				
	INC_ALL:	NEXT_STATE <= DEC_2;			//DATA AND MONITOR GET INCREMENTED BY 1
	DEC_ALL:	NEXT_STATE <= DEC_2;			//DATA AND MONITOR GET DECREMENTED BY 1	
	
	DEC_2:		begin					//MONITOR DECREMENTED BY 2 TO RETURN TO INITIAL STATE
			if (COUNT_VALUE1 == 7'b0000001)
				NEXT_STATE <= DONE;
			else 
				NEXT_STATE <= DEC_2;
			end
	
	DONE:		begin					//WAIT IN THIS STATE UNTIL NEXT CHANNEL CAN START
			if (START == 1'b0)
				NEXT_STATE <= DONE;
			else
				NEXT_STATE <= INIT;
			end
	
	default:	NEXT_STATE <= INIT;
	
	endcase
end	

//OUTPUT LOGIC
always@(CURRENT_STATE)
begin
	case(CURRENT_STATE)
	
	INIT:		begin
			COUNT0			<= 1'b0;
			UD0			<= 1'b0;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b0;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b1;	//+2
			STORE_STATUS[1]		<= 1'b1;	//+1
			STORE_STATUS[2]		<= 1'b1;	//0
			STORE_STATUS[3]		<= 1'b1;	//-1
			STORE_STATUS[4]		<= 1'b1;	//-2
			STATUS			<= 1'b0;	
			end

	WAIT128:	begin
			COUNT0			<= 1'b1;
			UD0			<= 1'b1;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b0;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b0;	//+2
			STORE_STATUS[1]		<= 1'b0;	//+1
			STORE_STATUS[2]		<= 1'b0;	//0
			STORE_STATUS[3]		<= 1'b0;	//-1
			STORE_STATUS[4]		<= 1'b0;	//-2
			STATUS			<= 1'b0;
			end
	
	COMPARE_0:	begin
			COUNT0			<= 1'b0;
			UD0			<= 1'b0;
			COUNT1			<= 1'b1;
			UD1			<= 1'b1;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b0;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b0;	//+2
			STORE_STATUS[1]		<= 1'b0;	//+1
			STORE_STATUS[2]		<= 1'b0;	//0
			STORE_STATUS[3]		<= 1'b0;	//-1
			STORE_STATUS[4]		<= 1'b0;	//-2
			STATUS			<= 1'b0;
			end

	RECORD_0_0:	begin
			COUNT0			<= 1'b0;
			UD0			<= 1'b0;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b0;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b0;	//+2
			STORE_STATUS[1]		<= 1'b0;	//+1
			STORE_STATUS[2]		<= 1'b1;	//0
			STORE_STATUS[3]		<= 1'b0;	//-1
			STORE_STATUS[4]		<= 1'b0;	//-2
			STATUS			<= 1'b0;	//ERRORS
			end
	
	RECORD_1_0:	begin
			COUNT0			<= 1'b0;
			UD0			<= 1'b0;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b0;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b0;	//+2
			STORE_STATUS[1]		<= 1'b0;	//+1
			STORE_STATUS[2]		<= 1'b1;	//0
			STORE_STATUS[3]		<= 1'b0;	//-1
			STORE_STATUS[4]		<= 1'b0;	//-2
			STATUS			<= 1'b1;	//ERROR FREE
			end
			
	DEC_1_0:	begin
			COUNT0			<= 1'b0;
			UD0			<= 1'b0;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;
			ICE_MONITOR		<= 1'b1;
			INC_DATABUS		<= 1'b0;
			ICE_DATABUS		<= 1'b0;	
			STORE_STATUS[0]		<= 1'b0;	//+2
			STORE_STATUS[1]		<= 1'b0;	//+1
			STORE_STATUS[2]		<= 1'b0;	//0
			STORE_STATUS[3]		<= 1'b0;	//-1
			STORE_STATUS[4]		<= 1'b0;	//-2
			STATUS			<= 1'b0;
			end
	
	WAIT7_0:	begin
			COUNT0			<= 1'b1;
			UD0			<= 1'b1;
			COUNT1			<= 1'b0;
			UD1			<= 1'b0;	
			INC_MONITOR		<= 1'b0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -