📄 par_framer.vhd
字号:
--------------------------------------------------------------------------------
-- Copyright (c) 2004 Xilinx, Inc.
-- All Rights Reserved
--------------------------------------------------------------------------------
-- ____ ____
-- / /\/ /
-- /___/ \ / Vendor: Xilinx
-- \ \ \/ Author: John F. Snow, Advanced Product Division, Xilinx, Inc.
-- \ \ Filename: $RCSfile: par_framer.vhd,rcs $
-- / / Date Last Modified: $Date: 2004-08-27 10:08:45-06 $
-- /___/ /\ Date Created: August 14, 2001
-- \ \ / \
-- \___\/\___\
--
--
-- Revision History:
-- $Log: par_framer.vhd,rcs $
-- Revision 1.1 2004-08-27 10:08:45-06 jsnow
-- Fixed bug in encoding of offset_val(0).
--
-- Revision 1.0 2004-08-27 10:08:13-06 jsnow
-- Initial release.
--
--------------------------------------------------------------------------------
--
-- 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.
--
--------------------------------------------------------------------------------
--
-- Description of module:
--
-- SMPTE 259M-1997 serial digital interface (SDI) is a standard for transmitting
-- digital video over a serial link.
--
-- This module accepts 10-bit parallel "unframed" data words from the SDI
-- descrambler module and examines the bit stream for the 30-bit TRS pramble.
-- Once a TRS is found, the framer then knows the bit boundary of all subsequent
-- 10-bit characters in the bit stream and uses this offset to generate a 10-bit
-- parallel data word on its output.
--
-- The module has the following control inputs:
--
-- ce: The clock enable input controls loading of all registers in the module.
-- It must be asserted whenever a new 10-bit word is to be loaded into the
-- module. By providing a clock enable, this module can use a clock that is
-- running at the bit rate of the SDI bit stream if ce is asserted once every
-- ten clock cycles.
--
-- frame_en: This input controls whether the framer rsynchronize to new
-- character offsets when out-of-phase TRS symbols are detected. When this input
-- is high, out-of-phase TRS symbols will cause the framer to resynchronize.
--
-- The module generates the following outputs:
--
-- q: This 10-bit output port contains the properly framed data word. The data
-- is normally valid on this port for 10 clock cycles.
--
-- trs: (timing reference signal) This output is asserted when the q output
-- register holds any of the four words of a TRS.
--
-- nsp: (new start position) If frame_en is low and a TRS is detected that does
-- not match the current character offset, this signal will be asserted high.
-- The nsp signal will remain asserted until the offset error has been
-- corrected.
--
-- There are normally three ways to use the frame_en input:
--
-- frame_en tied high: When frame_en is tied high, the framer will resynchronize
-- on every TRS detected.
--
-- frame_en tied to nsp: When in this mode, the framer implements TRS filtering.
-- If a TRS is detected that is out of phase with the existing character offset,
-- nsp will be asserted, but the framer will not resynchronize. If the next TRS
-- received is in phase with the current character offset, nsp will go low and
-- the will not resynchronize. If the next TRS arrives out of phase with the
-- current character offset, then the new character offset will be loaded and
-- nsp will be deasserted. Single erroneous TRS are ignored in this mode, but
-- if they persist, the decoder will adjust.
--
-- frame_en tied low: The automatic framing function is disabled when frame_en
-- is tied low. If data is being sent across the interface that does not comply
-- with the SDI standard and may contain data that looks like TRS symbols, the
-- framing function can be disabled in this manner.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity par_framer is
port (
clk: in std_ulogic; -- clock input
rst: in std_ulogic; -- async reset input
ce: in std_ulogic; -- clock enable input
d: in std_ulogic_vector(9 downto 0); -- input data bus
frame_en: in std_ulogic; -- enables resynch when 1
q: out std_ulogic_vector(9 downto 0); -- output data bus
trs: out std_ulogic; -- 1 when out reg contains TRS
nsp: out std_ulogic -- new start position detected
);
end par_framer;
architecture synth of par_framer is
-- Internal signals
signal in1_reg: std_ulogic_vector( 9 downto 0); -- input register 1
signal in2_reg: std_ulogic_vector( 9 downto 0); -- input register 2
signal in3_reg: std_ulogic_vector( 9 downto 0); -- input register 3
signal offset_reg: std_ulogic_vector( 3 downto 0); -- offset register
signal barrel_in: std_ulogic_vector(18 downto 0); -- input reg for barrel shifter
signal trs_out: std_ulogic_vector( 3 downto 0); -- generates trs signal
signal in_vector: std_ulogic_vector(38 downto 0); -- concat of 3 input regs & d
signal trs_match1: std_ulogic_vector( 9 downto 0); -- offsets in in_vector(18:0) matching 0x3ff
signal trs_match2: std_ulogic_vector( 9 downto 0); -- offsets in in_vector(28:10) matching 0x000
signal trs_match3: std_ulogic_vector( 9 downto 0); -- offsets in in_vector(38:20) matching 0x000
signal trs_match_all: std_ulogic_vector( 9 downto 0); -- offsets matching complete TRS preamble
signal trs_match1_l1: std_ulogic_vector(15 downto 0); -- intermediate level of gate outputs
signal trs_match2_l1: std_ulogic_vector(15 downto 0); -- intermediate level of gate outputs
signal trs_match3_l1: std_ulogic_vector(15 downto 0); -- intermediate level of gate outputs
signal trs_detected: std_ulogic; -- asserted when TRS is detected
signal trs_error: std_ulogic; -- more than one offset matched the TRS symbol
signal offset_val: std_ulogic_vector( 3 downto 0); -- calculated TRS offset value
signal barrel_out: std_ulogic_vector( 9 downto 0); -- output of barrel shifter
signal new_offset: std_ulogic; -- mismatch between offset_val and offset_reg
signal bs_in: std_ulogic_vector(20 downto 0); -- input vector for barrel shifter (2 MSBs are dummy)
signal bs_m1: std_ulogic_vector(12 downto 0); -- output of first MUX level of barrel shifter
signal bs_sm: std_ulogic_vector( 1 downto 0); -- barrel shifter first level MUX select bits
signal bs_sl: std_ulogic_vector( 1 downto 0); -- barrel shifter second level MUX select bits
begin
--
-- Input registers 1, 2, and 3
--
-- The following three registers form a 3-character deep pipeline
-- which will be examined by the 39-bit wide TRS detector.
--
process(clk, rst)
begin
if (rst = '1') then
in1_reg <= (others => '0');
in2_reg <= (others => '0');
in3_reg <= (others => '0');
elsif (clk'event and clk='1') then
if (ce = '1') then
in1_reg <= d;
in2_reg <= in1_reg;
in3_reg <= in2_reg;
end if;
end if;
end process;
--
-- TRS detector
--
-- The TRS detector finds 30-bit TRS preambles (0x3ff, 0x000, 0x000) in the
-- input data stream. The TRS detector scans a 39-bit input vector
-- consisting of all the bits from the three input registers plus the LS
-- 9 bits of the d input data.
--
-- The detector consists two main parts.
--
-- The first part is a series 10-bit AND and NOR gates that examine each
-- possible bit location in the 39 input vector for the TRS preamble. These
-- 10-bit wide AND and NOR gates have been coded here as two levels of
-- 3 and 4 input gates because this results in a more compact implementation
-- in most synthesis engines.
--
-- The outputs of these gates are assigned to the vectors trs_match1, 2,
-- and 3. These three vectors each contain 10 unary bits that indicate which
-- offset(s) matched the pattern being detected. ANDing these three vectors
-- together generates another 10-bit vector called trs_match_all whose bits
-- indicate which offset(s) matches the entire 30-bit TRS preamble.
--
-- The second part of the TRS detector consists of a case statement based on
-- the trs_match_all vector derived above. The case statement generates two
-- outputs. The first, offset_val, is a value between 0 and 9 that indicates
-- the bit offset of the TRS preamble. This value is only valid if there is
-- one and only one bit asserted in the trs_match_all vector. If
-- trs_match_all contains more or less than one bit set, the trs_error
-- signal will be asserted indicating a error in the TRS detection
-- algorithm.
--
in_vector <= d(8 downto 0) & in1_reg & in2_reg & in3_reg;
-- first level of gates
process(in_vector)
begin
trs_match1_l1( 0) <= in_vector( 3) and in_vector( 2) and
in_vector( 1) and in_vector( 0);
trs_match1_l1( 1) <= in_vector( 4) and in_vector( 3) and
in_vector( 2) and in_vector( 1);
trs_match1_l1( 2) <= in_vector( 5) and in_vector( 4) and
in_vector( 3) and in_vector( 2);
trs_match1_l1( 3) <= in_vector( 6) and in_vector( 5) and
in_vector( 4) and in_vector( 3);
trs_match1_l1( 4) <= in_vector( 7) and in_vector( 6) and
in_vector( 5) and in_vector( 4);
trs_match1_l1( 5) <= in_vector( 8) and in_vector( 7) and
in_vector( 6) and in_vector( 5);
trs_match1_l1( 6) <= in_vector( 9) and in_vector( 8) and
in_vector( 7) and in_vector( 6);
trs_match1_l1( 7) <= in_vector(10) and in_vector( 9) and
in_vector( 8) and in_vector( 7);
trs_match1_l1( 8) <= in_vector(11) and in_vector(10) and
in_vector( 9) and in_vector( 8);
trs_match1_l1( 9) <= in_vector(12) and in_vector(11) and
in_vector(10) and in_vector( 9);
trs_match1_l1(10) <= in_vector(13) and in_vector(12) and
in_vector(11) and in_vector(10);
trs_match1_l1(11) <= in_vector(14) and in_vector(13) and
in_vector(12) and in_vector(11);
trs_match1_l1(12) <= in_vector(15) and in_vector(14) and
in_vector(13) and in_vector(12);
trs_match1_l1(13) <= in_vector(16) and in_vector(15) and
in_vector(14) and in_vector(13);
trs_match1_l1(14) <= in_vector(17) and in_vector(16) and
in_vector(15) and in_vector(14);
trs_match1_l1(15) <= in_vector(18) and in_vector(17) and
in_vector(16) and in_vector(15);
trs_match2_l1( 0) <= not (in_vector(13) or in_vector(12) or
in_vector(11) or in_vector(10));
trs_match2_l1( 1) <= not (in_vector(14) or in_vector(13) or
in_vector(12) or in_vector(11));
trs_match2_l1( 2) <= not (in_vector(15) or in_vector(14) or
in_vector(13) or in_vector(12));
trs_match2_l1( 3) <= not (in_vector(16) or in_vector(15) or
in_vector(14) or in_vector(13));
trs_match2_l1( 4) <= not (in_vector(17) or in_vector(16) or
in_vector(15) or in_vector(14));
trs_match2_l1( 5) <= not (in_vector(18) or in_vector(17) or
in_vector(16) or in_vector(15));
trs_match2_l1( 6) <= not (in_vector(19) or in_vector(18) or
in_vector(17) or in_vector(16));
trs_match2_l1( 7) <= not (in_vector(20) or in_vector(19) or
in_vector(18) or in_vector(17));
trs_match2_l1( 8) <= not (in_vector(21) or in_vector(20) or
in_vector(19) or in_vector(18));
trs_match2_l1( 9) <= not (in_vector(22) or in_vector(21) or
in_vector(20) or in_vector(19));
trs_match2_l1(10) <= not (in_vector(23) or in_vector(22) or
in_vector(21) or in_vector(20));
trs_match2_l1(11) <= not (in_vector(24) or in_vector(23) or
in_vector(22) or in_vector(21));
trs_match2_l1(12) <= not (in_vector(25) or in_vector(24) or
in_vector(23) or in_vector(22));
trs_match2_l1(13) <= not (in_vector(26) or in_vector(25) or
in_vector(24) or in_vector(23));
trs_match2_l1(14) <= not (in_vector(27) or in_vector(26) or
in_vector(25) or in_vector(24));
trs_match2_l1(15) <= not (in_vector(28) or in_vector(27) or
in_vector(26) or in_vector(25));
trs_match3_l1( 0) <= not (in_vector(23) or in_vector(22) or
in_vector(21) or in_vector(20));
trs_match3_l1( 1) <= not (in_vector(24) or in_vector(23) or
in_vector(22) or in_vector(21));
trs_match3_l1( 2) <= not (in_vector(25) or in_vector(24) or
in_vector(23) or in_vector(22));
trs_match3_l1( 3) <= not (in_vector(26) or in_vector(25) or
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -