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

📄 quant.vhd

📁 用于FPGA的量化算法的HDL编码
💻 VHD
📖 第 1 页 / 共 4 页
字号:

--*********************************************************************
-- *********************************************************************
-- ** -----------------------------------------------------------------------------**
-- ** quant.v
-- **
-- ** Quantization
-- **
-- **
-- **
-- **                  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: quant : 
-- ** The 2D_DCT output is taken through the quantizer where each of the DCT 
-- ** coefficient is quantized by dividing by the corresponding element in the 
-- ** quantizer matrix. Quantization is done to zero out those DCT coefficients 
-- ** that correspond to the higher frequency components.
--  The default Q-matrices are as follows:
--        Intra quantizer matrix          Non-intra quantizer matrix
-- The Q_matrix is stored in a RAM. The "rdy_in" input signal goes active when the first DCT output is 
-- available. The quantization starts when rdy_in goes high and as long as it is high. An internal 
-- 64-count clock is used to loop through the 64 elements in the Q_matrix. The two default Q matrices 
-- (one for luma and one for chroma) are stored in memory. Additional two memories are provided to store 
-- user specified Q matrices in case that is used. 
-- The quant_scale_code is 5 bits wide and is used to select the quantiser scale. quant_scale_code value 
-- can range from 1 to 31. The inverse of the quant_scale_code is calculated and stored in q_scale_mem. 
-- The value is assigned 16 bits to minimize round off error. The 1 bit q_scale type is used to choose 
-- between two sets of q_scale_mems. q_scale_type is used to choose between the 2 quantizer_scale values. 
-- q_scale_type = 0 is used for MPEG1 and q_scale_type = 1 is used for MPEG2. Quantiser scale value for 
-- each quantiser scale code is found in the MPEG ISO/IEC document. 
-- The Q matrix has 64, 8-bit values. The inverse of the 256 possible Q matrix entries are stored in 
-- q_value_mem. The default q_values (in zig-zag order) are stored in a FIFO (q_value_fifo). Upon receving 
-- a new user defined Q matrix, the new 64 values are read in , one value per clock. These values are then 
-- used to access the q_value_mem, which in turn outputs new values into the q_value_fifo. The fifo retains 
-- one set of values as long as the load_new_q_value is inactive. This signal, load_new_q_value is active 
-- for 64 clocks after it sees a high on load_intra_qmatrix or load_non_intra_qmatrix. The macroblock-type 
-- input signal is used to choose either the intro or non-intra Q_matrix depending on the type of frame.
-- Quantization in MPEG2 is given by the following equation
-- *********************************************************************

--scale factor --- how many bits ?

library IEEE; 
use IEEE.numeric_std.all;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.std_logic_unsigned.all;


ENTITY quant IS
   PORT (
      CLK                     : IN bit;   
      RST                     : IN bit;   
      dct_in                  : IN std_logic_vector(11 DOWNTO 0);   --  11 bit output from DCT block 
      rdy_in                  : IN std_logic;    --  ready signal , starts quantization process                      
                                                 --  after DCT is done for the block 
      macroblock_type         : IN std_logic; -- don't how to use, set it to 0, the program can work well
      quant_scale_type        : IN std_logic; -- used to choose intra or non-intra quantizer matrix, 0 choose intra
                                              -- matrix, 1 choose non-intra matrix
      quant_scale_code        : IN std_logic_vector(4 DOWNTO 0); -- q_scale_code and q_scale_type are used together to
                                                        -- choose the quantiser_scale value as given in MPEG2 standard
      q_value                 : IN std_logic_vector(7 DOWNTO 0);   --  user defined Q matrix value 
      load_intra_qmatrix      : IN std_logic;   
      load_non_intra_qmatrix  : IN std_logic;   
      quant_rdy_out           : OUT std_logic;   
      quant_dct_out           : OUT std_logic_vector(11 DOWNTO 0));   --  quantised output value 
END quant;

ARCHITECTURE translated OF quant IS

   TYPE ram_mem1 IS ARRAY (64 DOWNTO 1) OF std_logic_vector(7 DOWNTO 0);
   TYPE ram_mem2 IS ARRAY (64 DOWNTO 1) OF std_logic_vector(7 DOWNTO 0);

   -- signals 
   SIGNAL macroblock_type_reg1     :  std_logic;   
   SIGNAL quant_scale_type_reg1    :  std_logic;   
   SIGNAL quant_scale_type_reg2    :  std_logic;   
   SIGNAL load_intra_qmatrix_reg1  :  std_logic;   
   SIGNAL load_non_intra_qmatrix_reg1     :  std_logic;   
   SIGNAL load_intra_qmatrix_reg2  :  std_logic;   
   SIGNAL load_non_intra_qmatrix_reg2     :  std_logic;   
   SIGNAL load_intra_qmatrix_reg3  :  std_logic;   
   SIGNAL load_non_intra_qmatrix_reg3     :  std_logic;   
   SIGNAL load_intra_qmatrix_reg4  :  std_logic;   
   SIGNAL load_non_intra_qmatrix_reg4     :  std_logic;   
   SIGNAL quant_scale_code_reg1    :  std_logic_vector(4 DOWNTO 0);   
   SIGNAL quant_scale_code_reg2    :  std_logic_vector(4 DOWNTO 0);   
   SIGNAL qscale_mem_sel           :  std_logic_vector(6 DOWNTO 0);   
   SIGNAL cnt64                    :  std_logic_vector(6 DOWNTO 0);   
   SIGNAL cnt64b                   :  std_logic_vector(6 DOWNTO 0);   
   SIGNAL cnt64c                   :  std_logic_vector(6 DOWNTO 0);   
   SIGNAL def_qmem_sel             :  std_logic_vector(8 DOWNTO 0);   
   SIGNAL cnt6                     :  std_logic_vector(3 DOWNTO 0);   
   SIGNAL memoryQ                  :  std_logic_vector(10 DOWNTO 0);   
   --reg[10:0] dct_out,dct_in_reg1,dct_in_reg2,dct_in_reg_mag;
   --reg[11:0] dct_in_reg[63:0];
   --reg[11:0] dct_in1;
   SIGNAL dct_in_pipe1             :  std_logic_vector(11 DOWNTO 0);   
   SIGNAL dct_in_pipe2             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe3             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe4             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe5             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe6             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe7             :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL dct_in_pipe2_sign        :  std_logic;   
   SIGNAL dct_in_pipe3_sign        :  std_logic;   
   SIGNAL dct_in_pipe4_sign        :  std_logic;   
   SIGNAL dct_in_pipe5_sign        :  std_logic;   
   SIGNAL dct_in_pipe6_sign        :  std_logic;   
   SIGNAL dct_in_pipe7_sign        :  std_logic;   
   SIGNAL dct_in_pipe8_sign        :  std_logic;   
   SIGNAL dct_in_pipe9_sign        :  std_logic;   
   SIGNAL macroblock_type_pipe1    :  std_logic;   
   SIGNAL macroblock_type_pipe2    :  std_logic;   
   SIGNAL macroblock_type_pipe3    :  std_logic;   
   SIGNAL macroblock_type_pipe4    :  std_logic;   
   SIGNAL macroblock_type_pipe5    :  std_logic;   
   SIGNAL macroblock_type_pipe6    :  std_logic;   
   SIGNAL macroblock_type_pipe7    :  std_logic;   
   SIGNAL macroblock_type_pipe8    :  std_logic;   
   SIGNAL q_scale_mem              :  std_logic_vector(12 DOWNTO 0);   
   SIGNAL qscale_reg1              :  std_logic_vector(12 DOWNTO 0);   
   SIGNAL qscale_reg2              :  std_logic_vector(12 DOWNTO 0);   
   SIGNAL def_q_mem                :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL def_q_mem_reg1           :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL def_q_mem_reg2           :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL def_q_mem_reg3           :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL q_value_new_out          :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL q_value_new_out_reg1     :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL q_value_new_intra        :  ram_mem1;   
   SIGNAL q_value_new_non_intra    :  ram_mem2;   
   SIGNAL prod1                    :  std_logic_vector(23 DOWNTO 0);   
   SIGNAL prod1_reg                :  std_logic_vector(23 DOWNTO 0);   
   SIGNAL prod2                    :  std_logic_vector(27 DOWNTO 0);   
   SIGNAL prod2_round              :  std_logic_vector(16 DOWNTO 0);   
   SIGNAL prod2_k                  :  std_logic_vector(18 DOWNTO 0);   
   SIGNAL q_value_select           :  std_logic_vector(8 DOWNTO 0);   
   SIGNAL cnt_start                :  std_logic;   
   SIGNAL temp4               :  std_logic_vector(10 DOWNTO 0);   
   SIGNAL temp5               :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL temp6               :  std_logic_vector(27 DOWNTO 9);   
   SIGNAL temp7               :  std_logic_vector(18 DOWNTO 2);   
   SIGNAL temp8               :  std_logic_vector(11 DOWNTO 0);   
  

BEGIN

   --***************************************************************************
   -- COUNTER CODE 
   --***************************************************************************
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cnt64 <= "1000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (cnt64 < "1000000") THEN
               cnt64 <= cnt64 + "0000001";    
            ELSE
               cnt64 <= "0000001";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cnt64b <= "0111111";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (cnt64b < "1000000") THEN
               cnt64b <= cnt64b + "0000001";    
            ELSE
               cnt64b <= "0000001";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cnt64c <= "0111111";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (cnt64c < "1000000") THEN
               cnt64c <= cnt64c + "0000001";    
            ELSE
               cnt64c <= "0000001";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cnt6 <= "0000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (cnt6 < "1000") THEN
               cnt6 <= cnt6 + "0001";    
            ELSE
               cnt6 <= "1000";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cnt_start <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1' AND cnt64 = "1000000") THEN
            cnt_start <= '1';    
         ELSE
            cnt_start <= cnt_start;    
         END IF;
      END IF;
   END PROCESS;

   --***************************************************************************
   --PIPELINING INPUT SIGNALS 
   --***************************************************************************
   --  register inputs for 64 clks. This is done to make sure that all the 64 
   --    DCT coefficients see the same qscaletype, qscale_code,macroblock type,
   --    load intra matrix, load non intra matrix: pipe stages = 1 
   
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         macroblock_type_reg1 <= '0';    
         quant_scale_code_reg1 <= "00000";    
         quant_scale_type_reg1 <= '0';    
         load_intra_qmatrix_reg1 <= '0';    
         load_non_intra_qmatrix_reg1 <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1' AND cnt64 = "1000000") THEN
            
            -- fork <<X-HDL>>
               macroblock_type_reg1 <= macroblock_type;    

⌨️ 快捷键说明

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