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

📄 compressor.vhd

📁 JPEG标准下图象压缩的vhdl实现工程
💻 VHD
📖 第 1 页 / 共 5 页
字号:
      end if;   
   end process RGB2YCbCr;   

   
   
   
   
   
   JPEG : process (reset, clk)
      --in this process data are sent to the DCT1 component, its output is quantized and written back
      --in the same addresses where they were read (buffers) to be sent to DCT1.
      variable Columna : std_logic_vector(9 downto 0);
      variable Linea : std_logic_vector(3 downto 0); --0 to 15
      variable Bloque : std_logic_vector(1 downto 0);
      variable DCTQ : std_logic_vector(24 downto 0); --for multiplication of the result of the DCT with numerator of Q
      
      variable Base : std_logic_vector(8 downto 0); --to access Q coefficients from the tables in ROM
      variable BaseH : std_logic_vector(8 downto 0); --for the Huffman tables ROM
      variable BaseQ : std_logic_vector(8 downto 0); --for the Q tables ROM
     
      variable HuffmanWord : std_logic_vector(22 downto 0);
      variable HuffmanWordPos : integer range -1 to 22;
      variable LumaBlock : std_logic; 
      variable Elemento : std_logic_vector(1 downto 0);
      variable Coeficiente : integer range 0 to 63; --indicates which is the next coefficient to be processed by Huffman
      variable PrevDC : std_logic_vector(11 downto 0); --previous value of luminance DC
      variable Coef : std_logic_vector(11 downto 0); --current coefficient's value
      variable LastBlockDCY : std_logic_vector(11 downto 0);
      variable LastBlockDCCb : std_logic_vector(11 downto 0);
      variable LastBlockDCCr : std_logic_vector(11 downto 0);
      variable IniDC : std_logic;
      variable FirstDC : std_logic;
      variable GetPrevDC : std_logic;
      variable ColBk : std_logic_vector(9 downto 0);
      variable LinBk : std_logic_vector(3 downto 0); --0 to 15
      variable Hlength : integer range 0 to 15;
      variable ZeroRun : integer range 0 to 16;
      variable ZRL : integer range 0 to 3;
      variable WriteZRL : std_logic;
      variable Cat : integer range 0 to 11;
      variable Sign : std_logic;
      variable Primera : std_logic;
      variable HeaderFinal : std_logic; --to know if we've already written EOI (End Of Image)
      variable VarTamImg : std_logic_vector(10 downto 0);
      variable DatoHeader : integer range 0 to 7 := 0; --to know where we are in the writing of the header's image size
      variable TempCompDC : std_logic_vector(14 downto 0);
      variable AddVal : std_logic_vector(11 downto 0);
      variable QDC : std_logic_vector(12 downto 0);
      --pragma translate_off
      
      --I couldn't find any testbench where I could read or write binary files and the ones I found were overcomplex
      --so I experimented and found this to be a useful way to do it without any complications.
      type ByteT is (c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24,c25,c26,c27,c28,c29,c30,c31,c32,c33,c34,c35,c36,c37,c38,c39,c40,c41,c42,c43,c44,c45,c46,c47,c48,c49,c50,c51,c52,c53,c54,c55,c56,c57,c58,c59,c60,c61,c62,c63,c64,c65,c66,c67,c68,c69,c70,c71,c72,c73,c74,c75,c76,c77,c78,c79,c80,c81,c82,c83,c84,c85,c86,c87,c88,c89,c90,c91,c92,c93,c94,c95,c96,c97,c98,c99,c100,c101,c102,c103,c104,c105,c106,c107,c108,c109,c110,c111,c112,c113,c114,c115,c116,c117,c118,c119,c120,c121,c122,c123,c124,c125,c126,c127,c128,c129,c130,c131,c132,c133,c134,c135,c136,c137,c138,c139,c140,c141,c142,c143,c144,c145,c146,c147,c148,c149,c150,c151,c152,c153,c154,c155,c156,c157,c158,c159,c160,c161,c162,c163,c164,c165,c166,c167,c168,c169,c170,c171,c172,c173,c174,c175,c176,c177,c178,c179,c180,c181,c182,c183,c184,c185,c186,c187,c188,c189,c190,c191,c192,c193,c194,c195,c196,c197,c198,c199,c200,c201,c202,c203,c204,c205,c206,c207,c208,c209,c210,c211,c212,c213,c214,c215,c216,c217,c218,c219,c220,c221,c222,c223,c224,c225,c226,c227,c228,c229,c230,c231,c232,c233,c234,c235,c236,c237,c238,c239,c240,c241,c242,c243,c244,c245,c246,c247,c248,c249,c250,c251,c252,c253,c254,c255);
      subtype Byte is ByteT; --well, maybe I oversubtyped it, hehe
      type ByteFileType is file of Byte;

      file outfile : ByteFileType open write_mode is "image.jpg";
      variable Pixel : Byte;
   	variable bufer: LINE;
      variable Header : std_logic_vector(4855 downto 0) := X"FFD8FFE000104A46494600010200000100010000FFC00011080020004003012200021101031101FFDB008400100B0C0E0C0A100E0D0E1211101318281A181616183123251D283A333D3C3933383740485C4E404457453738506D51575F626768673E4D71797064785C656763011112121815182F1A1A2F634238426363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363FFC401A20000010501010101010100000000000000000102030405060708090A0B100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FA0100030101010101010101010000000000000102030405060708090A0B1100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00";
      --pragma translate_on

   begin
      if (reset = '1') then
         CompressingInt <= '0';
         Linea := (others => '0');
         Columna := (others => '0');
         Bloque := "00";
         StepV <= 0;
         weY2 <= '0';
         weCb2 <= '0';
         weCr2 <= '0';
         Base := (others => '0');
         BaseH := (others => '0');
         BaseQ := (others => '0');        
         DCTQ := (others => '0');
         DIND <= (others => '0');
         ND <= '0';
         --Huffmanear <= '0';
         PrevDC := (others => '0');
         Coeficiente := 0;
         HuffmanWord := (others => '0');
         HuffmanWordPos := 22; --first free LSB (HuffmanWord's MSB)
         Elemento := "00";
         IniDC := '1';
         GetPrevDC := '1';
         FirstDC := '1';
         Save <= '0';
         addri <= "0000000000101100"; --first Table
         addribk <= "0000001001011110"; --pointer to last Header byte
         addrH <= (others => '0');
         addrQ <= (others => '0');
         addrCb2 <= (others => '0');
         addrCr2 <= (others => '0');
         addrY2 <= (others => '0');
         din <= (others => '0');
         we <= '0';
         dinY2 <= (others => '0');
         dinCr2 <= (others => '0');
         dinCb2 <= (others => '0');
         Done <= '0';
         Cat := 0;
         ZRL := 0;
         Coef := (others => '0');
         ColBk := (others => '0');
         LinBk := (others => '0');
         Sign := '0';
         ZeroRun := 0;
         Primera := '0';
         LumaBlock := '0';
         NDe <= '0';           
         HeaderFinal := '0';
         DatoHeader := 0;
         VarTamImg := (others => '0');    
         WriteAdditionalBits <= '0';
         TempCompDC := (others => '0');
         WriteZRL := '0';
         LastBlockDCY := (others => '0');
         LastBlockDCCb := (others => '0');
         LastBlockDCCr := (others => '0');            
         AddVal := (others => '0');                
         QDC := (others => '0');
         WriteTables <= '0';
         TableData <= (others => '0');
         Table <= '0';    
         addrTablaQ <= (others => '0');
         ZRLing <= '0';       
         RFDInt <= '0';
         RFDIntData <= (others => '0');
      elsif (clk = '1' and clk'event) then
         if CompressImage = '1' then
            FirstDC := '1';
            IniDC := '1';
            HeaderFinal := '0';
            GetPrevDC := '1';
            PrevDC := (others => '0'); --initialized to zero at the beginning of the image
            HuffmanWord := (others => '0');
            HuffmanWordPos := 22;
            Save <= '0';
            DatoHeader := 0;
            WriteAdditionalBits <= '0';
            HeaderFinal := '0';
            WriteTables <= '1';
            TableData <= (others => '0');
            Table <= '0';
            addribk <= "0000001001011110"; --pointer to the Header's last byte
            addri <= "0000000000101100"; --first Table
            case Compression is
               when "00" => --low quality
                  BaseQ := "100000000";
               when "01" => --medium quality
                  BaseQ := "010000000";
               when others => --10 high quality
                  BaseQ := "000000000";
            end case;
            addrTablaQ <= BaseQ; --ready first data

            CompressingInt <= '0';
            Bloque := "00";
            StepV <= 0;
            weY2 <= '0';
            weCb2 <= '0';
            weCr2 <= '0';
            Base := (others => '0');
            BaseH := (others => '0');
            ND <= '0';
            Coeficiente := 0;
            we <= '0';
            Done <= '0';            
            ZRLing <= '0';
            RFDInt <= '0';
            RFDIntData <= (others => '0');
            --pragma translate_off
               Columna := ('0' & ImgLines) + 1;                  
               for i in 606 downto 563 loop
                  case i is
                     when (606-25) => --MSByte of size Y
                        Pixel := ByteT'val(conv_integer("0000000" & Columna(8)));
                     when (606-26) => --LSByte of size Y
                        Pixel := ByteT'val(conv_integer(Columna(7 downto 0)));
                        Columna := ImgColumns + 1;
                     when (606-27) => --MSByte of size X
                        Pixel := ByteT'val(conv_integer("000000" & Columna(9 downto 8)));
                     when (606-28) => --LSByte of size X
                        Pixel := ByteT'val(conv_integer(Columna(7 downto 0)));
                     when others =>
                        Pixel := ByteT'val(conv_integer(Header(8*i+7 downto 8*i)));
                  end case;      
                  write(outfile, Pixel);
               end loop;            
            --pragma translate_on
            
         end if;
         we <= '0'; --after the ones that rise it
         if WriteTables = '1' then --write in memory the quantization tables for the selected compression level
            if Table = '0' then --the start of Table Q of value "00h" is in position 2Bh (43=101011)
               addri <= "0000000000101100" + ('0' & TableData);
            else--the start of Table Q of value "01h" is in position 6Ch (108=1101100) 
               addri <= "0000000001101101" + ('0' & TableData);
            end if;   
            din <= doutTablaQ;
            addrTablaQ <= addrTablaQ + 1;
            
            if addrTablaQ /= BaseQ then --first coefficient, not written because we'll have it also in next cycle
               --until second coefficient is loaded
               we <= '1';
               TableData <= TableData + 1;
               --pragma translate_off
               Pixel := ByteT'val(conv_integer(doutTablaQ));
               write(outfile, Pixel);
               --pragma translate_on            
            end if;
            
            if TableData = "111111" then
               if Table = '1' then --we are over
                  --pragma translate_off
                  for i in 433 downto 0 loop
                     Pixel := ByteT'val(conv_integer(Header(8*i+7 downto 8*i)));
                     write(outfile, Pixel);
                  end loop;            
                  --pragma translate_on                  

                  WriteTables <= '0';
                  addrTablaQ <= (others => '0'); --so that it doesn't stay in a non-existent address
               else   
                  Table <= '1';                 
                  --pragma translate_off
                  Pixel := ByteT'val(1); --points to the start of Table 01
                  write(outfile, Pixel);
                  --pragma translate_on                              
               end if;   
            end if;   
         end if;   
         
         if (MakeDCT = '1' or CompressingInt = '1') then --MakeDCT lasts only one cycle, but CompressingInt is high the following ones
            if MakeDCT = '1' then
               HeaderFinal := '0';
               --write the image size, now that we know it, in the header as at the least we must do
               --4 DCTs in an image, there won't be any problem if image size writing is done in four steps
               --or if it is repeated throughout the image's processing
               case DatoHeader is
                  when 0 => --MSByte of ImgLines+1
                     addri <= "0000000000011001"; --position 0 of the two bytes of size Y (lines)
                     we <= '1';
                     VarTamImg := ("00" & ImgLines) + 1;
                     din <= "000000" & VarTamImg(9 downto 8);
                     DatoHeader := 1;
                  when 1 => --LSByte of ImgLines+1
                     addri <= "0000000000011010"; 
                     we <= '1';
                     din <= VarTamImg(7 downto 0);
                     DatoHeader := 2;
                  when 2 => --MSByte of ImgColumns+1
                     addri <= "0000000000011011"; --position 0 of the two bytes of size X (columns)
                     we <= '1';
                     VarTamImg := ('0' & ImgColumns) + 1;
                     din <= "00000" & VarTamImg(10 downto 8);
                     DatoHeader := 3;
                  when 3 => --LSByte of ImgColumns+1
                     addri <= "0000000000011100"; 
                     we <= '1';
                     din <= VarTamImg(7 downto 0);
                     DatoHeader := 4;
                  when 4 to 7 => --it's been already written, don't do anything(we put 8 DatoHeader because in the last
                     --block when we pass to the next image, ImgLines is zero and it is wrongly written)
                     we <= '0';
                     if DatoHeader = 7 then

⌨️ 快捷键说明

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