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

📄 idct.vhd

📁 离散余弦变换及反离散余弦变换的HDL代码及测试文件。包括VHDL及Verilog版本。可用途JPEG及MEPG压缩算法。
💻 VHD
📖 第 1 页 / 共 3 页
字号:
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (en_ram1reg = '1' AND rd_cntr(5 downto 3) = "111") THEN
            rd_cntr(2 downto 0) <= rd_cntr(2 downto 0) + "001";    
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         rd_cntr(6) <= '1';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (en_ram1reg = '1' AND rd_cntr(5 downto 0) = "111111") THEN
            rd_cntr(6) <= NOT rd_cntr(6);    
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         wr_cntr <= "1111111";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (en_ram1reg = '1') THEN
            wr_cntr <= wr_cntr + "0000001";    
         ELSE
            wr_cntr <= "0000000";    
         END IF;
      END IF;
   END PROCESS;

-- write function
P_ram1: process (RST,CLK)
begin
if (RST = '1') then
ram1_mem(63 downto 0) <= (others => "00000000000");
 elsif (rising_edge (CLK)) then
	if (en_ram1reg = '1' and wr_cntr(6) = '0' ) then
	  ram1_mem(CONV_INTEGER (wr_cntr(5 downto 0))) <= z_out;
    end if;
 end if;
end process P_ram1;

P_ram2: process (RST,CLK)
begin
if (RST = '1') then
ram2_mem(63 downto 0) <= (others => "00000000000");
 elsif (rising_edge (CLK)) then
	if (en_ram1reg = '1' and wr_cntr(6) = '1') then
	  ram2_mem(CONV_INTEGER (wr_cntr(5 downto 0))) <= z_out;
    end if;
 end if;
end process P_ram2;

-- read function
P_ramout: process (RST,CLK)
begin
if (RST = '1') then
data_out <= (others => '0');
 elsif (rising_edge (CLK)) then
	if (en_ram1reg = '1' and rd_cntr(6) = '0') then
	    data_out <= ram2_mem(CONV_INTEGER (rd_cntr(5 downto 0)));
      elsif (en_ram1reg = '1' and rd_cntr(6) = '1') then
          data_out <= ram1_mem(conv_integer (rd_cntr(5 downto 0)));
      elsif (en_ram1reg = '0') then
          data_out <= (others => '0');
      end if;
   end if;
end process P_ramout;


   -- 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 
   --  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 
   
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         data_out_pipe1 <= "00000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         data_out_pipe1 <= data_out;    
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cntr80 <= "0000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            cntr80 <= cntr80 + "0000001";    
         END IF;
      END IF;
   END PROCESS;

   en_dct2d <= '0' WHEN RST = '1' ELSE '1' WHEN (cntr80 = "1001111") ELSE en_dct2d;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         en_dct2d_reg <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         en_dct2d_reg <= en_dct2d;    
      END IF;
   END PROCESS;
   data_out_final(10 downto 0) <= data_out_pipe1 ;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xb0_in <= "00000000000";    xb1_in <= "00000000000";    
         xb2_in <= "00000000000";    xb3_in <= "00000000000";    
         xb4_in <= "00000000000";    xb5_in <= "00000000000";    
         xb6_in <= "00000000000";    xb7_in <= "00000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (en_dct2d_reg = '1') THEN
            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;    
         ELSE
            IF (en_dct2d_reg = '0') THEN
               xb0_in <= "00000000000";    xb1_in <= "00000000000";    
               xb2_in <= "00000000000";    xb3_in <= "00000000000";    
               xb4_in <= "00000000000";    xb5_in <= "00000000000";    
               xb6_in <= "00000000000";    xb7_in <= "00000000000";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   -- register inputs, inputs read in every eighth clk
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xb0_reg <= "00000000000";    xb1_reg <= "00000000000";    
         xb2_reg <= "00000000000";    xb3_reg <= "00000000000";    
         xb4_reg <= "00000000000";    xb5_reg <= "00000000000";    
         xb6_reg <= "00000000000";    xb7_reg <= "00000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (cntr8 = "1000") THEN
            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 IF;
      END IF;
   END PROCESS;


   -- take absolute value of signals 
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xb0_reg_comp <= "0000000000";    xb1_reg_comp <= "0000000000";    
         xb2_reg_comp <= "0000000000";    xb3_reg_comp <= "0000000000";    
         xb4_reg_comp <= "0000000000";    xb5_reg_comp <= "0000000000";    
         xb6_reg_comp <= "0000000000";    xb7_reg_comp <= "0000000000";    
         xb0_reg_sign <= '0';    xb1_reg_sign <= '0';    
         xb2_reg_sign <= '0';    xb3_reg_sign <= '0';    
         xb4_reg_sign <= '0';    xb5_reg_sign <= '0';    
         xb6_reg_sign <= '0';    xb7_reg_sign <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
       if (xb0_reg(10) = '0') then  xb0_reg_comp <= xb0_reg(9 downto 0);
       else xb0_reg_comp <= not(xb0_reg(9 downto 0)) + '1'; end if;
       if (xb1_reg(10) = '0') then  xb1_reg_comp <= xb1_reg(9 downto 0);
       else xb1_reg_comp <= not(xb1_reg(9 downto 0)) + '1'; end if;
       if (xb2_reg(10) = '0') then  xb2_reg_comp <= xb2_reg(9 downto 0);
       else xb2_reg_comp <= not(xb2_reg(9 downto 0)) + '1'; end if;
       if (xb3_reg(10) = '0') then  xb3_reg_comp <= xb3_reg(9 downto 0);
       else xb3_reg_comp <= not(xb3_reg(9 downto 0)) + '1'; end if;
       if (xb4_reg(10) = '0') then  xb4_reg_comp <= xb4_reg(9 downto 0);
       else xb4_reg_comp <= not(xb4_reg(9 downto 0)) + '1'; end if;
       if (xb5_reg(10) = '0') then  xb5_reg_comp <= xb5_reg(9 downto 0);
       else xb5_reg_comp <= not(xb5_reg(9 downto 0)) + '1'; end if;
       if (xb6_reg(10) = '0') then  xb6_reg_comp <= xb6_reg(9 downto 0);
       else xb6_reg_comp <= not(xb6_reg(9 downto 0)) + '1'; end if;
       if (xb7_reg(10) = '0') then  xb7_reg_comp <= xb7_reg(9 downto 0);
       else xb7_reg_comp <= not(xb7_reg(9 downto 0)) + '1'; end if;

       xb0_reg_sign <= xb0_reg(10); xb1_reg_sign <= xb1_reg(10);
       xb2_reg_sign <= xb2_reg(10); xb3_reg_sign <= xb3_reg(10);
       xb4_reg_sign <= xb4_reg(10); xb5_reg_sign <= xb5_reg(10);
       xb6_reg_sign <= xb6_reg(10); xb7_reg_sign <= xb7_reg(10);

      END IF;
   END PROCESS;

   -- 10 bits * 7 bits = 16 bits 
   p1b_all <= xb7_reg_comp(9 downto 0) * memory1a(6 downto 0) ;
   p2b_all <= xb6_reg_comp(9 downto 0) * memory2a(6 downto 0) ;
   p3b_all <= xb5_reg_comp(9 downto 0) * memory3a(6 downto 0) ;
   p4b_all <= xb4_reg_comp(9 downto 0) * memory4a(6 downto 0) ;
   p5b_all <= xb3_reg_comp(9 downto 0) * memory5a(6 downto 0) ;
   p6b_all <= xb2_reg_comp(9 downto 0) * memory6a(6 downto 0) ;
   p7b_all <= xb1_reg_comp(9 downto 0) * memory7a(6 downto 0) ;
   p8b_all <= xb0_reg_comp(9 downto 0) * memory8a(6 downto 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 

xor1b <= (xb7_reg_sign) xor (memory1a(7));
xor2b <= (xb6_reg_sign) xor (memory2a(7));
xor3b <= (xb5_reg_sign) xor (memory3a(7));
xor4b <= (xb4_reg_sign) xor (memory4a(7));
xor5b <= (xb3_reg_sign) xor (memory5a(7));
xor6b <= (xb2_reg_sign) xor (memory6a(7));
xor7b <= (xb1_reg_sign) xor (memory7a(7));
xor8b <= (xb0_reg_sign) xor (memory8a(7));

   PROCESS (RST, CLK)
   BEGIN
      IF (RST = '1') THEN
         p1b <= "0000000000000000";    p2b <= "0000000000000000";    
         p3b <= "0000000000000000";    p4b <= "0000000000000000";    
         p5b <= "0000000000000000";    p6b <= "0000000000000000";    
         p7b <= "0000000000000000";    p8b <= "0000000000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1' AND prod_en1 = "1001") THEN
          if (xor1b = '1') then p1b <= not('0' & p1b_all(14 downto 0)) + '1'; 
          elsif (xor1b = '0') then p1b <= ('0' & p1b_all(14 downto 0)); end if;
          if (xor2b = '1') then p2b <= not('0' & p2b_all(14 downto 0)) + '1'; 
          elsif (xor2b = '0') then p2b <= ('0' & p2b_all(14 downto 0)); end if;
          if (xor3b = '1') then p3b <= not('0' & p3b_all(14 downto 0)) + '1'; 
          elsif (xor3b = '0') then p3b <= ('0' & p3b_all(14 downto 0)); end if;
          if (xor4b = '1') then p4b <= not('0' & p4b_all(14 downto 0)) + '1'; 
          elsif (xor4b = '0') then p4b <= ('0' & p4b_all(14 downto 0)); end if;
          if (xor5b = '1') then p5b <= not('0' & p5b_all(14 downto 0)) + '1'; 
          elsif (xor5b = '0') then p5b <= ('0' & p5b_all(14 downto 0)); end if;
          if (xor6b = '1') then p6b <= not('0' & p6b_all(14 downto 0)) + '1'; 
          elsif (xor6b = '0') then p6b <= ('0' & p6b_all(14 downto 0)); end if;
          if (xor7b = '1') then p7b <= not('0' & p7b_all(14 downto 0)) + '1'; 
          elsif (xor7b = '0') then p7b <= ('0' & p7b_all(14 downto 0)); end if;
          if (xor8b = '1') then p8b <= not('0' & p8b_all(14 downto 0)) + '1'; 
          elsif (xor8b = '0') then p8b <= ('0' & p8b_all(14 downto 0)); end if;
         ELSE
            p1b <= "0000000000000000";    
            p2b <= "0000000000000000";    
            p3b <= "0000000000000000";    
            p4b <= "0000000000000000";    
            p5b <= "0000000000000000";    
            p6b <= "0000000000000000";    
            p7b <= "0000000000000000";    
            p8b <= "0000000000000000";    
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         idct_2d_int1 <= "00000000000000000000";    
         idct_2d_int2 <= "00000000000000000000";    
         idct_2d_int3 <= "00000000000000000000";    
         idct_2d_int4 <= "00000000000000000000";    
         idct_2d_int <= "00000000000000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         idct_2d_int1 <= "0000" & (p1b + p2b);    
         idct_2d_int2 <= "0000" & (p3b + p4b);    
         idct_2d_int3 <= "0000" & (p5b + p6b);    
         idct_2d_int4 <= "0000" & (p7b + p8b);    
         idct_2d_int <= idct_2d_int1 + idct_2d_int2 + idct_2d_int3 + idct_2d_int4;    
      END IF;
   END PROCESS;
   -- max value for a input signal to dct is "11111111".
   --  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];
   idct_2d <= idct_2d_int(19) & idct_2d_int(14 downto 8) ;
   --assign idct_2d = idct_2d_int[7] ? (idct_2d_rnd + 1'b1) : idct_2d_rnd;

END logic;

⌨️ 快捷键说明

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