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

📄 anc_pkt_gen.vhd

📁 XAPP299 version 1.0 reference design files
💻 VHD
📖 第 1 页 / 共 2 页
字号:
--------------------------------------------------------------------------------
-- anc_pkt_gen.vhd
--
-- SDI ANC packet generator
--
--
--
--                  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
--
-- Other modules instanced in this design:
--          none
--
--------------------------------------------------------------------------------
-- 
-- This module formats an ANC packet from raw data written into the module. Once
-- all the raw data has been written, as indicated by the pkt_rdy_in input being
-- asserted, the module will assert the pkt_rdy_out signal to the anc_insert
-- module and place the first word of the ADF on the anc_out port.
-- 
-- When the anc_insert module is ready to insert the packet, it will assert the
-- send_pkt signal. The anc_pkt_gen module responds by sequentially placing each
-- word of the ANC packet on the anc_out port for one clock cycle. It also 
-- asserts the pkt_end signal when the last word of the packet (CS) is on the 
-- anc_out port.
-- 
-- The anc_insert module sometimes needs to abort the insertion of a packet 
-- after it has asserted the send_pkt signal. This is indicated by the abort_pkt
-- input. This signal may be asserted up through the DBN/SDID word of the 
-- packet, but not later.
-- 
-- The following signals are used to write the ANC data to the module. The CS 
-- and ADF words are generated automatically and do not need to be written to 
-- the module.
-- 
-- pkt_in_empty: This output must be asserted high before any ANC data may be
-- written to the module. It remains high until pkt_rdy_in is asserted, at which
-- point it goes low and remains low until the ANC packet has been inserted into
-- the video stream.
-- 
-- data_in: This 10-bit port is the input data port for the raw ANC data. When
-- 8-bit values (DID, SDID, DBN, and DC) are written, they must be placed on the
-- least significant 8-bits of the data_in port.
-- 
-- ld_did: When this signal is asserted, the module accepts the 8-bit DID value
-- from the data_in port.
-- 
-- ld_dbn: When this signal is asserted, the module accepts the 8-bit DBN or 
-- SDID value from the data_in port.
-- 
-- ld_dc: When this signal is asserted, the module accepts the 8-bit DC value
-- from the data_in port.
-- 
-- ld_udw: When this signal is asserted, a 10-bit user data word value is
-- accepted from the data_in port. The udw_wr_adr value must indicate which word
-- of the UDW payload is currently being written whenever ld_udw is asserted.
-- 
-- udw_wr_adr: This 8-bit input port must be set to indicate which word of the 
-- UDW words is currently being written whenever ld_udw is asserted. When the 
-- first word of the payload is written, udw_wr_adr must be 0. It must be 1 for
-- the second word, and so on.
-- 
-- calc_udw_parity: If the UDW words are formatted such that they have data in
-- the LS eight bits, and even parity bit in bit 8, and the complement of bit 8
-- in bit 9, then the module can automatically calculate the parity bits (8 and 
-- 9). When the calc_udw_parity signal is asserted at the same time as ld_udw,
-- the two MS bits of data_in are ignored and the module calculates bits 8 and 9
-- of the UDW word as parity bits.
-- 
-- pkt_rdy_in: Once all the words of the ANC packet have been written to the 
-- module, the pkt_rdy_in signal must be asserted. This signal only needs to be
-- asserted for one clock cycle. The pkt_rdy_in signal must be negated before
-- the pkt_empty_in signal will be reasserted by the module.
-- 
-- It should be noted that it is not possible to simply insert another copy of a
-- packet by reasserting pkt_rdy_in. This is because the DC word of the packet
-- is destroyed in the process of transmitting the packet to the anc_insert
-- module. At the very least, the DC word must be re-written to the anc_pkt_gen
-- module before pkt_rdy_in is reasserted.
-- 
-- This module calculates the size of the current packet by adding the number of
-- overhead words to the size of the payload. The total size of the packet is
-- sent out through the pkt_size port. This information is used by the 
-- anc_insert module.
-- 
-- The UDW words of the new packet are written into a 2560-bit (256 words x 
-- 10-bits) RAM and stored until they are sent to the anc_insert module. This 
-- RAM may be implemented in the FPGA as either distributed RAM or as block RAM.
-- The module contains code that will allows XST to infer either a single-port
-- distributed RAM or a dual-port block RAM. A `define statement defines a
-- variable called UDW_BLOCK_RAM. If this variable is defined, then block RAM
-- will be inferred (if the FPGA has block RAM). If this variable is not
-- defined, distributed RAM is inferred. If the variable is defined, but the
-- FPGA does not have block RAM, a dual-port distributed RAM will be inferred.
-- This dual-port RAM will consume twice as many LUTs as the single-port RAM and
-- is therefore rather wasteful.
--

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_pkt_gen 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:     in  std_ulogic;  -- indicates packet has been loaded into registers
        calc_udw_parity:in  std_ulogic;  -- indicates that module should calculate parity on UDW
        send_pkt:       in  std_ulogic;  -- causes module to send packet
        abort_pkt:      in  std_ulogic;  -- will abort the sending of a packet

        -- input packet RAM/register write controls and data
        data_in:        in  video_type;  -- input data bus
        ld_did:         in  std_ulogic;  -- loads DID register
        ld_dbn:         in  std_ulogic;  -- loads SDID/DBN register
        ld_dc:          in  std_ulogic;  -- loads DC register
        ld_udw:         in  std_ulogic;  -- loads the UDW RAM
        udw_wr_adr:     in  udwadr_type; -- UDW RAM write address
    
        -- outputs
        anc_out:        out video_type;  -- ANC packet data output
        pkt_size:       out pktsize_type;-- total number of words in packet
        pkt_in_empty:   out std_ulogic;  -- module is ready for input packet to be loaded
        pkt_end:        out std_ulogic;  -- output indicating last word of packet is being sent
        pkt_rdy_out:    out std_ulogic); -- output indicating module is ready to send packet
end;

architecture synth of anc_pkt_gen is

--
-- Define a datatype for the UDW memory array
--
type udw_ram_type is array (UDW_MEM_SIZE - 1 downto 0) of video_type; 

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

constant S_WAIT :       state_type := "0000";
constant S_ADF1 :       state_type := "0001";
constant S_ADF2 :       state_type := "0010";
constant S_DID  :       state_type := "0011";
constant S_DBN  :       state_type := "0100";
constant S_DC   :       state_type := "0101";
constant S_UDW  :       state_type := "0110";
constant S_CHK  :       state_type := "0111";
constant S_END  :       state_type := "1000";
constant S_DONE :       state_type := "1001";
constant S_ABRT :       state_type := "1010";

--
-- This group of constants specifies the select values for the various MUXes
-- in the module.
--
constant PMUXSEL_WIDTH  : integer := 2; 
subtype  pmuxsel_type is std_ulogic_vector(PMUXSEL_WIDTH - 1 downto 0);

constant PMUXSEL_DID    : pmuxsel_type := "00";
constant PMUXSEL_DBN    : pmuxsel_type := "01";
constant PMUXSEL_DC     : pmuxsel_type := "10";
constant PMUXSEL_UDW    : pmuxsel_type := "11";

constant OMUXSEL_WIDTH  : integer := 2;
subtype  omuxsel_type is std_ulogic_vector(OMUXSEL_WIDTH - 1 downto 0);

constant OMUXSEL_ADF0   : omuxsel_type := "00";
constant OMUXSEL_ADF1   : omuxsel_type := "01";
constant OMUXSEL_DATA   : omuxsel_type := "10";
constant OMUXSEL_CHK    : omuxsel_type := "11";     

constant DMUXSEL_PGEN   : std_ulogic := '0';
constant DMUXSEL_UDW    : std_ulogic := '1';  

--
-- These constants define the Ancillary Data Flag word values
--
constant ANC_ADF0       : video_type := (others => '0');
constant ANC_ADF1       : video_type := (others => '1'); 

-------------------------------------------------------------------------------
-- Signal definitions
--
signal current_state :  state_type;     -- FSM current state
signal next_state :     state_type;     -- FSM next state
signal parity :         std_ulogic;     -- used to generate parity_err signal
signal pword :          video_type;     -- data word with parity calculated
signal checksum :       cksum_type;     -- checksum generator for ANC packet
signal clr_checksum :   std_ulogic;     -- asserted to clear the checksum
signal udw_rd_cntr :    udwadr_type;    -- UDW read counter
signal clr_udw_rd_cntr: std_ulogic;     -- clears the UDW read address
signal inc_udw_rd_cntr: std_ulogic;     -- increments the UDW read address
signal dc_eq_0 :        std_ulogic;     -- asserted when DC register equals 0
signal dec_dc :         std_ulogic;     -- causes DC register to decrement
signal pmux :           ubyte_type;     -- output of the parity gen input MUX
signal dmux :           video_type;     -- selects between parity gen out or UDW RAM out
signal omux :           video_type;     -- output data MUX
signal pmux_sel :       pmuxsel_type;   -- parity MUX select
signal dmux_sel :       std_ulogic;     -- data MUX select
signal omux_sel :       omuxsel_type;   -- output MUX select
signal did :            ubyte_type;     -- DID register
signal dbn :            ubyte_type;     -- DBN/SDID register
signal dc :             ubyte_type;     -- DC register/counter
signal udw_ram :        udw_ram_type;   -- UDW RAM
signal udw_wr_en :      std_ulogic;     -- write enable signal for UDW RAM
signal ld_out_reg :     std_ulogic;     -- loads the anc_out reg when asserted
signal pkt_in_empty_x : std_ulogic;     -- internal version of pkt_in_empty output
signal udw :            video_type;     -- UDW RAM output
 
--------------------------------------------------------------------------------
-- If using block RAM, use this signal definition.
--
-- signal udw_rd_adr :      udwadr_type;    -- RAM read address reg for block RAM

--------------------------------------------------------------------------------
-- If using distributed RAM, use this signal definition.
--
signal udw_adr :        udwadr_type;    -- MUXed address into single port RAM


--
-- XST 4.1 was trying to use one-hot encoding for pmux_sel and omux_sel. These
-- statements force XST to use the constant values as given.
--
attribute fsm_encoding : string;
attribute fsm_encoding of pmux_sel : signal is "user";
attribute fsm_encoding of omux_sel : signal is "user";

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, pkt_rdy_in, send_pkt, dc_eq_0, abort_pkt)
    begin
        case current_state is
            when S_WAIT =>
                if (pkt_rdy_in = '1') then
                    next_state <= S_ADF1;
                else
                    next_state <= S_WAIT;
                end if;

            when S_ADF1 =>
                if (send_pkt = '1') then
                    next_state <= S_ADF2;
                else
                    next_state <= S_ADF1;
                end if;

            when S_ADF2 =>
                if (abort_pkt = '1') then
                    next_state <= S_ABRT;
                else
                    next_state <= S_DID;
                end if;
            
            when S_DID =>
                if (abort_pkt = '1') then
                    next_state <= S_ABRT;
                else
                    next_state <= S_DBN;
                end if;

            when S_DBN =>
                if (abort_pkt = '1') then
                    next_state <= S_ABRT;
                else
                    next_state <= S_DC;
                end if;

            when S_DC =>
                if (dc_eq_0 = '1') then
                    next_state <= S_CHK;
                else
                    next_state <= S_UDW;
                end if;

            when S_UDW =>
                if (dc_eq_0 = '1') then
                    next_state <= S_CHK;
                else
                    next_state <= S_UDW;
                end if;

            when S_CHK =>
                next_state <= S_END;

            when S_END =>
                next_state <= S_DONE;

            when S_DONE =>
                if (pkt_rdy_in = '1') then
                    next_state <= S_DONE;
                else
                    next_state <= S_WAIT;
                end if;

            when S_ABRT =>
                next_state <= S_ADF1;

            when others =>

⌨️ 快捷键说明

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