📄 hdsdi_rx_autorate.vhd
字号:
--------------------------------------------------------------------------------
-- Copyright (c) 2004 Xilinx, Inc.
-- All Rights Reserved
--------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Author: John F. Snow, Advanced Product Division, Xilinx, Inc.
-- \ \ Filename: $RCSfile: hdsdi_rx_autorate.vhd,rcs $
-- / / Date Last Modified: $Date: 2004-12-09 14:52:15-07 $
-- /___/ /\ Date Created: May 28, 2004
-- \ \ / \
-- \___\/\___\
--
--
-- Revision History:
-- $Log: hdsdi_rx_autorate.vhd,rcs $
-- Revision 1.1 2004-12-09 14:52:15-07 jsnow
-- Cosmetic changes only.
--
--------------------------------------------------------------------------------
--
-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
-- AS A COURTESY TO YOU, 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.
--
--------------------------------------------------------------------------------
--
-- This module will automatically toggle the reference clock to the RocketIO
-- transceiver until the data being received is error free. The reference clock
-- will then stay at this clock frequency too many errors are detected.
--
-- The user needs to balance error tolerance against reaction speed in this
-- design. Occasional errors, or even a burst of errors, should not cause the
-- circuit to toggle reference clock frequencies prematurely. On the other hand,
-- in some cases it is necessary to reacquire lock with the bitstream as quickly
-- as possible after the incoming bitstream changes frequencies.
--
-- When running with the wrong reference clock, the RocketIO receiver actually
-- will receive much of the data correctly. Most of the TRS symbols will be
-- correctly received. So, simply looking for missing or bad TRS symbols usually
-- isn't sufficient. A better indication is CRC errors. A CRC error will be
-- detected on virtually every video line when the wrong reference clock is
-- selected. However, simply looking for CRC errors may be insufficient, too,
-- since CRC errors aren't found when there are no TRS symbols being received.
--
-- This module uses both missing TRS symbols and CRC errors as the detection
-- mechanism for determining when to toggle the reference clock frequency. A
-- missing SAV, an SAV with protection bit errors, or a CRC error will cause
-- the finite state machine to flag the error as containing an error. Each line
-- that contains an error causes the error counter to increment. If a line is
-- found that is error free, the error counter is cleared back to zero. When
-- MAX_ERRS consecutive lines occur with errors, the state machine will toggle
-- the refclksel signal.
--
-- The width of the error counter and the MAX_ERRS value are both specified as
-- parameters and can modified by changing the parameter value. Also, the width
-- of the counter that determines if a SAV is missing is also programmable. This
-- counter times out when it reaches a count of all ones, signalling that an SAV
-- missing error has occurred.
--
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use work.hdsdi_pkg.all;
entity hdsdi_rx_autorate is
port (
clk: in std_logic; -- rxusrclk input
rst: in std_logic; -- async reset
sav: in std_logic; -- must be asserted during XYZ of SAV symbols
trs_err: in std_logic; -- TRS error bit from framer
y_crc_err: in std_logic; -- Y channel CRC error
c_crc_err: in std_logic; -- C channel CRC error
refclksel: out std_logic); -- output: 0 = 74.1758 MHz, 1 = 74.25 MHz
end hdsdi_rx_autorate;
architecture synth of hdsdi_rx_autorate is
--
-- Constant and type declarations
--
-- Changing the ERRCNT_WIDTH constant changes the width of the counter that is
-- used to keep track of the number of consecutive lines that contained errors.
-- By changing the counter width and changing the MAX_ERRS constant, the
-- latency for refclksel switching can be changed. Making the MAX_ERRS value
-- smaller will reduce the switching latency, but will also reduce the tolerance
-- to errors and cause unintentional refclksel switching.
--
-- The TRSCNT_WIDTH constant determines the width of the missing SAV timeout
-- counter. Increasing this counter's width causes the state machine to wait
-- longer before determining that a SAV was missing.
--
constant ERRCNT_WIDTH : integer := 2;
constant TRSCNT_WIDTH : integer := 12;
subtype errcnt_type is std_logic_vector(ERRCNT_WIDTH - 1 downto 0);
subtype trscnt_type is std_logic_vector(TRSCNT_WIDTH - 1 downto 0);
constant MAX_ERRS : errcnt_type := (others => '1');
--
-- This group of constants defines the states of the FSM.
--
constant STATE_WIDTH : integer := 3;
subtype state is std_logic_vector(STATE_WIDTH - 1 downto 0);
constant UNLOCK : state := "000";
constant TOG : state := "001";
constant LOCK1 : state := "010";
constant LOCK2 : state := "011";
constant ERR1 : state := "100";
constant ERR2 : state := "101";
--
-- Signal declarations
--
signal current_state : state; -- FSM current state
signal next_state : state; -- FSM next state
signal errcnt : errcnt_type; -- error counter
signal trscnt : trscnt_type; -- TRS timeout counter
signal trscnt_max : trscnt_type; -- MAX TRS count value
signal toggle : std_logic; -- FSM output that toggles refclksel
signal clr_errcnt : std_logic; -- FSM output that clears errcnt
signal inc_errcnt : std_logic; -- FSM output that increments errcnt
signal max_errcnt : std_logic; -- asserted when errcnt = MAX_ERRS
signal trs_tc : std_logic; -- terminal count output from trscnt
signal sel_int : std_logic; -- internal refclksel signal
signal sav_ok : std_logic; -- sav AND NOT trs_err
signal crc_err : std_logic; -- OR of CRC errors from Y and C channels
begin
sav_ok <= sav and not trs_err;
crc_err <= y_crc_err or c_crc_err;
--
-- TRS timeout counter
--
-- This counter is reset whenever a SAV signal is received, otherwise it
-- increments. When it reaches its terminal count, the trs_tc signal is
-- asserted and the the counter will roll over to zero on the next clock
-- cycle.
--
process(clk, rst)
begin
if rst = '1' then
trscnt <= (others => '0');
elsif clk'event and clk = '1' then
if sav_ok = '1' then
trscnt <= (others => '0');
else
trscnt <= trscnt + 1;
end if;
end if;
end process;
trscnt_max <= (others => '1');
trs_tc <= '1' when trscnt = trscnt_max else '0';
--
-- Error counter
--
-- The error counter increments each time the inc_errcnt output from the FSM
-- is asserted. It clears to zero when clr_errcnt is asserted. The
-- max_errcnt output is asserted if the error counter equals MAX_ERRS.
--
process(clk, rst)
begin
if rst = '1' then
errcnt <= (others => '0');
elsif clk'event and clk = '1' then
if inc_errcnt = '1' then
errcnt <= errcnt + 1;
elsif clr_errcnt = '1' then
errcnt <= (others => '0');
end if;
end if;
end process;
max_errcnt <= '1' when errcnt = MAX_ERRS else '0';
--
-- refclksel control signal
--
-- This is the hd_sd mode control output signal. hd_sd_int is the actual
-- flip-flop for internal use in this module and hd_sd is the output from
-- the module.
--
process(clk, rst)
begin
if rst = '1' then
sel_int <= '0';
elsif clk'event and clk = '1' then
if toggle = '1' then
sel_int <= not sel_int;
end if;
end if;
end process;
refclksel <= sel_int;
-- FSM
--
-- The finite state machine is implemented in three processes, one for the
-- current_state register, one to generate the next_state value, and the
-- third to decode the current_state to generate the outputs.
--
-- FSM: current_state register
--
-- This code implements the current state register. It loads with the HSYNC1
-- state on reset and the next_state value with each rising clock edge.
--
process(clk, rst)
begin
if rst = '1' then
current_state <= UNLOCK;
elsif clk'event and clk = '1' then
current_state <= next_state;
end if;
end process;
--
-- FSM: next_state logic
--
-- This case statement generates the next_state value for the FSM based on
-- the current_state and the various FSM inputs.
--
process(current_state, sav_ok, crc_err, max_errcnt, trs_tc)
begin
case current_state is
--
-- The FSM begins in the UNLOCK state and stays there until a SAV
-- symbol is found. In this state, if the TRS timeout counter
-- reaches its terminal count, the FSM moves to the TOG state to
-- toggle the refclksel signal.
--
when UNLOCK =>
if sav_ok = '1' then
next_state <= LOCK1;
elsif trs_tc = '1' then
next_state <= TOG;
else
next_state <= UNLOCK;
end if;
--
-- In the TOG state, the FSM toggles the refclksel signal and
-- returns to the UNLOCK state.
--
when TOG =>
next_state <= UNLOCK;
--
-- This is the main locked state LOCK1. Once a SAV has been found,
-- the FSM stays here until either another SAV is found or the TRS
-- counter times out.
--
when LOCK1 =>
if sav_ok = '1' and crc_err = '0' then
next_state <= LOCK2;
elsif sav_ok = '1' and (crc_err = '1' or trs_tc = '1') then
next_state <= ERR1;
else
next_state <= LOCK1;
end if;
--
-- The FSM moves to LOCK2 from LOCK1 if a SAV is found. The error
-- counter is reset in LOCK2.
--
when LOCK2 =>
next_state <= LOCK1;
--
-- The FSM moves to ERR1 from LOCK 1 if the TRS timeout counter
-- reaches its terminal count before a SAV is found. In this state,
-- the error counter is incremented and the FSM moves to ERR2.
--
when ERR1 =>
next_state <= ERR2;
--
-- The FSM enters ERR2 from ERR1 where the error counter was
-- incremented. In this state the max_errcnt signal is tested. If it
-- is asserted, the FSM moves to the TOG state, otherwise the FSM
-- returns to LOCK1.
--
when ERR2 =>
if max_errcnt = '1' then
next_state <= TOG;
else
next_state <= LOCK1;
end if;
when others =>
next_state <= LOCK1;
end case;
end process;
--
-- FSM: outputs
--
-- This block decodes the current state to generate the various outputs of
-- the FSM.
--
process(current_state)
begin
toggle <= '0';
clr_errcnt <= '0';
inc_errcnt <= '0';
case current_state is
when LOCK2 =>
clr_errcnt <= '1';
when TOG =>
toggle <= '1';
clr_errcnt <= '1';
when ERR1 =>
inc_errcnt <= '1';
when others =>
null;
end case;
end process;
end synth;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -