📄 compressor.vhd
字号:
---------------------------------------------------------------------------------------------------
--
-- Title : JPEG Hardware Compressor
-- Design : jpeg
-- Author : Victor Lopez Lorenzo
-- E-mail : galland@opencores.org
--
---------------------------------------------------------------------------------------------------
--
--
-- Copyright (C) 2004 Victor Lopez Lorenzo
--
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
--
---------------------------------------------------------------------------------------------------
--
-- 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 number of columns is limited, in this source code, to 352, but
-- it can be very easily changed to as many as wanted just by recustomizing
-- the BlockRAMs used for buffer_comp and buffer_comp_chrom as indicated in the
-- project's documentation, plus changing their associated signals in this
-- file and updating two functions: Mult_Columns and Mult_Half_Columns.
-- For the BlockRAMs, mainly:
-- - buffer_comp must have a depth of (number_of_columns x 16) positions
-- - buffer_comp_chrom must have a depth of (number_of_columns x 4) positions
-- width is 12 bits for both
--
-- There is another easily overridable limitation, buffer_img, the core of BlockRAM
-- memory used to save the final compressed image. I generated one of 51200 bytes,
-- if it is not enough for your application (remember that final compressed images
-- vary in size even with similar resolution input images as some compress better
-- than others), largening it may be as simple as recustomizing the core and
-- changing two signals (addri and addribk) and one constant (MaxImageSize),
-- apart from copying the new buffer_img declaration.
--
-- The only real 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. This limitation could be overriden with some extra logic
-- (for padding as indicated in the JPEG standard).
--
-- 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_off
library STD;
use STD.textio.all;
use IEEE.std_logic_textio.all;
library XilinxCoreLib;
--pragma translate_on
library 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_off
file 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);
--this is, (obviously along with the buffer_img blockram core itself) the limiting factor of final compressed image size
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
--for bigger images, enlarge buffer_img and change these signals' lengths
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -