📄 rt_window_monitor.vhd
字号:
--/////////////////////////////////////////////////////////////////////////////
--
-- File Name: RT_WINDOW_MONITOR.vhd
-- 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.
--
------------------------------------------------------------------
----
--
-- Library declarations
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library unisim;
use unisim.vcomponents.all;
--
ENTITY RT_WINDOW_MONITOR IS
PORT (
CLOCK : IN std_logic; -- RECEIVER CLOCK DOMAIN
RESET : IN std_logic; -- RESET
TRAINING_DONE : IN std_logic; -- FLAG INDICATING THAT INITIAL ALIGNMENT IS COMPLETE
START : IN std_logic; -- FLAG INDICATING THAT CHANNEL SWITCH HAS BEEN MADE
DATA_MASTER : IN std_logic_vector(5 DOWNTO 0); -- USER DATA CHANNEL
DATA_MONITOR : IN std_logic_vector(5 DOWNTO 0); -- MONITOR DATA CHANNEL
INC_MONITOR : OUT std_logic; -- INCREMENT/DECREMENT DELAY CONTROL FOR MONITOR DATA CHANNEL
ICE_MONITOR : OUT std_logic; -- INCREMENT/DECREMENT DELAY CONTROL FOR MONITOR DATA CHANNEL
INC_DATABUS : OUT std_logic; -- INCREMENT/DECREMENT DELAY CONTROL FOR USER DATA CHANNEL
ICE_DATABUS : OUT std_logic; -- INCREMENT/DECREMENT DELAY CONTROL FOR USER DATA CHANNEL
DATA_ALIGNED_RT : OUT std_logic); -- FLAG INDICATING THAT PROCEDURE ON CURRENT CHANNEL COMPLETED
END RT_WINDOW_MONITOR;
ARCHITECTURE translated OF RT_WINDOW_MONITOR IS
COMPONENT count_to_128
PORT (
clk : IN std_logic;
rst : IN std_logic;
count : IN std_logic;
ud : IN std_logic;
counter_value : OUT std_logic_vector(6 DOWNTO 0));
END COMPONENT;
SIGNAL COUNT_VALUE0 : std_logic_vector(6 DOWNTO 0);
SIGNAL COUNT_VALUE1 : std_logic_vector(6 DOWNTO 0);
SIGNAL SAMPLE_WINDOW : std_logic_vector(4 DOWNTO 0);
-- {-2, -1, CENTER, +1, +2}, WHERE "0" IS ERRORS
-- AND "1" IS ERROR FREE AT THAT POSITION
SIGNAL DATA_ALIGNED_RTx : std_logic;
SIGNAL CURRENT_STATE : std_logic_vector(4 DOWNTO 0);
SIGNAL NEXT_STATE : std_logic_vector(4 DOWNTO 0);
SIGNAL COUNT0 : std_logic;
SIGNAL UD0 : std_logic;
SIGNAL COUNT1 : std_logic;
SIGNAL UD1 : std_logic;
SIGNAL STORE_STATUS : std_logic_vector(4 DOWNTO 0);
SIGNAL STATUS : std_logic;
CONSTANT INIT : std_logic_vector(4 DOWNTO 0) := "00000";
CONSTANT WAIT128 : std_logic_vector(4 DOWNTO 0) := "00001";
CONSTANT COMPARE_0 : std_logic_vector(4 DOWNTO 0) := "00010";
CONSTANT RECORD_0_0 : std_logic_vector(4 DOWNTO 0) := "00011";
CONSTANT RECORD_1_0 : std_logic_vector(4 DOWNTO 0) := "00100";
CONSTANT DEC_1_0 : std_logic_vector(4 DOWNTO 0) := "00101";
CONSTANT WAIT7_0 : std_logic_vector(4 DOWNTO 0) := "00110";
CONSTANT COMPARE_MINUS1 : std_logic_vector(4 DOWNTO 0) := "00111";
CONSTANT RECORD_0_1 : std_logic_vector(4 DOWNTO 0) := "01000";
CONSTANT RECORD_1_1 : std_logic_vector(4 DOWNTO 0) := "01001";
CONSTANT DEC_1_1 : std_logic_vector(4 DOWNTO 0) := "01010";
CONSTANT WAIT7_1 : std_logic_vector(4 DOWNTO 0) := "01011";
CONSTANT COMPARE_MINUS2 : std_logic_vector(4 DOWNTO 0) := "01100";
CONSTANT RECORD_0_2 : std_logic_vector(4 DOWNTO 0) := "01101";
CONSTANT RECORD_1_2 : std_logic_vector(4 DOWNTO 0) := "01110";
CONSTANT INC_3 : std_logic_vector(4 DOWNTO 0) := "01111";
CONSTANT WAIT7_2 : std_logic_vector(4 DOWNTO 0) := "10000";
CONSTANT COMPARE_PLUS1 : std_logic_vector(4 DOWNTO 0) := "10001";
CONSTANT RECORD_0_3 : std_logic_vector(4 DOWNTO 0) := "10010";
CONSTANT RECORD_1_3 : std_logic_vector(4 DOWNTO 0) := "10011";
CONSTANT INC_1 : std_logic_vector(4 DOWNTO 0) := "10100";
CONSTANT WAIT7_3 : std_logic_vector(4 DOWNTO 0) := "10101";
CONSTANT COMPARE_PLUS2 : std_logic_vector(4 DOWNTO 0) := "10110";
CONSTANT RECORD_0_4 : std_logic_vector(4 DOWNTO 0) := "10111";
CONSTANT RECORD_1_4 : std_logic_vector(4 DOWNTO 0) := "11000";
CONSTANT IDLE : std_logic_vector(4 DOWNTO 0) := "11001";
CONSTANT BEGIN_ADJUST : std_logic_vector(4 DOWNTO 0) := "11010";
CONSTANT INC_ALL : std_logic_vector(4 DOWNTO 0) := "11011";
CONSTANT DEC_ALL : std_logic_vector(4 DOWNTO 0) := "11100";
CONSTANT DEC_2 : std_logic_vector(4 DOWNTO 0) := "11101";
CONSTANT DONE : std_logic_vector(4 DOWNTO 0) := "11110";
BEGIN
DATA_ALIGNED_RTx <= (((CURRENT_STATE(4) AND CURRENT_STATE(3)) AND
CURRENT_STATE(2)) AND CURRENT_STATE(1)) AND NOT CURRENT_STATE(0) ;
count_reg : FDR
PORT MAP (
Q => DATA_ALIGNED_RT,
C => CLOCK,
D => DATA_ALIGNED_RTx,
R => RESET);
counter0 : count_to_128
PORT MAP (
clk => CLOCK,
rst => RESET,
count => COUNT0,
ud => UD0,
counter_value => COUNT_VALUE0);
counter1 : count_to_128
PORT MAP (
clk => CLOCK,
rst => RESET,
count => COUNT1,
ud => UD1,
counter_value => COUNT_VALUE1);
bit2 : FDRE
PORT MAP (
Q => SAMPLE_WINDOW(0),
C => CLOCK,
CE => STORE_STATUS(0),
D => STATUS,
R => RESET);
bit1 : FDRE
PORT MAP (
Q => SAMPLE_WINDOW(1),
C => CLOCK,
CE => STORE_STATUS(1),
D => STATUS,
R => RESET);
bit0 : FDRE
PORT MAP (
Q => SAMPLE_WINDOW(2),
C => CLOCK,
CE => STORE_STATUS(2),
D => STATUS,
R => RESET);
bitN1 : FDRE
PORT MAP (
Q => SAMPLE_WINDOW(3),
C => CLOCK,
CE => STORE_STATUS(3),
D => STATUS,
R => RESET);
bitN2 : FDRE
PORT MAP (
Q => SAMPLE_WINDOW(4),
C => CLOCK,
CE => STORE_STATUS(4),
D => STATUS,
R => RESET);
--CURRENT STATE LOGIC
PROCESS (CLOCK, RESET)
BEGIN
IF (RESET = '1') THEN
CURRENT_STATE <= "00000";
ELSIF (CLOCK'EVENT AND CLOCK = '1') THEN
CURRENT_STATE <= NEXT_STATE;
END IF;
END PROCESS;
--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)
PROCESS (CURRENT_STATE, DATA_MASTER, DATA_MONITOR, START,
COUNT_VALUE0, COUNT_VALUE1, SAMPLE_WINDOW, TRAINING_DONE)
BEGIN
CASE CURRENT_STATE IS
WHEN INIT =>
--REMAIN HERE UNTIL TRAINING COMPLETES
IF (TRAINING_DONE = '0') THEN
NEXT_STATE <= INIT;
ELSE
IF (START = '0') THEN
NEXT_STATE <= WAIT128;
ELSE
NEXT_STATE <= INIT;
END IF;
END IF;
WHEN WAIT128 =>
--WAIT 128 CYCLES BEFORE BEGINNING COMPARISON
IF (COUNT_VALUE0 > "1111100") THEN
NEXT_STATE <= COMPARE_0;
ELSE
NEXT_STATE <= WAIT128;
END IF;
WHEN COMPARE_0 =>
--COMPARE THE INITIAL POSITION (0)
IF (DATA_MASTER /= (NOT DATA_MONITOR)) THEN
NEXT_STATE <= RECORD_0_0;
ELSE
IF (COUNT_VALUE1 < "1111110") THEN
NEXT_STATE <= COMPARE_0;
ELSE
IF (DATA_MASTER = (NOT DATA_MONITOR)) THEN
NEXT_STATE <= RECORD_1_0;
ELSE
NEXT_STATE <= RECORD_0_0;
END IF;
END IF;
END IF;
WHEN RECORD_0_0 =>
NEXT_STATE <= DEC_1_0; -- INITIAL POSITION HAD ERRORS
WHEN RECORD_1_0 =>
NEXT_STATE <= DEC_1_0; -- INITIAL POSITION WAS ERROR FREE
WHEN DEC_1_0 =>
NEXT_STATE <= WAIT7_0;
-- DECREMENT THE MONITOR TO ONE IDELAY TAP LESS (-1)
WHEN WAIT7_0 =>
--WAIT FOR LATENCY TO SETTLE
IF (COUNT_VALUE0 > "0000111") THEN
NEXT_STATE <= COMPARE_MINUS1;
ELSE
NEXT_STATE <= WAIT7_0;
END IF;
WHEN COMPARE_MINUS1 =>
--COMPARE THE -1 POSITION
IF (DATA_MASTER /= (NOT DATA_MONITOR)) THEN
NEXT_STATE <= RECORD_0_1;
ELSE
IF (COUNT_VALUE1 < "1111110") THEN
NEXT_STATE <= COMPARE_MINUS1;
ELSE
IF (DATA_MASTER = (NOT DATA_MONITOR)) THEN
NEXT_STATE <= RECORD_1_1;
ELSE
NEXT_STATE <= RECORD_0_1;
END IF;
END IF;
END IF;
WHEN RECORD_0_1 =>
NEXT_STATE <= DEC_1_1; -- -1 POSITION HAD ERRORS
WHEN RECORD_1_1 =>
NEXT_STATE <= DEC_1_1; -- -1 POSITION WAS ERROR FREE
WHEN DEC_1_1 =>
NEXT_STATE <= WAIT7_1; -- DECREMENT THE MONITOR TO ONE IDELAY TAP LESS (-2)
WHEN WAIT7_1 =>
IF (COUNT_VALUE0 > "0000111") THEN
--WAIT FOR LATENCY TO SETTLE
NEXT_STATE <= COMPARE_MINUS2;
ELSE
NEXT_STATE <= WAIT7_1;
END IF;
WHEN COMPARE_MINUS2 =>
--COMPARE THE -2 POSITION
IF (DATA_MASTER /= (NOT DATA_MONITOR)) THEN
NEXT_STATE <= RECORD_0_2;
ELSE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -