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

📄 idct.v

📁 离散余弦变换及反离散余弦变换的HDL代码及测试文件。包括VHDL及Verilog版本。可用途JPEG及MEPG压缩算法。
💻 V
📖 第 1 页 / 共 3 页
字号:
   if (RST)
       begin
       wr_cntr <= 7'b1111111;
       end
   else begin
       if (en_ram1reg == 1'b1)
          wr_cntr <= wr_cntr + 1;
	   else 
	      wr_cntr <= 7'b0;
       end
   end

initial
begin
ram2_mem[0] <= 16'b0; ram2_mem[1] <= 16'b0; ram2_mem[2] <= 16'b0; ram2_mem[3] <= 16'b0; ram2_mem[4] <= 16'b0;
ram2_mem[5] <= 16'b0; ram2_mem[6] <= 16'b0; ram2_mem[7] <= 16'b0; ram2_mem[8] <= 16'b0; ram2_mem[9] <= 16'b0;
ram2_mem[10] <= 16'b0; ram2_mem[11] <= 16'b0; ram2_mem[12] <= 16'b0; ram2_mem[13] <= 16'b0; ram2_mem[14] <= 16'b0;
ram2_mem[15] <= 16'b0; ram2_mem[16] <= 16'b0; ram2_mem[17] <= 16'b0; ram2_mem[18] <= 16'b0; ram2_mem[19] <= 16'b0;
ram2_mem[20] <= 16'b0; ram2_mem[21] <= 16'b0; ram2_mem[22] <= 16'b0; ram2_mem[23] <= 16'b0; ram2_mem[24] <= 16'b0;
ram2_mem[25] <= 16'b0; ram2_mem[26] <= 16'b0; ram2_mem[27] <= 16'b0; ram2_mem[28] <= 16'b0; ram2_mem[29] <= 16'b0;
ram2_mem[30] <= 16'b0; ram2_mem[31] <= 16'b0; ram2_mem[32] <= 16'b0; ram2_mem[33] <= 16'b0; ram2_mem[34] <= 16'b0;
ram2_mem[35] <= 16'b0; ram2_mem[36] <= 16'b0; ram2_mem[37] <= 16'b0; ram2_mem[38] <= 16'b0; ram2_mem[39] <= 16'b0;
ram2_mem[40] <= 16'b0; ram2_mem[41] <= 16'b0; ram2_mem[42] <= 16'b0; ram2_mem[43] <= 16'b0; ram2_mem[44] <= 16'b0;
ram2_mem[45] <= 16'b0; ram2_mem[46] <= 16'b0; ram2_mem[47] <= 16'b0; ram2_mem[48] <= 16'b0; ram2_mem[49] <= 16'b0;
ram2_mem[50] <= 16'b0; ram2_mem[51] <= 16'b0; ram2_mem[52] <= 16'b0; ram2_mem[53] <= 16'b0; ram2_mem[54] <= 16'b0;
ram2_mem[55] <= 16'b0; ram2_mem[56] <= 16'b0; ram2_mem[57] <= 16'b0; ram2_mem[58] <= 16'b0; ram2_mem[59] <= 16'b0;
ram2_mem[60] <= 16'b0; ram2_mem[61] <= 16'b0; ram2_mem[62] <= 16'b0; ram2_mem[63] <= 16'b0;
 
ram1_mem[0] <= 16'b0; ram1_mem[1] <= 16'b0; ram1_mem[2] <= 16'b0; ram1_mem[3] <= 16'b0; ram1_mem[4] <= 16'b0;
ram1_mem[5] <= 16'b0; ram1_mem[6] <= 16'b0; ram1_mem[7] <= 16'b0; ram1_mem[8] <= 16'b0; ram1_mem[9] <= 16'b0;
ram1_mem[10] <= 16'b0; ram1_mem[11] <= 16'b0; ram1_mem[12] <= 16'b0; ram1_mem[13] <= 16'b0; ram1_mem[14] <= 16'b0;
ram1_mem[15] <= 16'b0; ram1_mem[16] <= 16'b0; ram1_mem[17] <= 16'b0; ram1_mem[18] <= 16'b0; ram1_mem[19] <= 16'b0;
ram1_mem[20] <= 16'b0; ram1_mem[21] <= 16'b0; ram1_mem[22] <= 16'b0; ram1_mem[23] <= 16'b0; ram1_mem[24] <= 16'b0;
ram1_mem[25] <= 16'b0; ram1_mem[26] <= 16'b0; ram1_mem[27] <= 16'b0; ram1_mem[28] <= 16'b0; ram1_mem[29] <= 16'b0;
ram1_mem[30] <= 16'b0; ram1_mem[31] <= 16'b0; ram1_mem[32] <= 16'b0; ram1_mem[33] <= 16'b0; ram1_mem[34] <= 16'b0;
ram1_mem[35] <= 16'b0; ram1_mem[36] <= 16'b0; ram1_mem[37] <= 16'b0; ram1_mem[38] <= 16'b0; ram1_mem[39] <= 16'b0;
ram1_mem[40] <= 16'b0; ram1_mem[41] <= 16'b0; ram1_mem[42] <= 16'b0; ram1_mem[43] <= 16'b0; ram1_mem[44] <= 16'b0;
ram1_mem[45] <= 16'b0; ram1_mem[46] <= 16'b0; ram1_mem[47] <= 16'b0; ram1_mem[48] <= 16'b0; ram1_mem[49] <= 16'b0;
ram1_mem[50] <= 16'b0; ram1_mem[51] <= 16'b0; ram1_mem[52] <= 16'b0; ram1_mem[53] <= 16'b0; ram1_mem[54] <= 16'b0;
ram1_mem[55] <= 16'b0; ram1_mem[56] <= 16'b0; ram1_mem[57] <= 16'b0; ram1_mem[58] <= 16'b0; ram1_mem[59] <= 16'b0;
ram1_mem[60] <= 16'b0; ram1_mem[61] <= 16'b0; ram1_mem[62] <= 16'b0; ram1_mem[63] <= 16'b0;
 
end

always @ (posedge CLK)
if (en_ram1reg == 1'b1 && wr_cntr[6] == 1'b0)
ram1_mem[wr_cntr[5:0]] <= z_out;


always @ (posedge CLK)
if (en_ram1reg == 1'b1 && wr_cntr[6] == 1'b1)
ram2_mem[wr_cntr[5:0]] <= z_out;

always @ (posedge CLK)
begin
if (en_ram1reg == 1'b1 && rd_cntr[6] == 1'b0)
  data_out <= ram2_mem[rd_cntr[5:0]];

else if (en_ram1reg == 1'b1 && rd_cntr[6] == 1'b1)
  data_out <= ram1_mem[rd_cntr[5:0]];
else data_out <= 11'b0;
end


/* END MEMORY SECTION */

/* 2D-DCT implementation same as the 1D-DCT implementation */

/* First dct coeeficient appears at the output of the RAM1 after 13clk + 1clk ram in + 64 
clk cycles + 1clk ram out. including the 1 pipestage, the 2nd DCT operation starts after 
16 +  64 clk cycles. Pipe stages are added to match the timing with the cntr8 counter */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       data_out_pipe1 <= 11'b0;
       end
   else
       begin
       data_out_pipe1 <= data_out;
       end
   end

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       cntr80 <= 7'b0;
       end
   else if (rdy_in ==1'b1)
       begin
       cntr80 <= cntr80 + 1;
      end
   end

assign en_dct2d = RST ? 1'b0 : (cntr80== 7'b1001111) ? 1'b1 : en_dct2d;

always @ (posedge CLK or posedge RST)
        begin
          if (RST)
              begin  en_dct2d_reg <= 1'b0; end
          else
              begin  en_dct2d_reg <= en_dct2d ; end
        end

assign data_out_final[10:0] = data_out_pipe1;

always @ (posedge CLK or posedge RST )
   begin
   if (RST)
       begin
       xb0_in <= 11'b0; xb1_in <= 11'b0; xb2_in <= 11'b0; xb3_in <= 11'b0;
       xb4_in <= 11'b0; xb5_in <= 11'b0; xb6_in <= 11'b0; xb7_in <= 11'b0;
       end
   else if (en_dct2d_reg == 1'b1) 
       begin
       xb0_in <= data_out_final; xb1_in <= xb0_in; xb2_in <= xb1_in; xb3_in <= xb2_in;
       xb4_in <= xb3_in; xb5_in <= xb4_in; xb6_in <= xb5_in; xb7_in <= xb6_in;
       end
   else if (en_dct2d_reg == 1'b0)
       begin
       xb0_in <= 11'b0; xb1_in <= 11'b0; xb2_in <= 11'b0; xb3_in <= 11'b0;
       xb4_in <= 11'b0; xb5_in <= 11'b0; xb6_in <= 11'b0; xb7_in <= 11'b0;
       end
   end

/* register inputs, inputs read in every eighth clk*/

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       xb0_reg <= 11'b0; xb1_reg <= 11'b0; xb2_reg <= 11'b0; xb3_reg <= 11'b0;
       xb4_reg <= 11'b0; xb5_reg <= 11'b0; xb6_reg <= 11'b0; xb7_reg <= 11'b0;
       end
   else if (cntr8 == 4'b1000)
       begin
       xb0_reg <= xb0_in; xb1_reg <= xb1_in; xb2_reg <= xb2_in; xb3_reg <= xb3_in;
       xb4_reg <= xb4_in; xb5_reg <= xb5_in; xb6_reg <= xb6_in; xb7_reg <= xb7_in;
       end
   end

/* take absolute value of signals */

always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       xb0_reg_comp <= 10'b0; xb1_reg_comp <= 10'b0; xb2_reg_comp <= 10'b0; xb3_reg_comp <= 10'b0;
       xb4_reg_comp <= 10'b0; xb5_reg_comp <= 10'b0; xb6_reg_comp <= 10'b0; xb7_reg_comp <= 10'b0;
       xb0_reg_sign <= 1'b0; xb1_reg_sign <= 1'b0; xb2_reg_sign <= 1'b0; xb3_reg_sign <= 1'b0;
       xb4_reg_sign <= 1'b0; xb5_reg_sign <= 1'b0; xb6_reg_sign <= 1'b0; xb7_reg_sign <= 1'b0;
       end
   else 
       begin 
       xb0_reg_sign <= xb0_reg[10];
       xb0_reg_comp[9:0] <= (xb0_reg[10]) ? (-xb0_reg) : xb0_reg[9:0]; 
       xb1_reg_sign <= xb1_reg[10];
       xb1_reg_comp[9:0] <= (xb1_reg[10]) ? (-xb1_reg) : xb1_reg[9:0]; 
       xb2_reg_sign <= xb2_reg[10];
       xb2_reg_comp[9:0] <= (xb2_reg[10]) ? (-xb2_reg) : xb2_reg[9:0]; 
       xb3_reg_sign <= xb3_reg[10];
       xb3_reg_comp[9:0] <= (xb3_reg[10]) ? (-xb3_reg) : xb3_reg[9:0];
       xb4_reg_sign <= xb4_reg[10];
       xb4_reg_comp[9:0] <= (xb4_reg[10]) ? (-xb4_reg) : xb4_reg[9:0]; 
       xb5_reg_sign <= xb5_reg[10];
       xb5_reg_comp[9:0] <= (xb5_reg[10]) ? (-xb5_reg) : xb5_reg[9:0]; 
       xb6_reg_sign <= xb6_reg[10];
       xb6_reg_comp[9:0] <= (xb6_reg[10]) ? (-xb6_reg) : xb6_reg[9:0]; 
       xb7_reg_sign <= xb7_reg[10];
       xb7_reg_comp[9:0] <= (xb7_reg[10]) ? (-xb7_reg) : xb7_reg[9:0];
       end
   end

/* 10 bits * 7 bits = 16 bits */
     assign p1b_all = xb7_reg_comp[9:0] * memory1a[6:0];
     assign p2b_all = xb6_reg_comp[9:0] * memory2a[6:0];
     assign p3b_all = xb5_reg_comp[9:0] * memory3a[6:0];
     assign p4b_all = xb4_reg_comp[9:0] * memory4a[6:0];
     assign p5b_all = xb3_reg_comp[9:0] * memory5a[6:0];
     assign p6b_all = xb2_reg_comp[9:0] * memory6a[6:0];
     assign p7b_all = xb1_reg_comp[9:0] * memory7a[6:0];
     assign p8b_all = xb0_reg_comp[9:0] * memory8a[6:0];

/* The following instantiation can be used while targetting Virtex2 */
//MULT18X18 mult1b (.A({10'b0,xb7_reg_comp[7:0]}), .B({11'b0,memory1a[6:0]}), .P(p1b_all));
//MULT18X18 mult2b (.A({10'b0,xb6_reg_comp[7:0]}), .B({11'b0,memory2a[6:0]}), .P(p2b_all));
//MULT18X18 mult3b (.A({10'b0,xb5_reg_comp[7:0]}), .B({11'b0,memory3a[6:0]}), .P(p3b_all));
//MULT18X18 mult4b (.A({10'b0,xb4_reg_comp[7:0]}), .B({11'b0,memory4a[6:0]}), .P(p4b_all));
//MULT18X18 mult5b (.A({10'b0,xb3_reg_comp[7:0]}), .B({11'b0,memory5a[6:0]}), .P(p5b_all));
//MULT18X18 mult6b (.A({10'b0,xb2_reg_comp[7:0]}), .B({11'b0,memory6a[6:0]}), .P(p6b_all));
//MULT18X18 mult7b (.A({10'b0,xb1_reg_comp[7:0]}), .B({11'b0,memory7a[6:0]}), .P(p7b_all));
//MULT18X18 mult8b (.A({10'b0,xb0_reg_comp[7:0]}), .B({11'b0,memory8a[6:0]}), .P(p8b_all));


/* multiply the outputs of the add/sub block with the 8 sets of stored coefficients */

always @ (posedge RST or posedge CLK)
  begin
    if (RST)
      begin
        p1b <= 19'b0; p2b <= 19'b0; p3b <= 19'b0; p4b <= 19'b0; 
        p5b <= 19'b0; p6b <= 19'b0; p7b <= 19'b0; p8b <= 19'b0;
      end
    else if (rdy_in == 1'b1 && prod_en1 == 4'b1001)
        begin
        p1b <= (xb7_reg_sign ^ memory1a[7])?(-p1b_all[15:0]):(p1b_all[15:0]);
        p2b <= (xb6_reg_sign ^ memory2a[7])?(-p2b_all[15:0]):(p2b_all[15:0]);
        p3b <= (xb5_reg_sign ^ memory3a[7])?(-p3b_all[15:0]):(p3b_all[15:0]);
        p4b <= (xb4_reg_sign ^ memory4a[7])?(-p4b_all[15:0]):(p4b_all[15:0]);
        p5b <= (xb3_reg_sign ^ memory5a[7])?(-p5b_all[15:0]):(p5b_all[15:0]);
        p6b <= (xb2_reg_sign ^ memory6a[7])?(-p6b_all[15:0]):(p6b_all[15:0]);
        p7b <= (xb1_reg_sign ^ memory7a[7])?(-p7b_all[15:0]):(p7b_all[15:0]);
        p8b <= (xb0_reg_sign ^ memory8a[7])?(-p8b_all[15:0]):(p8b_all[15:0]);
        end
    else
        begin
        p1b <= 19'b0; p2b <= 19'b0; p3b <= 19'b0; p4b <= 19'b0; 
        p5b <= 19'b0; p6b <= 19'b0; p7b <= 19'b0; p8b <= 19'b0;
        end
        
  end


always @ (posedge CLK or posedge RST)
   begin
   if (RST)
       begin
       idct_2d_int1 <= 20'b0; idct_2d_int2 <= 20'b0; idct_2d_int3 <= 20'b0;
       idct_2d_int4 <= 20'b0; idct_2d_int <= 20'b0;
       end
   else
       begin
       idct_2d_int1 <= (p1b + p2b);
       idct_2d_int2 <= (p3b + p4b);
       idct_2d_int3 <= (p5b + p6b);
       idct_2d_int4 <= (p7b + p8b);
       idct_2d_int <= (idct_2d_int1 + idct_2d_int2 + idct_2d_int3 + idct_2d_int4);
       end
   end

/* max value for a input signal to dct is "11111111".
To represent this we need only 8 bits, plus 1 bit for sign */

//assign idct_2d = idct_2d_int[16:8];
assign idct_2d = {idct_2d_int[19],idct_2d_int[14:8]};
//assign idct_2d = idct_2d_int[7] ? (idct_2d_rnd + 1'b1) : idct_2d_rnd;

endmodule

//module MULT18X18 (A, B, P); // synthesis syn_black_box
/*input[17:0]  A;
input[17:0]  B;
output[35:0] P;
endmodule*/

⌨️ 快捷键说明

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