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

📄 idct.vhd

📁 离散余弦变换及反离散余弦变换的HDL代码及测试文件。包括VHDL及Verilog版本。可用途JPEG及MEPG压缩算法。
💻 VHD
📖 第 1 页 / 共 3 页
字号:
--*********************************************************************
-- *********************************************************************
-- ** -----------------------------------------------------------------------------**
-- ** idct.v
-- **
-- ** 8x8 Inverse Discrete Cosine Transform
-- **
-- **
-- **
-- **                  Author: Latha Pillai
-- **                  Senior Applications Engineer
-- **
-- **                  Video Applications
-- **                  Advanced Products Group
-- **                  Xilinx, Inc.
-- **
-- **                  Copyright (c) 2001 Xilinx, Inc.
-- **                  All rights reserved
-- **
-- **                  Date:   Feb. 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: idct8x8 
-- ** A 1D-IDCT is implemented on the input dct values. The output of this called
-- ** the intermediate value is stored in a RAM. The 2nd 1D-IDCT operation is done ** on this stored value to give the final 2D-IDCT output idct_2d. The inputs are ** 9 bits wide and the 2d-idct outputs are 8 bits wide.
-- ** 1st 1D section
-- ** The input signals are taken one pixel at a time in the order x00 to x07,
-- ** x10 to x07 and so on up to x77. These inputs are fed into a 8 bit shift 
-- ** register. The outputs of the 8 bit shift registers are registered at every 
-- ** 8th clock .This will enable us to register in 8 pixels (one row) at atime. 
-- ** The pixels are fed into a multiplier whose other input is connected to stored 
-- ** values in registers which act as memory. The outputs of the 8 multipliers are 
-- ** added at every CLK in the final adder. The ouput of the adder z_out is the 
-- ** 1D-IDCT values given out in the order in which the inputs were read in.
-- ** It takes 8 clks to read in the first set of inputs, 1 clk to get the absolute 
-- ** value of the input, 1 clk for multiplication, 2 clk for the final adder. 
-- ** total = 12 clks to get the 1st z_out value. Every subsequent clk gives out
-- **  the next z_out value. So to get all the 64 values we need 12+64=76 clks.
-- ** Storage / RAM section
-- ** The outputs z_out of the adder are stored in RAMs. Two RAMs are used so that 
-- ** data write can be continuous. The 1st valid input for the RAM1 is available 
-- ** at the 12th clk. So the RAM1 enable is active after 11 clks. After this the 
-- ** write operation continues for 64 clks . At the 65th clock, since z_out is 
-- ** continuous, we get the next valid z_out_00. This 2nd set of valid 1D-DCT 
-- ** coefficients are written into RAM2 which is enabled at 12+64 clks.
-- ** So at 65th clk, RAM1 goes into read mode for the next 64 clks and RAM2 is in 
-- ** write mode. After this for every 64 clks, the read and write switches between 
-- ** the 2 RAMS.
-- ** 2nd 1D-IDCT section
-- ** After the 1st 76th clk when RAM1 is full, the 2nd 1d calculations can start.
-- ** The second 1D implementation is the same as the 1st 1D implementation with 
-- ** the inputs now coming from either RAM1 or RAM2. Also, the inputs are read in 
-- ** one column at a time in the order z00 to z70, z10 to z70 up to z77. The 
-- ** outputs from the adder in the 2nd section are the 2D-IDCT coefficients.
-- **********************************************************************

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;
--library virtex; 
--use virtex.components.all; 
--library synplify; 
--use synplify.attributes.all; 
library unisims_ver; -- include this for modelsim simulation
                     -- when using mult18x18
--library UNISIM;
--use UNISIM.VComponents.all;

ENTITY idct IS
   PORT (
      CLK                     : IN std_logic;   
      RST                     : IN std_logic;   
      rdy_in                  : IN std_logic;   
      dct_2d                  : IN std_logic_vector(11 downto 0);   
      idct_2d                 : OUT std_logic_vector(7 downto 0));   
END idct;

ARCHITECTURE logic OF idct IS


   -- The max value of a pixel after processing (to make their expected mean to zero)
--  The max value of a pixel after processing (to make their expected mean to zero)
-- is 2047. If all the values in a row are 2047, the max value of the product terms
-- would be (127*2)*23170 and that of z_out_int would be (2047*8)*23170=235,407,20 which 
-- is a 25 bit binary. This value divided by 2raised to 16
-- is equivalent to ignoring the 16 lsb bits of the value 
-- 1D section 
signal xa0_in, xa1_in, xa2_in, xa3_in,
       xa4_in, xa5_in, xa6_in, xa7_in:     std_logic_vector(11 downto 0);
signal xa0_reg, xa1_reg, xa2_reg, xa3_reg, 
       xa4_reg, xa5_reg, xa6_reg, xa7_reg: std_logic_vector (11 downto 0);
signal xa0_reg_comp,xa1_reg_comp,xa2_reg_comp,
       xa3_reg_comp, xa4_reg_comp,xa5_reg_comp,
       xa6_reg_comp,xa7_reg_comp: std_logic_vector (10 downto 0);
signal xa0_reg_sign,xa1_reg_sign,xa2_reg_sign,xa3_reg_sign,
       xa4_reg_sign,xa5_reg_sign,xa6_reg_sign,xa7_reg_sign: std_logic;
signal xor1a,xor2a,xor3a,xor4a,xor5a,xor6a,xor7a,xor8a: std_logic;

signal p1a,p2a,p3a,p4a,p5a,p6a,p7a,p8a : std_logic_vector (21 downto 0);
signal p1a_all,p2a_all,p3a_all,p4a_all,
       p5a_all,p6a_all,p7a_all,p8a_all: std_logic_vector (17 downto 0);
                  -- assign as 36 bit wide signal if using mult18x18

   signal z_out_int1               :  std_logic_vector(21 downto 0);   
   signal z_out_int2               :  std_logic_vector(21 downto 0);   
   signal z_out_int3               :  std_logic_vector(21 downto 0);   
   signal z_out_int4               :  std_logic_vector(21 downto 0);   
   signal z_out_int                :  std_logic_vector(21 downto 0);   
   signal z_out_rnd                :  std_logic_vector(10 downto 0);   
   signal z_out                    :  std_logic_vector(10 downto 0);   
   signal indexi_val               :  std_logic_vector(2 downto 0);   

   -- clks and counters 
   signal cntr11                   :  std_logic_vector(3 downto 0);   
   signal cntr8                    :  std_logic_vector(3 downto 0);   
   signal prod_en1                 :  std_logic_vector(3 downto 0);   
   signal cntr80                   :  std_logic_vector(6 downto 0);   
   signal wr_cntr                  :  std_logic_vector(6 downto 0);   
   signal rd_cntr                  :  std_logic_vector(6 downto 0);   



   -- memory section 

  signal memory1a, memory2a, memory3a, memory4a,
       memory5a, memory6a, memory7a, memory8a: std_logic_vector(7 downto 0);

  
   type ram1a_mem IS ARRAY (63 downto 0) OF std_logic_vector(10 downto 0);
   signal ram1_mem                 :  ram1a_mem;     
 --  add the following to infer block RAM in synlpicity

   
   type ram2a_mem IS ARRAY (63 downto 0) OF std_logic_vector(10 downto 0);
   signal ram2_mem                 :  ram2a_mem;
     --  add the following to infer block RAM in synlpicity


   signal data_out                 :  std_logic_vector(10 downto 0);   
   signal data_out_pipe1           :  std_logic_vector(10 downto 0);   
   signal en_ram1                  :  std_logic;   
   signal en_dct2d                 :  std_logic;   
   signal en_ram1reg               :  std_logic;   
   signal en_dct2d_reg             :  std_logic;   
   -- 2D section 
   signal data_out_final           :  std_logic_vector(10 downto 0); 

signal xb0_in, xb1_in, xb2_in, xb3_in, 
       xb4_in, xb5_in, xb6_in, xb7_in: std_logic_vector(10 downto 0);
signal xb0_reg, xb1_reg, xb2_reg, xb3_reg, 
       xb4_reg, xb5_reg, xb6_reg, xb7_reg: std_logic_vector(10 downto 0);
signal xb0_reg_comp,xb1_reg_comp,xb2_reg_comp,
       xb3_reg_comp, xb4_reg_comp,xb5_reg_comp,
       xb6_reg_comp,xb7_reg_comp: std_logic_vector (9 downto 0);
signal xb0_reg_sign,xb1_reg_sign,xb2_reg_sign,xb3_reg_sign,
       xb4_reg_sign,xb5_reg_sign,xb6_reg_sign,xb7_reg_sign: std_logic;
signal xor1b,xor2b,xor3b,xor4b,xor5b,xor6b,xor7b,xor8b: std_logic;
signal p1b,p2b,p3b,p4b,p5b,p6b,p7b,p8b : std_logic_vector (15 downto 0);
signal p1b_all,p2b_all,p3b_all,p4b_all,
       p5b_all,p6b_all,p7b_all,p8b_all: std_logic_vector (16 downto 0);
     -- assign as 36 bit wide signal if using mult18x18
  
   signal idct_2d_int1             :  std_logic_vector(19 downto 0);   
   signal idct_2d_int2             :  std_logic_vector(19 downto 0);   
   signal idct_2d_int3             :  std_logic_vector(19 downto 0);   
   signal idct_2d_int4             :  std_logic_vector(19 downto 0);   
   signal idct_2d_int              :  std_logic_vector(19 downto 0);   

BEGIN

   --wire[7:0] idct_2d_rnd;
   
   --  1D-DCT BEGIN 
   -- store  1D-DCT constant coeeficient values for multipliers */
   
   PROCESS (RST, CLK)
   BEGIN
      IF (RST = '1') THEN
         memory1a <= "00000000";    memory2a <= "00000000";    
         memory3a <= "00000000";    memory4a <= "00000000";    
         memory5a <= "00000000";    memory6a <= "00000000";    
         memory7a <= "00000000";    memory8a <= "00000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         CASE indexi_val IS
            WHEN "000" =>
                     memory1a <= "01011011";    
                     memory2a <= "01111110";    
                     memory3a <= "01110110";    
                     memory4a <= "01101010";    
                     memory5a <= "01011011";    
                     memory6a <= "01000111";    
                     memory7a <= "00110001";    
                     memory8a <= "00011001";    
            WHEN "001" =>
                     memory1a <= "01011011";    
                     memory2a <= "01101010";    
                     memory3a <= "00110001";    
                     memory4a <= "10011001";    
                     memory5a <= "11011011";    
                     memory6a <= "11111110";    
                     memory7a <= "11110110";    
                     memory8a <= "11000111";    
            WHEN "010" =>
                     memory1a <= "01011011";    
                     memory2a <= "01000111";    
                     memory3a <= "10110001";    
                     memory4a <= "11111110";    
                     memory5a <= "11011011";    
                     memory6a <= "00011001";    
                     memory7a <= "01110110";    
                     memory8a <= "01101010";    
            WHEN "011" =>
                     memory1a <= "01011011";    
                     memory2a <= "00011001";    
                     memory3a <= "11110110";    
                     memory4a <= "11000111";    
                     memory5a <= "01011011";    
                     memory6a <= "01101010";    
                     memory7a <= "10110001";    
                     memory8a <= "11111110";    
            WHEN "111" =>
                     memory1a <= "01011011";    
                     memory2a <= "11111110";    
                     memory3a <= "01110110";    
                     memory4a <= "11101010";    
                     memory5a <= "01011011";    
                     memory6a <= "11000111";    
                     memory7a <= "00110001";    
                     memory8a <= "10011001";    
            WHEN "110" =>
                     memory1a <= "01011011";    
                     memory2a <= "11101010";    
                     memory3a <= "00110001";    
                     memory4a <= "00011001";    
                     memory5a <= "11011011";    
                     memory6a <= "01111110";    
                     memory7a <= "11110110";    
                     memory8a <= "01000111";    
            WHEN "101" =>
                     memory1a <= "01011011";    
                     memory2a <= "11000111";    
                     memory3a <= "10110001";    
                     memory4a <= "01111110";    
                     memory5a <= "11011011";    
                     memory6a <= "10011001";    
                     memory7a <= "01110110";    
                     memory8a <= "11101010";    
            WHEN "100" =>
                     memory1a <= "01011011";    
                     memory2a <= "10011001";    
                     memory3a <= "11110110";    
                     memory4a <= "01000111";    
                     memory5a <= "01011011";    
                     memory6a <= "11101010";    
                     memory7a <= "10110001";    
                     memory8a <= "01111110";    
            WHEN OTHERS =>
                     NULL;
            
         END CASE;
      END IF;
   END PROCESS;

   -- 8-bit input shifted 8 times thru a shift register
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xa0_in <= "000000000000";    xa1_in <= "000000000000";    
         xa2_in <= "000000000000";    xa3_in <= "000000000000";    
         xa4_in <= "000000000000";    xa5_in <= "000000000000";    
         xa6_in <= "000000000000";    xa7_in <= "000000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            xa0_in <= dct_2d;    xa1_in <= xa0_in;    
            xa2_in <= xa1_in;    xa3_in <= xa2_in;    
            xa4_in <= xa3_in;    xa5_in <= xa4_in;    
            xa6_in <= xa5_in;    xa7_in <= xa6_in;    
         ELSE
            xa0_in <= "000000000000";    xa1_in <= "000000000000";    

⌨️ 快捷键说明

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