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

📄 anc_insert.vhd

📁 XAPP299 version 1.0 reference design files
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------
-- anc_insert.vhd
--
-- SDI ANC packet insertion module
--
--
--
--                  Author: John F. Snow
--                  Staff Applications Engineer
--
--                  Video Applications
--                  Advanced Products Group
--                  Xilinx, Inc.
--
--                  Copyright (c) 2002 Xilinx, Inc.
--                  All rights reserved
--
--                  Date:   May 8, 2002
--
--                  RESTRICTED RIGHTS LEGEND
--
--      This software has not been published by the author, and 
--      has been disclosed to others for the purpose of enhancing 
--      and promoting design productivity in Xilinx products.
--
--      Therefore use, duplication or disclosure, now and in the 
--      future should give consideration to the productivity 
--      enhancements afforded the user of this code by the author's 
--      efforts.  Thank you for using our products !
--
-- Disclaimer:  THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY 
--              WHATSOEVER AND XILINX SPECIFICALLY DISCLAIMS ANY 
--              IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
--              A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT.
--
-- Revision:
--              May 8, 2002     Release
--
-- Other modules instanced in this design:
--
--------------------------------------------------------------------------------
-- 
-- This module is instanced by the anc_mux module. The anc_insert module
-- searches the video stream for an appropriate place to insert a new ANC
-- packet. The ANC space must be of the appropriate type (HANC or VANC) as
-- requested by the hanc_pkt and vanc_pkt inputs. The space must also be large
-- enough to accomodate a packet of the size indicated by the pkt_size value.
-- This module will overwrite end_marker packets but does not overwrite packets
-- that have been marked for deletion.
-- 
-- The new ANC packet data comes in on the anc_in port. When the pkt_rdy
-- input is asserted, the module begins looking for a free ANC space for the
-- packet. Note that when pkt_rdy is asserted, the module assumes that the first
-- word of the ADF is present on the anc_in port. The total number of words in
-- the new packet must also be present on the pkt_size port when pkt_rdy is
-- asserted.
-- 
-- The module will always assure that ANC packets are contiguous in the ANC
-- space. New packets will only be inserted immediately after the TRS symbols
-- at the beginning of the ANC space, after an existing EDH packet, or in place
-- of an end-marker ANC packet. The module respects the "keep-out" area around
-- the synchronous switching interval and also the spaces reserved for EDH
-- packets.
-- 
-- When the modules finds a candidate ANC space for the new packet, it asserts
-- the send_pkt output. At the next rising clock edge, the anc_in port must 
-- change to the second word of the ADF. Each word of the new packet must be 
-- placed on anc_in during each successive clock cycle. When the last word (CS) 
-- of the ANC packet is on the anc_in port, the pkt_end signal must also be 
-- asserted to let the module know that the end of the packet has been reached. 
-- Note that send_pkt is asserted by the module for only a single clock cycle to 
-- begin the process of sending the ANC packet.
-- 
-- In some cases, the module will attempt to insert the packet, only to find out
-- that the packet couldn't really be inserted. This is because either the ANC
-- space was part of the prohibited synchronous switching interval or because
-- another ANC packet already exists in the video stream and cannot be
-- overwritten. In this case, the module will assert the abort_pkt signal. The 
-- module sending the packet to anc_insert must stop sending the packet and 
-- resend the same packet when anc_insert next asserts the send_pkt signal. The
-- anc_insert module is designed in such a way that when a packet insertion is 
-- aborted, the data in the video stream is not corrupted in any way.
--

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.anc_edh_pkg.all;

entity anc_insert is
    port (
        -- inputs
        clk:            in  std_ulogic;  -- clock input
        ce:             in  std_ulogic;  -- clock enable
        rst:            in  std_ulogic;  -- async reset input
        pkt_rdy :       in  std_ulogic;  -- indicates packet is ready to be sent
        anc_in :        in  video_type;  -- ANC packet data input
        vid_in :        in  video_type;  -- video data input
        pkt_size :      in  pktsize_type;-- size of packet to be sent
        pkt_end :       in  std_ulogic;  -- indicates last word of packet being sent
        anc_next :      in  std_ulogic;  -- vid_in contains ANC packet starting at next word
        eav_next :      in  std_ulogic;  -- vid_in contains EAV starting at next word
        sav_next :      in  std_ulogic;  -- vid_in contains SAV starting at next word
        hanc_pkt :      in  std_ulogic;  -- ANC packet to be sent can be inserted into HANC space
        vanc_pkt :      in  std_ulogic;  -- ANC packet to be sent can be inserted into VANC space
        std :           in  vidstd_type; -- current video standard
        v_blank :       in  std_ulogic;  -- vertical blanking indicator
        field :         in  std_ulogic;  -- field indicator
        horz_count :    in  hpos_type;   -- current horizontal position
        vert_count :    in  vpos_type;   -- current vertical position
        switch_line :   in  std_ulogic;  -- current line is a sync switching line
    
        -- outputs
        vid_out :       out video_type;  -- output video data
        send_pkt :      out std_ulogic;  -- tells anc_pkt_gen to send packet
        abort_pkt :     out std_ulogic); -- tells anc_pkt_gen to abort packet
end;
        
architecture synth of anc_insert is

-- The padding subtype is used to pad the packet size vector to the lenth of
-- the horizontal position vector.
subtype padding   is std_logic_vector(HCNT_WIDTH - 9 downto 0);

-------------------------------------------------------------------------------
-- Constant definitions
--      

--
-- This group of constants defines the states of the EDH processor state
-- machine.
--
constant STATE_WIDTH : integer := 5;
subtype state_type is std_ulogic_vector(STATE_WIDTH - 1 downto 0);

constant S_WAIT :       state_type := "00000";
constant S_EAV1 :       state_type := "00001";
constant S_EAV2 :       state_type := "00010";
constant S_EAV3 :       state_type := "00011";
constant S_WHAT :       state_type := "00100";
constant S_SAV1 :       state_type := "00101";
constant S_SAV2 :       state_type := "00110";
constant S_SAV3 :       state_type := "00111";
constant S_SND1 :       state_type := "01000";
constant S_SND2 :       state_type := "01001";
constant S_ABRT :       state_type := "01010";
constant S_ADF1 :       state_type := "01011";
constant S_ADF2 :       state_type := "01100";
constant S_ADF3 :       state_type := "01101";
constant S_DID  :       state_type := "01110";
constant S_DBN  :       state_type := "01111";
constant S_DC   :       state_type := "10000";
constant S_UDW  :       state_type := "10001";
constant S_NC   :       state_type := "10010";




-------------------------------------------------------------------------------
-- Signal definitions
--
signal current_state:   state_type;     -- FSM current state
signal next_state:      state_type;     -- FSM next state
signal switching:       std_ulogic;     -- asserted if in switching keep-out area
signal done_switching:  std_ulogic;     -- used to generate the switching signal
signal space_avail:     std_ulogic;     -- asserted if space is available for packet
signal set_hanc:        std_ulogic;     -- sets the hanc signal
signal set_vanc:        std_ulogic;     -- clears the hanc signal (vanc = ~hanc)
signal hanc:            std_ulogic;     -- asserted during HANC space
signal ld_udw_cntr:     std_ulogic;     -- loads the UDW counter
signal udw_cntr_mux:    ubyte_type;     -- input MUX for the UDW counter
signal udw_cntr_eq_0:   std_ulogic;     -- asserted when udw_cntr_mux == 0
signal udw_cntr:        ubyte_type;     -- this is the UDW counter register
signal hanc_end:        hpos_type;      -- ending position of HANC space for current video std
signal vanc_end:        hpos_type;      -- ending position of VANC space for current video std
signal f1_edh_line:     vpos_type;      -- line in field 1 where EDH packet occurs
signal f2_edh_line:     vpos_type;      -- line in field 2 where EDH packet occurs
signal fx_edh_line:     vpos_type;      -- line in current field where EDH packet occurs
signal edh_line:        std_ulogic;     -- asserted when current line contains EDH packet
signal free_space:      hpos_type;      -- amount of free space remaining in ANC space
signal space_end:       hpos_type;      -- indicates the ending location of current ANC space
signal pkt_out:         std_ulogic;     -- asserted when ANC packet is being output
signal start_marker:    std_ulogic;     -- asserted when DID == 0x88
signal end_marker:      std_ulogic;     -- asserted when DID == 0x84
signal mod_pkt_size:    pktsize_type;   -- modified packet size value
signal pad_pkt_size:    hpos_type;      -- mod_pkt_size padded to HCNT width
signal mod_space_avail: std_ulogic;     -- when asserted, reduces the pkt_size by 3 for overwrites
signal overwrite:       std_ulogic;     -- asserted when an end marker packet is overwritten
signal abort_pkt_int :  std_ulogic;     -- internal version of abort_pkt
signal send_pkt_int :   std_ulogic;     -- internal version of send_pkt
 
begin
    
    --
    -- FSM: current_state register
    --
    -- This code implements the current state register. 
    --
    process(clk, rst)
    begin
        if (rst = '1') then
            current_state <= S_WAIT;
        elsif (clk'event and clk = '1') then
            if (ce = '1') then
                current_state <= next_state;
            end if;
        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, eav_next, sav_next, v_blank, switching, anc_next,
            pkt_rdy, vanc_pkt, hanc_pkt, space_avail, pkt_end,
            udw_cntr_eq_0, start_marker, overwrite)
    begin
        case current_state is
            when S_WAIT =>
                if (eav_next = '1') then
                    next_state <= S_EAV1;
                elsif (sav_next = '1') then
                    next_state <= S_SAV1;
                else
                    next_state <= S_WAIT;
                end if;
                    
            when S_EAV1 =>
                next_state <= S_EAV2;

            when S_EAV2 =>
                next_state <= S_EAV3;

            when S_EAV3 =>
                if (hanc_pkt = '0' or switching = '1') then
                    next_state <= S_WAIT;
                elsif (pkt_rdy = '1') then
                    next_state <= S_WHAT;
                else
                    next_state <= S_WAIT;
                end if;

            when S_WHAT =>
                if (anc_next = '1') then 
                    next_state <= S_ADF1;
                elsif (space_avail = '1') then
                    next_state <= S_SND1;
                else
                    next_state <= S_WAIT;
                end if;

            when S_SAV1 =>
                next_state <= S_SAV2;

            when S_SAV2 =>
                next_state <= S_SAV3;

            when S_SAV3 =>
                if (v_blank = '0' or vanc_pkt = '0') then 
                    next_state <= S_WAIT;
                elsif (pkt_rdy = '1') then
                    next_state <= S_WHAT;
                else
                    next_state <= S_WAIT;
                end if;

            when S_ADF1 =>  
                next_state <= S_ADF2;

            when S_ADF2 =>
                next_state <= S_ADF3;

            when S_ADF3 =>
                next_state <= S_DID;
            
            when S_DID =>
                if (start_marker = '1') then 
                    next_state <= S_NC;
                elsif (overwrite = '1') then
                    next_state <= S_SND2;
                else
                    next_state <= S_DBN;
                end if;

            when S_DBN =>
                next_state <= S_DC;

            when S_DC =>
                if (udw_cntr_eq_0 = '1' and pkt_rdy = '1') then
                    next_state <= S_WHAT;
                elsif (udw_cntr_eq_0 = '1' and pkt_rdy = '0') then
                    next_state <= S_WAIT;
                else
                    next_state <= S_UDW;
                end if;

            when S_UDW =>
                if (udw_cntr_eq_0 = '1' and pkt_rdy = '1') then
                    next_state <= S_WHAT;
                elsif (udw_cntr_eq_0 = '1' and pkt_rdy = '0') then
                    next_state <= S_WAIT;
                else
                    next_state <= S_UDW;
                end if;

            when S_SND1 =>
                if (switching = '1') then
                    next_state <= S_ABRT;
                else
                    next_state <= S_SND2;
                end if;

            when S_SND2 =>
                if (pkt_end = '1') then
                    next_state <= S_WAIT;
                else
                    next_state <= S_SND2;
                end if;

            when S_ABRT =>
                next_state <= S_WAIT;

            when S_NC =>
                if (anc_next = '1') then
                    next_state <= S_ADF1;
                elsif (eav_next = '1') then
                    next_state <= S_EAV1;
                elsif (sav_next = '1') then
                    next_state <= S_SAV1;
                else
                    next_state <= S_NC;

⌨️ 快捷键说明

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