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

📄 idct.v

📁 离散余弦变换及反离散余弦变换的HDL代码及测试文件。包括VHDL及Verilog版本。可用途JPEG及MEPG压缩算法。
💻 V
📖 第 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.
***********************************************************************/
`timescale 1ns/1ps

module idct ( CLK, RST, rdy_in, dct_2d,idct_2d);
output [7:0] idct_2d;
input CLK, RST,rdy_in;
input[11:0] dct_2d;
wire[7:0] idct_2d;

/* constants */
reg[7:0] memory1a, memory2a, memory3a, memory4a;
reg[7:0] memory5a, memory6a, memory7a, memory8a;

/* 1D section */
/* 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 */
reg[11:0] xa0_in, xa1_in, xa2_in, xa3_in, xa4_in, xa5_in, xa6_in, xa7_in;
reg[11:0] xa0_reg, xa1_reg, xa2_reg, xa3_reg, xa4_reg, xa5_reg, xa6_reg, xa7_reg;
reg[10:0] xa0_reg_comp, xa1_reg_comp, xa2_reg_comp, xa3_reg_comp, 
         xa4_reg_comp, xa5_reg_comp, xa6_reg_comp, xa7_reg_comp;
reg xa0_reg_sign, xa1_reg_sign, xa2_reg_sign, xa3_reg_sign, 
           xa4_reg_sign, xa5_reg_sign, xa6_reg_sign, xa7_reg_sign;
reg[21:0] p1a,p2a,p3a,p4a,p5a,p6a,p7a,p8a;
wire[35:0] p1a_all,p2a_all,p3a_all,p4a_all,p5a_all,p6a_all,p7a_all,p8a_all;
reg[21:0] z_out_int1, z_out_int2, z_out_int3;
reg[21:0] z_out_int4; 
reg[21:0] z_out_int;
wire[10:0] z_out_rnd;
wire[10:0] z_out;
reg[2:0] indexi_val;

/* clks and counters */
reg[3:0] cntr11 ;
reg[3:0] cntr8, prod_en1;
reg[6:0] cntr80;
reg[6:0] wr_cntr,rd_cntr;
reg[10:0] ram1_mem[63:0],ram2_mem[63:0]; // add the following to infer block RAM in synlpicity
                                         //    synthesis syn_ramstyle = "block_ram"   

/* memory section */
reg[10:0] data_out;
reg[10:0] data_out_pipe1;
wire en_ram1,en_dct2d;
reg en_ram1reg,en_dct2d_reg;

/* 2D section */
wire[10:0] data_out_final;
reg[10:0] xb0_in, xb1_in, xb2_in, xb3_in, xb4_in, xb5_in, xb6_in, xb7_in;
reg[10:0] xb0_reg, xb1_reg, xb2_reg, xb3_reg, xb4_reg, xb5_reg, xb6_reg, xb7_reg;
reg[9:0] xb0_reg_comp, xb1_reg_comp, xb2_reg_comp, xb3_reg_comp, 
         xb4_reg_comp, xb5_reg_comp, xb6_reg_comp, xb7_reg_comp;
reg xb0_reg_sign, xb1_reg_sign, xb2_reg_sign, xb3_reg_sign, 
    xb4_reg_sign, xb5_reg_sign, xb6_reg_sign, xb7_reg_sign;

reg[15:0] p1b,p2b,p3b,p4b,p5b,p6b,p7b,p8b;
wire[35:0] p1b_all,p2b_all,p3b_all,p4b_all,p5b_all,p6b_all,p7b_all,p8b_all;
reg[19:0] idct_2d_int1,idct_2d_int2,idct_2d_int3,idct_2d_int4;
reg[19:0] idct_2d_int;
//wire[7:0] idct_2d_rnd;

/*  1D-DCT BEGIN */

// store  1D-DCT constant coeeficient values for multipliers */

always @ (posedge RST or posedge CLK)
   begin
   if (RST)
       begin
       memory1a <= 8'd0; memory2a <= 8'd0; memory3a <= 8'd0; memory4a <= 8'd0;
       memory5a <= 8'd0; memory6a <= 8'd0; memory7a <= 8'd0; memory8a <= 8'd0;
       end
   else
       begin
	     case (indexi_val)
       3'b000 : begin memory1a <= 8'd91; memory2a <= 8'd126; 
                      memory3a <= 8'd118; memory4a <= 8'd106;
                      memory5a <= 8'd91; memory6a <= 8'd71; 
                      memory7a <= 8'd49; memory8a <= 8'd25;end
         
       3'b001 : begin memory1a <= 8'd91; memory2a <= 8'd106;  
                      memory3a <= 8'd49;  
                      memory4a[7] <= 1'd1; memory4a[6:0] <= 7'd25;
                      memory5a[7] <= 1'd1;memory5a[6:0] <= 7'd91; 
                      memory6a[7] <= 1'd1;memory6a[6:0] <= 7'd126;
                      memory7a[7] <= 1'd1;memory7a[6:0] <= 7'd118; 
                      memory8a[7] <= 1'd1;memory8a[6:0] <= 7'd71;end
         
       3'b010 : begin memory1a <= 8'd91; memory2a <= 8'd71;  
                      memory3a[7] <= 1'd1;memory3a[6:0] <= 7'd49; 
                      memory4a[7] <= 1'd1;memory4a[6:0] <= 7'd126;
                      memory5a[7] <= 1'd1;memory5a[6:0] <= 7'd91; 
                      memory6a <= 8'd25; 
                      memory7a <= 8'd118; memory8a <= 8'd106;end

       3'b011 : begin memory1a <= 8'd91; memory2a <= 8'd25;  
                      memory3a[7] <= 1'd1;memory3a[6:0] <= 7'd118; 
                      memory4a[7] <= 1'd1;memory4a[6:0] <= 7'd71;
                      memory5a <= 8'd91; 
                      memory6a <= 8'd106; 
                      memory7a[7] <= 1'd1;memory7a[6:0] <= 7'd49; 
                      memory8a[7] <= 1'd1;memory8a[6:0] <= 7'd126;end
         
       3'b111 : begin memory1a <= 8'd91; 
                      memory2a[7] <= 1'd1;memory2a[6:0] <= 7'd126; 
                      memory3a <= 8'd118; 
                      memory4a[7] <= 1'd1;memory4a[6:0] <= 7'd106;
                      memory5a <= 8'd91; 
                      memory6a[7] <= 1'd1;memory6a[6:0] <= 7'd71; 
                      memory7a <= 8'd49; 
                      memory8a[7] <= 1'd1;memory8a[6:0] <= 7'd25;end
         
       3'b110 : begin memory1a <= 8'd91; 
                      memory2a[7] <= 1'd1;memory2a[6:0] <= 7'd106;  
                      memory3a <= 8'd49;  
                      memory4a <= 8'd25;
                      memory5a[7] <= 1'd1;memory5a[6:0] <= 7'd91; 
                      memory6a <= 8'd126; 
                      memory7a[7] <= 1'd1;memory7a[6:0] <= 7'd118; 
                      memory8a <= 8'd71;end
         
       3'b101 : begin memory1a <= 8'd91; 
                      memory2a[7] <= 1'd1;memory2a[6:0] <= 7'd71;  
                      memory3a[7] <= 1'd1;memory3a[6:0] <= 7'd49; 
                      memory4a <= 8'd126;
                      memory5a[7] <= 1'd1;memory5a[6:0] <= 7'd91; 
                      memory6a[7] <= 1'd1;memory6a[6:0] <= 7'd25; 
                      memory7a <= 8'd118; 
                      memory8a[7] <= 1'd1;memory8a[6:0] <= 7'd106;end

       3'b100 : begin memory1a <= 8'd91; 
                      memory2a[7] <= 1'd1;memory2a[6:0] <= 7'd25;  
                      memory3a[7] <= 1'd1;memory3a[6:0] <= 7'd118; 
                      memory4a <= 8'd71;
                      memory5a <= 8'd91; 
                      memory6a[7] <= 1'd1;memory6a[6:0] <= 7'd106; 
                      memory7a[7] <= 1'd1;memory7a[6:0] <= 7'd49; 
                      memory8a <= 8'd126;end
      
       endcase
      end
end


/* 8-bit input shifted 8 times thru a shift register*/
always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       xa0_in <= 12'b0; xa1_in <= 12'b0; xa2_in <= 12'b0; xa3_in <= 12'b0;
       xa4_in <= 12'b0; xa5_in <= 12'b0; xa6_in <= 12'b0; xa7_in <= 12'b0;
       end
   else if (rdy_in == 1'b1)
       begin
       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;
       end
   else 
       begin
       xa0_in <= 12'b0; xa1_in <= 12'b0; xa2_in <= 12'b0; xa3_in <= 12'b0;
       xa4_in <= 12'b0; xa5_in <= 12'b0; xa6_in <= 12'b0; xa7_in <= 12'b0;
       end
   end

/* shifted inputs registered every 8th clk (using cntr8)*/

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       cntr8 <= 4'b0;
       end
   else if(rdy_in == 1'b1)
       begin
       if (cntr8 < 4'b1000)
           begin
           cntr8 <= cntr8 + 1;
           end
       else 
           begin
           cntr8 <= 4'b001;
           end
       end
   else  cntr8 <= 4'b0;

   end

always @ (posedge CLK or posedge RST)
   begin

⌨️ 快捷键说明

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