📄 zigzag_encode.vhd
字号:
--*********************************************************************
-- *********************************************************************
-- ** -----------------------------------------------------------------------
-- **
-- ** zigzag.v
-- **
-- **
-- **
-- **
-- **
-- ** Author: Latha Pillai
-- ** Senior Applications Engineer
-- **
-- ** Video Applications
-- ** Advanced Products Group
-- ** Xilinx, Inc.
-- **
-- ** Copyright (c) 2001 Xilinx, Inc.
-- ** All rights reserved
-- **
-- ** Date: April. 10, 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.
-- ** Module: zigzag :
-- The zigzag module is used to read out the quanized dct input in a zigzag order. There are two different zigzag
--scanning modes in MPEG2. The scanning mode is chosen by the "scan_type" input. Scan_type = 0 chooses the default
--scanning mode which is also the mode used in MPEG1. MPEG2 has an alternate scanning mode which is chosen when
--scan_type = 1. The 2 scanning modes for an 8x8 block is as shown below
-- 0 1 5 6 14 15 22 28
-- 2 4 7 13 16 26 29 42
-- 3 8 12 17 25 30 41 43
-- 9 11 18 24 31 40 44 53 MPEG1 zigzag scanning mode
-- 10 19 23 32 39 45 52 54
-- 20 22 33 38 46 51 55 60
-- 21 34 37 47 50 56 59 61
-- 35 36 48 49 57 58 62 63
-- 0 4 6 20 22 36 38 52
-- 1 5 7 21 23 37 39 53
-- 2 8 19 24 34 40 50 54
-- 3 9 18 25 35 41 51 55
-- 10 17 26 30 42 46 56 60 MPEG2 zigzag scanning mode
-- 11 16 27 31 43 47 57 61
-- 12 15 28 32 44 48 58 62
-- 13 14 29 33 45 49 59 63
-- The scanning order requires that some of the later coeeficients be available in the beginning. For example,
--in alternate scanning mode, the 56th coeeficient is read in at the 13th clock. Also some of the initial coefficients
-- are read out later in the cycle. For example, in alternate scanning mode, the 7th coefficient is read out only in
-- the 52th clock cycle. Due to this nature, it is safer to have all the 64 coefficient available for 64 clock cycles.
-- This is ensured by the memread_rdy signal. This signal waits for 64 clocks before reading out from qdct_in_reg1.
--By this time, all the 64 coefficients would have been stored in this memory and they are held there for 64 clocks.
-- Since the input data qdct_in is continuous, we get a new value for the 1st coefficient at the 65th clock. Since
--the reading from qdct_in_reg1 would not be complete by the 65th clock, a second memory , qdct_in_reg2, is used to
--store the next set of 64 coefficients. After reading the 64 values from qdct_in_reg1, the next 64 values are read
--from qdct_in_reg2. This selection is done using the toggle_mem signal. This signal holds a '0' or '1' for 64 clocks
--and then switches.
-- The values are read out from the memories depending on the value of scan_mem. Scan_mem is a register used to
--hold the 2 different kinds of scanning orders. Scan_type signal chooses between the 2 scanning orders.
-- *********************************************************************
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
ENTITY zigzag_encode IS
PORT (
CLK : IN std_logic;
RST : IN std_logic; --active in high value
rdy_in : IN std_logic;
qdct_in : IN std_logic_vector(11 DOWNTO 0);
scan_type : IN std_logic; --0, reference useing MPEG1 scanning mode. 1, reference MPEG2 mode
zigzag_out : OUT std_logic_vector(11 DOWNTO 0);
rdy_out : OUT std_logic);
END zigzag_encode;
ARCHITECTURE translated OF zigzag_encode IS
TYPE ram_mem1 IS ARRAY (63 DOWNTO 0) OF std_logic_vector(11 DOWNTO 0);
TYPE ram_mem2 IS ARRAY (63 DOWNTO 0) OF std_logic_vector(11 DOWNTO 0);
SIGNAL cnt64 : std_logic_vector(6 DOWNTO 0); --count from 1 to 64,to read 64 datas into scan_mem
SIGNAL memread_rdy : std_logic; --waits for 64 clocks before reading out from qdct_in_reg1
SIGNAL toggle_mem : std_logic; --0, choose qdct_in_reg1. 1, choose qdct_in_reg2
SIGNAL scan_mem : std_logic_vector(6 DOWNTO 0);--zig-zag scanning secquency, decide datas output
--secquency
SIGNAL qdct_in_reg1 : ram_mem1; --store the 1st 64 datas and Ping-Pang operation with qdct_in_reg2
SIGNAL qdct_in_reg2 : ram_mem2; --store the 2nd 64 datas and Ping-Pang operation with qdct_in_reg1
SIGNAL rdy_out1 : std_logic;
BEGIN
--***************************************************************************
--scan_type register. This register is used to store the 2 different kinds of scan mode. Normal
--scan mode (0) is used for MPEG1 and MPEG2. Alternate scan mode (1) is used in MPEG2 for intra coded blocks
PROCESS (CLK)
BEGIN
IF (CLK'EVENT AND CLK = '1') THEN
IF (scan_type = '0') THEN
CASE cnt64 IS
WHEN "0000001" => scan_mem <= "0000000";
WHEN "0000010" => scan_mem <= "0000001";
WHEN "0000011" => scan_mem <= "0001000";
WHEN "0000100" => scan_mem <= "0010000";
WHEN "0000101" => scan_mem <= "0001001";
WHEN "0000110" => scan_mem <= "0000010";
WHEN "0000111" => scan_mem <= "0000011";
WHEN "0001000" => scan_mem <= "0001010";
WHEN "0001001" => scan_mem <= "0010001";
WHEN "0001010" => scan_mem <= "0011000";
WHEN "0001011" => scan_mem <= "0100000";
WHEN "0001100" => scan_mem <= "0011001";
WHEN "0001101" => scan_mem <= "0010010";
WHEN "0001110" => scan_mem <= "0001011";
WHEN "0001111" => scan_mem <= "0000100";
WHEN "0010000" => scan_mem <= "0000101";
WHEN "0010001" => scan_mem <= "0001100";
WHEN "0010010" => scan_mem <= "0010011";
WHEN "0010011" => scan_mem <= "0011010";
WHEN "0010100" => scan_mem <= "0100001";
WHEN "0010101" => scan_mem <= "0101000";
WHEN "0010110" => scan_mem <= "0110000";
WHEN "0010111" => scan_mem <= "0101001";
WHEN "0011000" => scan_mem <= "0100010";
WHEN "0011001" => scan_mem <= "0011011";
WHEN "0011010" => scan_mem <= "0010100";
WHEN "0011011" => scan_mem <= "0001101";
WHEN "0011100" => scan_mem <= "0000110";
WHEN "0011101" => scan_mem <= "0000111";
WHEN "0011110" => scan_mem <= "0001110";
WHEN "0011111" => scan_mem <= "0010101";
WHEN "0100000" => scan_mem <= "0011100";
WHEN "0100001" => scan_mem <= "0100011";
WHEN "0100010" => scan_mem <= "0101010";
WHEN "0100011" => scan_mem <= "0110001";
WHEN "0100100" => scan_mem <= "0111000";
WHEN "0100101" => scan_mem <= "0111001";
WHEN "0100110" => scan_mem <= "0110010";
WHEN "0100111" => scan_mem <= "0101011";
WHEN "0101000" => scan_mem <= "0100100";
WHEN "0101001" => scan_mem <= "0011101";
WHEN "0101010" => scan_mem <= "0010110";
WHEN "0101011" => scan_mem <= "0001111";
WHEN "0101100" => scan_mem <= "0010111";
WHEN "0101101" => scan_mem <= "0011110";
WHEN "0101110" => scan_mem <= "0100101";
WHEN "0101111" => scan_mem <= "0101100";
WHEN "0110000" => scan_mem <= "0110011";
WHEN "0110001" => scan_mem <= "0111010";
WHEN "0110010" => scan_mem <= "0111011";
WHEN "0110011" => scan_mem <= "0110100";
WHEN "0110100" => scan_mem <= "0101101";
WHEN "0110101" => scan_mem <= "0100110";
WHEN "0110110" => scan_mem <= "0011111";
WHEN "0110111" => scan_mem <= "0011011";
WHEN "0111000" => scan_mem <= "0101110";
WHEN "0111001" => scan_mem <= "0110101";
WHEN "0111010" => scan_mem <= "0111100";
WHEN "0111011" => scan_mem <= "0111101";
WHEN "0111100" => scan_mem <= "0110110";
WHEN "0111101" => scan_mem <= "0101111";
WHEN "0111110" => scan_mem <= "0110111";
WHEN "0111111" => scan_mem <= "0111110";
WHEN "1000000" => scan_mem <= "0111111";
WHEN OTHERS => NULL;
END CASE;
ELSE
IF (scan_type = '1') THEN
CASE cnt64 IS
WHEN "0000001" => scan_mem <= "0000000";
WHEN "0000010" => scan_mem <= "0001000";
WHEN "0000011" => scan_mem <= "0010000";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -