?? compressor.vhd
字號:
------------------------------------------------------------------------------------------------------- Title : JPEG Hardware Compressor-- Design : jpeg-- Author : Victor Lopez Lorenzo-- E-mail : victor.lopez ((at)) ono ((dot)) com---- License : Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported-- http://creativecommons.org/licenses/by-nc-sa/3.0/----------------------------------------------------------------------------------------------------------- Copyright (C) 2004 Victor Lopez Lorenzo------ PLEASE NOTICE THAT THIS CORE IS LICENSED UNDER http://creativecommons.org/licenses/by-nc-sa/3.0/-- (Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported).-- That means you may use it only for NON-COMMERCIAL purposes.----------------------------------------------------------------------------------------------------------- Contributors :-- Peter Eisemann - Fixed GetCategory, writes and file declarations in order to-- simulate code under ModelSim-- --------------------------------------------------------------------------------------------------------- -- IMPORTANT NOTES :---- This source code features a compliant JPEG compressor Baseline DCT with-- Huffman enconding and 2x2 1x1 1x1 subsampling. The header is the widely-- employed JFIF.---- Baseline DCT JPEG with JFIF header is one of the most used image formats.---- The maximum image size is limited to 352x288---- Another limitation is that the input image must have width and height-- multiple of 16 (that is, an image 32x32 will produce a strictly compliant-- JPEG image file, but not a 32x24 or a 24x32 input image, although the resulting-- image will more likely still be viewable), this is due to the subsampling-- method employed.---- I apologize if you find this code somewhat messy. When I programmed it I imposed-- myself very strict deadlines and making it opensource was not in my mind, mainly-- because, if I were to do it again, I would do it in other way to get much-- more performance. The main problem faced with this implementation was a very-- scarce availability of BlockRAM in the target FPGA, so some areas that could-- perfectly run in parallel, speeding a lot the whole process, had to be made-- sequential in order to save up BlockRAMs. Anyways, this code works-- (it functioned as a webcam, attached to a CMOS sensor) and, though not-- as fast as it could be, it has a good performance.-- -- As a part of this project there is a quite useful Testbench that takes as input-- any BMP (24 bit color) image and compresses it with this code, outputting a JPG-- file that you can view in your computer.-----------------------------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.all;use IEEE.numeric_std.all;use IEEE.std_logic_unsigned.all; --for arithmetic ops--pragma translate_offlibrary STD;use IEEE.std_logic_textio.all;library XilinxCoreLib;--pragma translate_onlibrary UNISIM; use UNISIM.all; entity Compressor is port ( clk : in STD_LOGIC; reset : in STD_LOGIC; --Control/Status Interface CompressImage : in std_logic; --must be active high for just one cycle Compression : in std_logic_vector(1 downto 0); --Quality: 00 = low, 01 = medium, 10 = high Mono : in std_logic; --active high for grey-scale input image (Red=Green=Blue) ImgColumns : in std_logic_vector(9 downto 0); --columns in each line of the image to compress ImgLines : in std_logic_vector(8 downto 0); --lines of the image to compress Compressing : out std_logic; --Data Interface ProcessRGB : in std_logic; ProcessingRGB : out std_logic; Red : in std_logic_vector(7 downto 0); Green : in std_logic_vector(7 downto 0); Blue : in std_logic_vector(7 downto 0); --JPEG Image BlockRAM (Output) Interface addr: out std_logic_VECTOR(15 downto 0); din: out std_logic_VECTOR(7 downto 0); we: out std_logic);end Compressor;architecture JPG of Compressor is--pragma translate_offfile Debug: TEXT open WRITE_MODE is "Debug.txt";file DebugY: TEXT open WRITE_MODE is "DebugY.txt";file DebugCb: TEXT open WRITE_MODE is "DebugCb.txt";file DebugCr: TEXT open WRITE_MODE is "DebugCr.txt";-- file Debug:TEXT is out "Debug.txt";-- file DebugY:TEXT is out "DebugY.txt";-- file DebugCb:TEXT is out "DebugCb.txt";-- file DebugCr:TEXT is out "DebugCr.txt"; constant espacio:string:=" "; constant espacios:string:=" "; constant puntoycoma:string:=";"; constant strElemento:string:=" Element: "; constant strColumna:string:=" Column: "; constant strLinea:string:=" Line: ";--pragma translate_on component dct2d port ( ND: IN std_logic; RDY: OUT std_logic; RFD: OUT std_logic; CLK: IN std_logic; DIN: IN std_logic_VECTOR(7 downto 0); DOUT: OUT std_logic_VECTOR(18 downto 0)); end component; component buffer_comp port ( addr: IN std_logic_VECTOR(12 downto 0); clk: IN std_logic; din: IN std_logic_VECTOR(11 downto 0); dout: OUT std_logic_VECTOR(11 downto 0); we: IN std_logic); end component; component buffer_comp_chrom port ( addr: IN std_logic_VECTOR(10 downto 0); clk: IN std_logic; din: IN std_logic_VECTOR(11 downto 0); dout: OUT std_logic_VECTOR(11 downto 0); we: IN std_logic); end component; component q_rom port ( addr: IN std_logic_VECTOR(8 downto 0); clk: IN std_logic; dout: OUT std_logic_VECTOR(12 downto 0)); end component; component huff_rom port ( addr: IN std_logic_VECTOR(8 downto 0); clk: IN std_logic; dout: OUT std_logic_VECTOR(19 downto 0)); end component; component tabla_q port ( addr: IN std_logic_VECTOR(8 downto 0); clk: IN std_logic; dout: OUT std_logic_VECTOR(7 downto 0)); end component; --signals for tabla_q signal addrTablaQ: std_logic_VECTOR(8 downto 0); signal doutTablaQ: std_logic_VECTOR(7 downto 0); --signal for huff_rom signal addrH : std_logic_vector(8 downto 0); signal doutH : std_logic_vector(19 downto 0); --signals for DCT block signal ND: std_logic; signal RDY: std_logic; signal RFD: std_logic; signal DIND: std_logic_VECTOR(7 downto 0); signal DOUTD: std_logic_VECTOR(18 downto 0); --signals for compression buffer signal addrY: std_logic_VECTOR(12 downto 0); signal dinY: std_logic_VECTOR(11 downto 0); signal doutY: std_logic_VECTOR(11 downto 0); signal weY: std_logic; signal addrCb: std_logic_VECTOR(10 downto 0); signal dinCb: std_logic_VECTOR(11 downto 0); signal doutCb: std_logic_VECTOR(11 downto 0); signal weCb: std_logic; signal addrCr: std_logic_VECTOR(10 downto 0); signal dinCr: std_logic_VECTOR(11 downto 0); signal doutCr: std_logic_VECTOR(11 downto 0); signal weCr: std_logic; signal addrY1: std_logic_VECTOR(12 downto 0); signal addrCb1: std_logic_VECTOR(10 downto 0); signal addrCr1: std_logic_VECTOR(10 downto 0); signal addrY2: std_logic_VECTOR(12 downto 0); signal addrCb2: std_logic_VECTOR(10 downto 0); signal addrCr2: std_logic_VECTOR(10 downto 0); signal dinY1: std_logic_VECTOR(11 downto 0); signal dinY2: std_logic_VECTOR(11 downto 0); signal dinCb1: std_logic_VECTOR(11 downto 0); signal dinCb2: std_logic_VECTOR(11 downto 0); signal dinCr1: std_logic_VECTOR(11 downto 0); signal dinCr2: std_logic_VECTOR(11 downto 0); signal weY1: std_logic; signal weY2: std_logic; signal weCb1: std_logic; signal weCb2: std_logic; signal weCr1: std_logic; signal weCr2: std_logic; --signals for the quantization coefficients ROM signal addrQ : std_logic_vector(8 downto 0); signal doutQ : std_logic_vector(12 downto 0); signal addri : std_logic_vector(15 downto 0); --to write directly to the port (headers and JPEG size) and read from it signal addribk : std_logic_vector(15 downto 0); --exclusive when signal Save='1', it holds the current pixel constant MaxImageSize : std_logic_vector(15 downto 0) :="1100011111111100"; --51196 bytes signal ColumnToCompress : std_logic_vector(9 downto 0); signal LineToCompress : std_logic_vector(3 downto 0); --goes from 0 to 15, the 16 that may occupy the luminance buffer signal LineAbsToCompress: std_logic_vector(8 downto 0); signal MakeDCT : std_logic; signal CompressingInt : std_logic; signal Done : std_logic; --the Huffman encoding part rises it for one cycle when finishes signal StepV : integer range 0 to 5; signal Save : std_logic; signal NDe : std_logic; signal WriteAdditionalBits : std_logic; signal WriteTables : std_logic; signal TableData : std_logic_vector(5 downto 0); signal Table : std_logic; signal ZRLing : std_logic; signal RFDInt : std_logic; signal RFDIntData : std_logic_vector(7 downto 0); function Multiplier (Num, Prod : in std_logic_vector) return std_logic_vector; function Multiplier (Num, Prod : in std_logic_vector) return std_logic_vector is variable result : std_logic_vector(19 downto 0) := (others => '0'); begin --8 bits * 10 bits both unsigned = 18 bits result := ('0' & Num(7 downto 0)) * ('0' & Prod); return result(17 downto 0); end Multiplier; function MultiplierQ (Num, Prod : in std_logic_vector) return std_logic_vector; function MultiplierQ (Num, Prod : in std_logic_vector) return std_logic_vector is variable result : std_logic_vector(26 downto 0); variable UNum : std_logic_vector(11 downto 0); begin --it is like Multiplier but admits bigger operands: Num (10..0) (signed) and Prod (10..0) (unsigned) --max result = 1000_0000_0000 * 111_1111_1111 = 1(sign)11_1111_1111_1000_0000_0000 (-2.048 * 2.047 = -4.192.256) --UPDATE: now Prod may be of up to 13 bits (12..0), so the result will be 24..0 if Num(Num'High) = '1' then --negative number? UNum := not (Num) + 1; --two's complement to make it positive else UNum := Num;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -