📄 rt_window_monitor.v
字号:
///////////////////////////////////////////////////////////////////////////////
//
// 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 + -