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

📄 idct.vhd

📁 离散余弦变换及反离散余弦变换的HDL代码及测试文件。包括VHDL及Verilog版本。可用途JPEG及MEPG压缩算法。
💻 VHD
📖 第 1 页 / 共 3 页
字号:
            xa2_in <= "000000000000";    xa3_in <= "000000000000";    
            xa4_in <= "000000000000";    xa5_in <= "000000000000";    
            xa6_in <= "000000000000";    xa7_in <= "000000000000";    
         END IF;
      END IF;
   END PROCESS;

   -- shifted inputs registered every 8th clk (using cntr8)
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cntr8 <= "0000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (cntr8 < "1000") THEN
               cntr8 <= cntr8 + "0001";    
            ELSE
               cntr8 <= "0001";    
            END IF;
         ELSE
            cntr8 <= "0000";    
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         prod_en1 <= "0000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            IF (prod_en1 < "1001") THEN
               prod_en1 <= prod_en1 + "0001";    
            ELSE
               prod_en1 <= "1001";    
            END IF;
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xa0_reg <= "000000000000";  xa1_reg <= "000000000000";    
         xa2_reg <= "000000000000";  xa3_reg <= "000000000000";    
         xa4_reg <= "000000000000";  xa5_reg <= "000000000000";    
         xa6_reg <= "000000000000";  xa7_reg <= "000000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (cntr8 = "1000") THEN
            xa0_reg <= xa0_in;  xa1_reg <= xa1_in;    
            xa2_reg <= xa2_in;  xa3_reg <= xa3_in;    
            xa4_reg <= xa4_in;  xa5_reg <= xa5_in;    
            xa6_reg <= xa6_in;  xa7_reg <= xa7_in;    
         ELSE
            
         END IF;
      END IF;
   END PROCESS;

   -- take absolute value of signals 
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         xa0_reg_comp <= "00000000000";    xa1_reg_comp <= "00000000000";    
         xa2_reg_comp <= "00000000000";    xa3_reg_comp <= "00000000000";    
         xa4_reg_comp <= "00000000000";    xa5_reg_comp <= "00000000000";    
         xa6_reg_comp <= "00000000000";    xa7_reg_comp <= "00000000000";    
         xa0_reg_sign <= '0';   xa1_reg_sign <= '0';    
         xa2_reg_sign <= '0';   xa3_reg_sign <= '0';    
         xa4_reg_sign <= '0';   xa5_reg_sign <= '0';    
         xa6_reg_sign <= '0';   xa7_reg_sign <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
       if (xa0_reg(11) = '0') then  xa0_reg_comp <= xa0_reg(10 downto 0);
       else xa0_reg_comp <= not(xa0_reg(10 downto 0)) + '1'; end if;
       if (xa1_reg(11) = '0') then  xa1_reg_comp <= xa1_reg(10 downto 0);
       else xa1_reg_comp <= not(xa1_reg(10 downto 0)) + '1'; end if;
       if (xa2_reg(11) = '0') then  xa2_reg_comp <= xa2_reg(10 downto 0);
       else xa2_reg_comp <= not(xa2_reg(10 downto 0)) + '1'; end if;
       if (xa3_reg(11) = '0') then  xa3_reg_comp <= xa3_reg(10 downto 0);
       else xa3_reg_comp <= not(xa3_reg(10 downto 0)) + '1'; end if;
       if (xa4_reg(11) = '0') then  xa4_reg_comp <= xa4_reg(10 downto 0);
       else xa4_reg_comp <= not(xa4_reg(10 downto 0)) + '1'; end if;
       if (xa5_reg(11) = '0') then  xa5_reg_comp <= xa5_reg(10 downto 0);
       else xa5_reg_comp <= not(xa5_reg(10 downto 0)) + '1'; end if;
       if (xa6_reg(11) = '0') then  xa6_reg_comp <= xa6_reg(10 downto 0);
       else xa6_reg_comp <= not(xa6_reg(10 downto 0)) + '1'; end if;
       if (xa7_reg(11) = '0') then  xa7_reg_comp <= xa7_reg(10 downto 0); 
       else xa7_reg_comp <= not(xa7_reg(10 downto 0)) + '1'; end if;

       xa0_reg_sign <= xa0_reg(11); xa1_reg_sign <= xa1_reg(11);
       xa2_reg_sign <= xa2_reg(11); xa3_reg_sign <= xa3_reg(11);
       xa4_reg_sign <= xa4_reg(11); xa5_reg_sign <= xa5_reg(11);
       xa6_reg_sign <= xa6_reg(11); xa7_reg_sign <= xa7_reg(11);

      END IF;
   END PROCESS;

   -- multiply the outputs of the add/sub block with the 8 sets of stored coefficients 
   -- The inputs are shifted thru 8 registers in 8 clk cycles. The ouput of the shift
   --  The inputs are shifted thru 8 registers in 8 clk cycles. The ouput of the shift
   -- registers are registered at the 9th clk. The values are then added or subtracted at the 10th
   -- clk. The first mutiplier output is obtained at the 11th clk. Memoryx[0] shd be accessed
   -- at the 11th clk
   
   --wait state counter 
   -- First valid add_sub appears at the 10th clk (8 clks for shifting inputs,
   
   -- 9th clk for registering shifted input and 10th clk for add_sub
   
   -- to synchronize the i value to the add_sub value, i value is incremented
   
-- only after 10 clks using i_wait

   
   -- max value for p1a = 2047*126. = 18 bits 
   p1a_all <= xa7_reg_comp(10 downto 0) * memory1a(6 downto 0) ;
   p2a_all <= xa6_reg_comp(10 downto 0) * memory2a(6 downto 0) ;
   p3a_all <= xa5_reg_comp(10 downto 0) * memory3a(6 downto 0) ;
   p4a_all <= xa4_reg_comp(10 downto 0) * memory4a(6 downto 0) ;
   p5a_all <= xa3_reg_comp(10 downto 0) * memory5a(6 downto 0) ;
   p6a_all <= xa2_reg_comp(10 downto 0) * memory6a(6 downto 0) ;
   p7a_all <= xa1_reg_comp(10 downto 0) * memory7a(6 downto 0) ;
   p8a_all <= xa0_reg_comp(10 downto 0) * memory8a(6 downto 0) ;


   -- The following instantiation can be used while targetting Virtex2 
   --MULT18X18 mult1a (.A({10'b0,xa7_reg_comp[7:0]}), .B({11'b0,memory1a[6:0]}), .P(p1a_all));
   
   --MULT18X18 mult2a (.A({10'b0,xa6_reg_comp[7:0]}), .B({11'b0,memory2a[6:0]}), .P(p2a_all));
   
   --MULT18X18 mult3a (.A({10'b0,xa5_reg_comp[7:0]}), .B({11'b0,memory3a[6:0]}), .P(p3a_all));
   
   --MULT18X18 mult4a (.A({10'b0,xa4_reg_comp[7:0]}), .B({11'b0,memory4a[6:0]}), .P(p4a_all));
   
   --MULT18X18 mult5a (.A({10'b0,xa3_reg_comp[7:0]}), .B({11'b0,memory5a[6:0]}), .P(p5a_all));
   
   --MULT18X18 mult6a (.A({10'b0,xa2_reg_comp[7:0]}), .B({11'b0,memory6a[6:0]}), .P(p6a_all));
   
   --MULT18X18 mult7a (.A({10'b0,xa1_reg_comp[7:0]}), .B({11'b0,memory7a[6:0]}), .P(p7a_all));
   
   --MULT18X18 mult8a (.A({10'b0,xa0_reg_comp[7:0]}), .B({11'b0,memory8a[6:0]}), .P(p8a_all));

xor1a <= (xa7_reg_sign) xor (memory1a(7));
xor2a <= (xa6_reg_sign) xor (memory2a(7));
xor3a <= (xa5_reg_sign) xor (memory3a(7));
xor4a <= (xa4_reg_sign) xor (memory4a(7));
xor5a <= (xa3_reg_sign) xor (memory5a(7));
xor6a <= (xa2_reg_sign) xor (memory6a(7));
xor7a <= (xa1_reg_sign) xor (memory7a(7));
xor8a <= (xa0_reg_sign) xor (memory8a(7));
   
   PROCESS (RST, CLK)
   BEGIN
      IF (RST = '1') THEN
         p1a <= "0000000000000000000000";    
         p2a <= "0000000000000000000000";    
         p3a <= "0000000000000000000000";    
         p4a <= "0000000000000000000000";    
         p5a <= "0000000000000000000000";    
         p6a <= "0000000000000000000000";    
         p7a <= "0000000000000000000000";    
         p8a <= "0000000000000000000000";    
         indexi_val <= "000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1' AND prod_en1 = "1001") THEN
          if (xor1a = '1') then p1a <= not("000000" & p1a_all(15 downto 0)) + '1'; 
          elsif (xor1a = '0') then p1a <= ("000000" & p1a_all(15 downto 0)); end if;
          if (xor2a = '1') then p2a <= not("000000" & p2a_all(15 downto 0)) + '1'; 
          elsif (xor2a = '0') then p2a <= ("000000" & p2a_all(15 downto 0)); end if;
          if (xor3a = '1') then p3a <= not("000000" & p3a_all(15 downto 0)) + '1'; 
          elsif (xor3a = '0') then p3a <= ("000000" & p3a_all(15 downto 0)); end if;
          if (xor4a = '1') then p4a <= not("000000" & p4a_all(15 downto 0)) + '1'; 
          elsif (xor4a = '0') then p4a <= ("000000" & p4a_all(15 downto 0)); end if;
          if (xor5a = '1') then p5a <= not("000000" & p5a_all(15 downto 0)) + '1'; 
          elsif (xor5a = '0') then p5a <= ("000000" & p5a_all(15 downto 0)); end if;
          if (xor6a = '1') then p6a <= not("000000" & p6a_all(15 downto 0)) + '1'; 
          elsif (xor6a = '0') then p6a <= ("000000" & p6a_all(15 downto 0)); end if;
          if (xor7a = '1') then p7a <= not("000000" & p7a_all(15 downto 0)) + '1'; 
          elsif (xor7a = '0') then p7a <= ("000000" & p7a_all(15 downto 0)); end if;
          if (xor8a = '1') then p8a <= not("000000" & p8a_all(15 downto 0)) + '1'; 
          elsif (xor8a = '0') then p8a <= ("000000" & p8a_all(15 downto 0)); end if;
            IF (indexi_val = "111") THEN
               indexi_val <= "000";    
            ELSE
               indexi_val <= indexi_val + "001";    
            END IF;
         ELSE
            p1a <= "0000000000000000000000";    
            p2a <= "0000000000000000000000";    
            p3a <= "0000000000000000000000";    
            p4a <= "0000000000000000000000";    
            p5a <= "0000000000000000000000";    
            p6a <= "0000000000000000000000";    
            p7a <= "0000000000000000000000";    
            p8a <= "0000000000000000000000";    
         END IF;
      END IF;
   END PROCESS;

   -- Final adder. Adding the ouputs of the 4 multipliers 
   -- max value for z_out_int = 2047*126*8 = 2063376 = 21 bits 
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         z_out_int1 <= "0000000000000000000000";    
         z_out_int2 <= "0000000000000000000000";    
         z_out_int3 <= "0000000000000000000000";    
         z_out_int4 <= "0000000000000000000000";    
         z_out_int <= "0000000000000000000000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         z_out_int1 <= p1a + p2a;    
         z_out_int2 <= p3a + p4a;    
         z_out_int3 <= p5a + p6a;    
         z_out_int4 <= p7a + p8a;    
         z_out_int <= z_out_int1 + z_out_int2 + z_out_int3 + z_out_int4;    
      END IF;
   END PROCESS;
   -- rounding of the value
   
   -- max value for a 1D-DCT output is "11111111"*126*8/256=1004.
   --  max value for a 1D-DCT output is "11111111"*126*8/256=1004.
   -- To represent this we need only 10 bits, plus 1 bit for sign 
   z_out_rnd <= z_out_int(18 downto 8) ;
   z_out <= (z_out_rnd + "00000000001") WHEN z_out_int(7) = '1' ELSE z_out_rnd;
 

   -- 1D-DCT END 
   -- tranpose memory to store intermediate Z coefficients 
   -- store the 64 coefficients in the first 64 locations of the RAM 
   -- first valid final (product) adder ouput is at the 13th clk. 8clk SR
   --  first valid final (product) adder ouput is at the 13th clk. 8clk SR
   -- + 1 clk reg + 1 clk comp + 1 clk prod. + 2 clks summing.
   -- So the RAM is enabled at the 11th clk) 
   
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         cntr11 <= "0000";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (rdy_in = '1') THEN
            cntr11 <= cntr11 + "0001";    
         END IF;
      END IF;
   END PROCESS;

   en_ram1 <= '0' WHEN RST = '1' ELSE '1' WHEN (cntr11 = "1100") ELSE en_ram1;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         en_ram1reg <= '0';    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         en_ram1reg <= en_ram1;    
      END IF;
   END PROCESS;

   -- After the RAM is enabled, data is written into the RAM1 for 64 clk cycles. Data is written in into
   --  After the RAM is enabled, data is written into the RAM1 for 64 clk cycles. Data is written in into
   -- each consecutive location . After 64 locations are written into, RAM1 goes into read mode and RAM2 goes into
   -- write mode. The cycle then repeats.
   -- For either RAM, data is written into each consecutive location. However , data is read in a different order. If data
   -- is assumed to be written in each row at a time, in an 8x8 matrix, data is read each column at a time. ie., after
   -- the first data is read out, every eight data is read out . Then the 2nd data is read out followed be every 8th.
   -- the write is as follows:
   -- 1w(ram_locn1) 2w(ram_locn2) 3w(ram_locn3) 4w(ram_locn4) 5w(ram_locn5) 6w(ram_locn6) 7w(ram_locn7) 8w(ram_locn8)
   -- 9w(ram_locn9) 10w(ram_locn10) 11w(ram_locn11) 12w(ram_locn12) 13w(ram_locn13) 14w(ram_locn14) 15w(ram_locn15) 16w(ram_locn16)
   -- ..................
   -- 57w(ram_locn57) 58w(ram_locn58) 59w(ram_locn59) 60w(ram_locn60) 61w(ram_locn61) 62w(ram_locn62) 63w(ram_locn63) 64w(ram_locn64)
   -- the read is as follows:
   -- 1r(ram_locn1)  9r(ram_locn2) . . . 57r(ram_locn8)
   -- 2r(ram_locn9) 10r(ram_locn10) . . . 58r(ram_locn16) 
   -- 3r(ram_locn17) 11r(ram_locn18) . . . 59r(ram_locn24)
   -- 4r(ram_locn25) 12r(ram_locn26) . . . 60r(ram_locn32)
   -- 5r(ram_locn33) 13r(ram_locn34) . . . 61r(ram_locn40)
   -- 6r(ram_locn41) 14r(ram_locn42) . . . 62r(ram_locn48)
   -- 7r(ram_locn49) 15r(ram_locn50) . . . 63r(ram_locn56)
   -- 8r(ram_locn57) 16r(ram_locn58) . . . 64r(ram_locn64)
   -- where "xw" is the xth write and "ram_locnx" is the xth ram location and "xr" is the xth read. Reading 
   -- is advanced by the read counter rd_cntr, nd writing by the write counter wr_cntr. 
   
   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         rd_cntr(5 downto 3) <= "111";    
      ELSIF (CLK'EVENT AND CLK = '1') THEN
         IF (en_ram1reg = '1') THEN
            rd_cntr(5 downto 3) <= rd_cntr(5 downto 3) + "001";    
         END IF;
      END IF;
   END PROCESS;

   PROCESS (CLK, RST)
   BEGIN
      IF (RST = '1') THEN
         rd_cntr(2 downto 0) <= "111";    

⌨️ 快捷键说明

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