📄 quant.vhd
字号:
--*********************************************************************
-- *********************************************************************
-- ** -----------------------------------------------------------------------------**
-- ** 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 + -