URL
https://opencores.org/ocsvn/huffmandecoder/huffmandecoder/trunk
Subversion Repositories huffmandecoder
Compare Revisions
- This comparison shows the changes necessary to convert path
/huffmandecoder/trunk
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/all.sav
0,0 → 1,21
[timestart] 0 |
[size] 1000 600 |
[pos] -1 -1 |
*-33.000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 |
[treeopen] top. |
[treeopen] top.jpeg_tb. |
@28 |
top.jpeg_tb.wr_en |
top.jpeg_tb.wr |
top.jpeg_tb.clk |
top.jpeg_tb.sop |
@22 |
#data_in[7:0] top.jpeg_tb.data_in[7] top.jpeg_tb.data_in[6] top.jpeg_tb.data_in[5] top.jpeg_tb.data_in[4] top.jpeg_tb.data_in[3] top.jpeg_tb.data_in[2] top.jpeg_tb.data_in[1] top.jpeg_tb.data_in[0] |
@28 |
top.jpeg_tb.next_eob |
@22 |
#zrl[3:0] top.jpeg_tb.zrl[3] top.jpeg_tb.zrl[2] top.jpeg_tb.zrl[1] top.jpeg_tb.zrl[0] |
#data_out[15:0] top.jpeg_tb.data_out[15] top.jpeg_tb.data_out[14] top.jpeg_tb.data_out[13] top.jpeg_tb.data_out[12] top.jpeg_tb.data_out[11] top.jpeg_tb.data_out[10] top.jpeg_tb.data_out[9] top.jpeg_tb.data_out[8] top.jpeg_tb.data_out[7] top.jpeg_tb.data_out[6] top.jpeg_tb.data_out[5] top.jpeg_tb.data_out[4] top.jpeg_tb.data_out[3] top.jpeg_tb.data_out[2] top.jpeg_tb.data_out[1] top.jpeg_tb.data_out[0] |
@28 |
top.jpeg_tb.output_valid |
top.jpeg_tb.eop |
/huffman_decoder.vhd
0,0 → 1,963
---------------------------------------------------------------------------------- |
-- Company: Dossmatik GmbH /Germany |
-- Engineer: Rene Doss |
-- Create Date: 10/12/2009 |
-- Design Name: |
-- Module Name: huffman decoder for jpeg application |
---------------------------------------------------------------------------------- |
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.numeric_std.all; |
-- use std.textio.all; -- only for testing |
--use work.txt_util.all; |
|
--use IEEE.STD_LOGIC_ARITH.ALL; |
--use IEEE.STD_LOGIC_UNSIGNED.ALL; |
|
|
|
entity huffman_decoder is |
port( |
clk :in std_logic; |
|
--interface data input |
wr :in std_logic; --write |
data_in : in unsigned (7 downto 0); --data jpeg stream |
wr_en : out std_logic:='1'; --write enable |
|
--interface data out |
output_valid : buffer std_logic; --use it as write signal in the follow IDCT |
data_out : out signed (15 downto 0); --decoded and dequantized coefficient |
next_eob : buffer std_logic:='0'; --the next data is the last coefficient of block |
--all higher zigzag coeficients are zero |
sop : out std_logic:='0'; --start of picture, can be used as reset in the following IDCT |
eop : out std_logic:='0'; --end of picture |
zrl : out unsigned (3 downto 0); -- number of consecutive zeros before the next coefficient |
decoder_enable : in std_logic); |
end huffman_decoder; |
|
|
|
|
|
architecture Behavioral of huffman_decoder is |
------------------------------------------------- |
subtype by_te is character; |
type f_byte is file of by_te; |
|
type ubyte_vector16 is array (0 to 15) of unsigned (7 downto 0); |
type uword_vector16 is array (0 to 15) of unsigned (15 downto 0); |
|
--prepaired type for post IDCT not implemented yet |
-- type word_vector64 is array (0 to 63) of signed (15 downto 0); |
|
type dual_table is array (0 to 1,0 to 63) of unsigned (7 downto 0); --quant Tables |
|
|
type int_vector64 is array (0 to 63) of integer; |
constant zigzag :int_vector64:=( 0, 8, 1, 2, 9,16,24,17, |
10, 3, 4,11,18,25,32,40, |
33,26,19,12, 5, 6,13,20, |
27,34,41,48,56,49,42,35, |
28,21,14, 7,15,22,29,36, |
43,50,57,58,51,44,37,30, |
23,31,38,45,52,59,60,53, |
46,39,47,54,61,62,55,63); |
|
|
--hufftable storage place definition |
constant RAM_addrwidth: integer:=9; |
-- Entspricht 512 Speicherzellen reicht für 2 DC und 2AC Tabellen |
--sollte gegebenfalls erhöht werden!!!!!!!!! |
|
type RAM is array (0 to (2**RAM_addrwidth-1)) of unsigned (7 downto 0); |
subtype RAM_int is integer range 0 to (2**RAM_addrwidth-1); |
|
|
--2*4*16 Für 4 DC-Tabellen und 4AC-Tabelle |
type pointer_array is array (0 to 127) of RAM_int; |
type uword_array is array ( 0 to 127) of unsigned (15 downto 0); |
type int_vectorRAM is array(0 to 15) of integer range 0 to (2**RAM_addrwidth-1); |
------------------------------------------------------- |
--the state machine is divide |
--some states for sub state machine |
type sos_type is (decode,decode_post,catch,catch_post,change_comp0, |
change_comp,change_DC_AC0,change_DC_AC); |
type sos_header_type is (selector,table); |
type SOF0_Header_type is (selector,sampling,table); |
|
|
--this is for the main state machine |
type state_type is (IDLE, |
SOI, --0xFFD8 start of image |
APP0, --0xFFE0 application segment |
|
DQT, --0xFFDB define quantisation table |
DQT_length,DQT_length0, |
DQT_active, |
SOF0_length,SOF0_length0, --0xFFC0 baseline DCT |
SOF0_precision, |
SOF0_y_high,SOF0_y_low, |
SOF0_x_high,SOF0_x_low, |
SOF0_nr_comp,SOF0_active, |
|
DHT, --0xFFC4 define Huffman Table |
DHT_length,DHT_length0, |
DHT_destination, |
DHT_Number, |
|
DHT_active, |
--0xFFDA start of scan |
SOS_length,SOS_length0,SOS_header, |
SOS_init0,SOS_init1,SOS_init2,SOS_init3, |
SOS_scan, |
EOI); --0xFFD9 end of Image |
----------------------------------------------------------------------------- |
|
signal value : signed (15 downto 0); |
|
|
signal qtable : dual_table; |
signal write_active: std_logic; |
signal input_reg:unsigned (23 downto 0); |
signal Markerlength: unsigned (15 downto 0); |
signal next_state,state: state_type:=idle; |
signal sos_state,sos_state_old:sos_type:=decode; |
signal DHT_counter: integer; |
|
|
signal SOF0_header_state:SOF0_Header_type; |
signal sof0_header_index:integer range 0 to 15 := 15; |
signal x_size,y_size:unsigned (15 downto 0); --picture size |
signal sof0_number_comp: unsigned(7 downto 0); |
signal sof0_comp_table: uword_vector16; -- hier ist die Info Qtable genommen werden |
|
|
signal output_active: std_logic:='0'; |
|
signal huff_wr_en: std_logic:='1'; |
|
|
|
|
--Hufftable |
signal ram_pointer: pointer_array; |
signal huff_ram: RAM; |
signal huff_code_offset: uword_array; |
signal ram_offset:RAM_int; |
|
signal dest: integer:=0; |
signal DC_AC_decode: unsigned (2 downto 0):="000"; |
signal DC_AC_old: unsigned (0 downto 0); |
signal index: integer range 0 to 15; |
signal huff_table_end :std_logic:='1'; |
signal addr: integer range 0 to (2**RAM_addrwidth-1); |
signal huff_a: unsigned (7 downto 0):="00000011"; |
signal huff_code_number: ubyte_vector16; |
signal h_code: unsigned (15 downto 0); |
signal h_delta: uword_vector16; |
signal code_word: unsigned (7 downto 0); |
|
|
|
signal comp_table:ubyte_vector16; |
--data |
signal read_offset,read_offset_a: integer range 0 to 15; |
signal shift : integer range 1 to 16; |
--signal ablock :word_vector64; |
signal RLD_wr:std_logic; |
signal stuffing :std_logic; |
signal scan_data: unsigned (7 downto 0); |
signal Barrel,ba: unsigned (15 downto 0); |
signal ba_1: unsigned (0 downto 0); |
signal rot_buffer: unsigned(31 downto 0):=X"00000000"; --Das ist der Ringspeicher vom Decoder |
signal barrel_pointer: unsigned (4 downto 0):="00000"; |
signal write_rot_pointer: unsigned (1 downto 0):="11"; |
signal sos_number_comp: unsigned(7 downto 0); |
signal sos_comp_table: ubyte_vector16; -- hier ist die Info welche Huff-table und Qtable genommen werden |
signal sos_wr_en:std_logic:='1'; |
signal sos_teiler2: std_logic:='0'; |
|
signal sos_header_state:sos_header_type; |
signal sos_header_index:integer range 0 to 15 := 15; |
signal sos_matrix_counter:unsigned (5 downto 0):=(others=>'0'); |
Signal sos_scan_index: integer; |
signal sos_hi :unsigned (3 downto 0); |
signal sos_vi :unsigned (3 downto 0); |
signal sos_component: integer range 0 to 15; |
signal eoi_detect:std_logic_vector (1 downto 0):="00"; --bit 0 eoi detect, bit 1 last eob detect |
-------------------------------------------- |
signal addr_table: integer range 0 to 63; |
|
|
-- |
begin |
|
data_out<=value; |
|
process(clk) |
begin |
if clk'event and clk='1' then |
if sos_state=catch_post then |
output_active<='1'; |
end if; |
if state=eoi then |
output_active<='0'; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
if clk'event and clk='1' then |
if output_active='1' and sos_state=catch then |
output_valid<='1'; |
zrl<=code_word(7 downto 4); |
else |
output_valid<='0'; |
end if; |
end if; |
end process; |
|
-- --this is my testing process at simulation |
--process(clk) |
--constant file_name: string:="output.txt"; |
--file log: text open write_mode is file_name; |
--variable myline:line; |
--begin |
--if clk'event and clk='1' then |
-- if sos_state=catch then |
-- write(myline,now); |
-- write(myline,string'(" ")); |
-- write(myline,str(to_integer(DC_AC_decode))); |
-- write(myline,string'(" ")); |
-- write(myline,str(to_integer(value))); |
-- writeline(log,myline); |
-- end if; |
--end if; |
--end process; |
|
|
--sm Huffdecoder |
|
|
--state decode huffman decode |
--state catch mantissa bits |
--state catch post an additional delay |
|
-- decode -> catch -> catch_post ->decode...........this is the cycle in work |
--some waits needed when the table is changed that all values are valid |
|
|
process (clk,state,decoder_enable) |
begin |
if state=sos_init1 then |
barrel_pointer<="11111"; |
|
elsif clk'event and clk='1' and decoder_enable='1' then |
if state=sos_init0 then |
sos_state<=decode; |
end if; |
|
if state=sos_scan then |
if sos_state=catch then |
sos_state<=catch_post; |
|
end if; |
--normaler Ablauf |
if (sos_state=catch_post and (DC_AC_decode(0 downto 0)/="0" and code_word/=to_unsigned(0,8)))then |
barrel_pointer<=barrel_pointer - ('0'& code_word(3 downto 0)); |
sos_state<=decode; |
end if; |
--letzte Zeichen |
if(sos_state=catch_post and (DC_AC_decode(0 downto 0)/="0" and code_word=to_unsigned(0,8))) then |
sos_state<=change_comp0; |
end if; |
if sos_state=change_comp0 then |
sos_state<=change_comp; |
end if; |
|
--DC zu AC Uebergang |
if (sos_state=catch_post and (DC_AC_decode(0 downto 0)="0")) then |
sos_state<=change_DC_AC0; |
end if; |
if sos_state=change_DC_AC0 then |
sos_state<=change_DC_AC; |
end if; |
-- |
if sos_state=change_DC_AC or sos_state=change_comp then |
barrel_pointer<=barrel_pointer - ('0'& code_word(3 downto 0)); |
sos_state<=decode; |
end if; |
|
|
if ((write_rot_pointer=barrel_pointer(4 downto 3)) or |
(write_rot_pointer="00" and barrel_pointer(4 downto 3)="11") or |
(write_rot_pointer="01" and barrel_pointer(4 downto 3)="00") or |
(write_rot_pointer="10" and barrel_pointer(4 downto 3)="01") or |
(write_rot_pointer="11" and barrel_pointer(4 downto 3)="10")) then |
|
if sos_state= decode then |
barrel_pointer<=barrel_pointer-to_unsigned(shift,5); |
sos_state<=catch; |
|
end if; |
|
|
end if; |
end if; |
|
|
end if; |
end process; |
|
|
|
|
--chose the correct table |
--xx0 DC Tables |
--xx1 AC Table |
process (clk) |
begin |
if clk'event and clk='1' then |
sos_state_old<=sos_state; |
|
if state=sos_init0 then |
DC_AC_decode<=SOS_comp_table(0)(1 downto 0)&"0"; |
sos_matrix_counter<=(others=>'0'); |
sos_scan_index<=0; |
sos_component<=0; |
sos_vi<=to_unsigned(1,4); |
sos_hi<=to_unsigned(1,4); |
end if; |
|
if state=sos_scan then |
if sos_state=change_comp0 then |
DC_AC_decode<=SOS_comp_table(sos_component)(1 downto 0)&"0"; |
|
end if; |
if sos_state_old=catch then |
if (((code_word=0) and (sos_matrix_counter>0)) or sos_matrix_counter=63) then |
--darf erst ab Position 2 zurückgesetzt werden |
--mindestens ein DC und ein AC Wert |
sos_matrix_counter<=(others=>'0'); |
|
else |
sos_matrix_counter<=sos_matrix_counter+1; |
end if; |
|
|
if sos_matrix_counter=0 then |
DC_AC_decode<=SOS_comp_table(sos_component)(1 downto 0)&"1"; |
|
end if; |
if sos_matrix_counter/=0 then |
|
-- |
if code_word=0 or sos_matrix_counter=63 then |
|
if sos_vi<sof0_comp_table(sos_component)(15 downto 12) then |
sos_vi<=sos_vi+1; |
|
else |
sos_vi<=to_unsigned(1,4); |
if sos_hi<sof0_comp_table(sos_component)(11 downto 8) then |
sos_hi<=sos_hi+1; |
else |
sos_hi<=to_unsigned(1,4); |
end if; |
if sos_hi=sof0_comp_table(sos_component)(11 downto 8) then |
if sos_component=to_integer(sos_number_comp-1) then |
sos_component<=0; |
else |
sos_component<=sos_component+1; |
end if; |
end if; |
end if; |
end if; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
|
|
|
|
wr_en<=huff_wr_en and sos_wr_en and not eoi_detect(0) after 2 ns; |
|
|
---decoder |
|
write_active<=wr; --notwendig für die Simulation |
|
|
-- waiting for the last block |
|
process(clk) |
begin |
if clk'event and clk='1' then |
if next_state=eoi then |
eoi_detect<="00"; |
end if; |
if input_reg(15 downto 0)=x"FFD9"then |
eoi_detect(0)<='1'; |
end if; |
if eoi_detect(0)='1' and next_eob='1' then |
eoi_detect(1)<='1'; |
end if; |
end if; |
end process; |
|
|
--destuffing |
process(clk,write_active) |
begin |
if write_active='1' then |
if clk'event and clk='1' then |
if input_reg(7 downto 0)=X"FF" then |
stuffing<='1'; |
else |
stuffing<='0'; |
end if; |
end if; |
end if; |
end process; |
|
|
|
sos_wr_en<='0' when state=sos_scan and barrel_pointer(4 downto 3) = write_rot_pointer else '1'; |
|
---load fifo |
--it is a cirular memory 32bit long |
-- this is the importent part in ths design |
process(clk,write_active,sos_wr_en,eoi_detect(0)) |
|
begin |
--wr_en<=huff_wr_en and sos_wr_en and not eoi_detect after 2 ns; |
if clk'event and clk='1' then |
|
if (write_active='1' and stuffing='0')or (sos_wr_en='1' and eoi_detect(0)='1' ) then |
|
|
if state=SOS_init0 then |
write_rot_pointer<="11"; |
rot_buffer(31 downto 24) <=input_reg(15 downto 8); |
end if; |
if state=SOS_init1 then |
rot_buffer(23 downto 16) <=input_reg(15 downto 8); |
end if; |
if state=SOS_init2 then |
rot_buffer(15 downto 8) <=input_reg (15 downto 8); |
end if; |
if state=SOS_init3 then |
rot_buffer(7 downto 0)<= input_reg(15 downto 8); |
|
end if; |
|
|
if state=sos_scan then |
if barrel_pointer(4 downto 3) /= write_rot_pointer then |
|
--sos_wr_en<='0'; |
|
write_rot_pointer<=write_rot_pointer-1; |
--sos_wr_en<='1'; |
case write_rot_pointer is |
when "00"=> rot_buffer(7 downto 0)<= input_reg(15 downto 8); |
when "01"=> rot_buffer(15 downto 8) <=input_reg (15 downto 8); |
when "10"=> rot_buffer(23 downto 16) <=input_reg(15 downto 8); |
when "11"=> rot_buffer(31 downto 24) <=input_reg(15 downto 8); |
when others=> null; |
end case; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
process (barrel_pointer,rot_buffer) |
begin |
case to_integer(barrel_pointer) is |
when 0 => barrel<= rot_buffer (0 downto 0) & rot_buffer (31 downto 17); |
when 1 => barrel<= rot_buffer (1 downto 0) & rot_buffer (31 downto 18); |
when 2 => barrel<= rot_buffer (2 downto 0) & rot_buffer (31 downto 19); |
when 3 => barrel<= rot_buffer (3 downto 0) & rot_buffer (31 downto 20); |
when 4 => barrel<= rot_buffer (4 downto 0) & rot_buffer (31 downto 21); |
when 5 => barrel<= rot_buffer (5 downto 0) & rot_buffer (31 downto 22); |
when 6 => barrel<= rot_buffer (6 downto 0) & rot_buffer (31 downto 23); |
when 7 => barrel<= rot_buffer (7 downto 0) & rot_buffer (31 downto 24); |
when 8 => barrel<= rot_buffer (8 downto 0) & rot_buffer (31 downto 25); |
when 9 => barrel<= rot_buffer (9 downto 0) & rot_buffer (31 downto 26); |
when 10 => barrel<= rot_buffer (10 downto 0) & rot_buffer (31 downto 27); |
when 11 => barrel<= rot_buffer (11 downto 0) & rot_buffer (31 downto 28); |
when 12 => barrel<= rot_buffer (12 downto 0) & rot_buffer (31 downto 29); |
when 13 => barrel<= rot_buffer (13 downto 0) & rot_buffer (31 downto 30); |
when 14 => barrel<= rot_buffer (14 downto 0) & rot_buffer (31 downto 31); |
when 15 => barrel<= rot_buffer (15 downto 0); |
when 16 => barrel<= rot_buffer (16 downto 1); |
when 17 => barrel<= rot_buffer (17 downto 2); |
when 18 => barrel<= rot_buffer (18 downto 3); |
when 19 => barrel<= rot_buffer (19 downto 4); |
when 20 => barrel<= rot_buffer (20 downto 5); |
when 21 => barrel<= rot_buffer (21 downto 6); |
when 22 => barrel<= rot_buffer (22 downto 7); |
when 23 => barrel<= rot_buffer (23 downto 8); |
when 24 => barrel<= rot_buffer (24 downto 9); |
when 25 => barrel<= rot_buffer (25 downto 10); |
when 26 => barrel<= rot_buffer (26 downto 11); |
when 27 => barrel<= rot_buffer (27 downto 12); |
when 28 => barrel<= rot_buffer (28 downto 13); |
when 29 => barrel<= rot_buffer (29 downto 14); |
when 30 => barrel<= rot_buffer (30 downto 15); |
when 31 => barrel<= rot_buffer (31 downto 16); |
when others => null; |
end case; |
end process; |
|
--preprocessing calculate the distance of different codelengths |
--this is parallel at the same periode detect codelength |
process(clk) |
begin |
if clk'event and clk='1' then |
h_delta(0)<="000000000000000"&(Barrel(15 downto 15)); |
h_delta(1)<=(Barrel(15 downto 14)- ("00000000000000"& huff_code_offset(to_integer(DC_AC_decode &"0001")) (0 downto 0)&'0')); |
h_delta(2)<=(Barrel(15 downto 13)- ("0000000000000"&huff_code_offset(to_integer(DC_AC_decode&"0010")) (1 downto 0) &'0')); |
h_delta(3)<=(Barrel(15 downto 12)- ("000000000000"&huff_code_offset(to_integer(DC_AC_decode &"0011")) (2 downto 0) &'0')); |
h_delta(4)<=(Barrel(15 downto 11)- ("00000000000"&huff_code_offset(to_integer(DC_AC_decode &"0100")) (3 downto 0) &'0')); |
h_delta(5)<=(Barrel(15 downto 10)- ("0000000000"&huff_code_offset(to_integer(DC_AC_decode &"0101")) (4 downto 0) &'0')); |
h_delta(6)<=(Barrel(15 downto 9)- ("000000000"&huff_code_offset(to_integer(DC_AC_decode &"0110")) (5 downto 0) &'0')); |
h_delta(7)<=(Barrel(15 downto 8) - ("00000000"&huff_code_offset(to_integer(DC_AC_decode &"0111")) (6 downto 0) &'0')); |
h_delta(8)<=(Barrel(15 downto 7) - ("0000000"&huff_code_offset(to_integer(DC_AC_decode &"1000")) (7 downto 0) &'0')); |
h_delta(9)<=(Barrel(15 downto 6) - ("000000"&huff_code_offset(to_integer(DC_AC_decode &"1001")) (8 downto 0) &'0')); |
h_delta(10)<=(Barrel(15 downto 5)- ("00000"&huff_code_offset(to_integer(DC_AC_decode &"1010")) (9 downto 0) &'0')); |
h_delta(11)<=(Barrel(15 downto 4)- ("0000"&huff_code_offset(to_integer(DC_AC_decode &"1011")) (10 downto 0) &'0')); |
h_delta(12)<=(Barrel(15 downto 3)- ("000"&huff_code_offset(to_integer(DC_AC_decode &"1100")) (11 downto 0) &'0')); |
h_delta(13)<=(Barrel(15 downto 2)- ("00"&huff_code_offset(to_integer(DC_AC_decode &"1101")) (12 downto 0) &'0')); |
h_delta(14)<=(Barrel(15 downto 1)- ("0"&huff_code_offset(to_integer(DC_AC_decode &"1110")) (13 downto 0) &'0')); |
h_delta(15)<=(Barrel(15 downto 0)- (huff_code_offset(to_integer(DC_AC_decode &"1111")) (14 downto 0) &'0')); |
end if; |
end process; |
|
process(clk) |
begin |
if clk'event and clk='1' then |
DC_AC_old(0)<=DC_AC_decode(0); |
if state=sos_scan then |
if DC_AC_decode(0)='0' and DC_AC_old(0)='1' then |
next_eob<='1'; |
else |
next_eob<='0'; |
end if; |
end if; |
end if; |
end process; |
------------------------------------------------------------------------------------------------------------------------- |
--code_word<=HUFF_RAM(to_integer(ram_pointer(DC_AC_decode,0,read_offset)+h_delta(read_offset)(8 downto 0))); |
|
ram_offset<=ram_pointer(to_integer(DC_AC_decode & to_unsigned(read_offset,4))); --begin the actual codeword table |
|
--recognise code word |
|
process(clk,write_active) |
begin |
if clk'event and clk='1' then |
read_offset<=read_offset_a; |
|
if state=sos_header then |
code_word<=to_unsigned(1,code_word'length); |
end if; |
|
if sos_state=catch then |
code_word<=HUFF_RAM(to_integer(ram_offset+h_delta(read_offset)(8 downto 0))); |
end if; |
end if; |
|
end process; |
|
read_offset_a<= |
0 when Barrel(15 downto 15)< huff_code_offset(to_integer(DC_AC_decode &"0001")) (0 downto 0) else |
1 when Barrel(15 downto 14)< huff_code_offset(to_integer(DC_AC_decode &"0010")) (1 downto 0) else |
2 when Barrel(15 downto 13)< huff_code_offset(to_integer(DC_AC_decode &"0011")) (2 downto 0) else |
3 when Barrel(15 downto 12)< huff_code_offset(to_integer(DC_AC_decode &"0100")) (3 downto 0) else |
4 when Barrel(15 downto 11)< huff_code_offset(to_integer(DC_AC_decode &"0101")) (4 downto 0) else |
5 when Barrel(15 downto 10)< huff_code_offset(to_integer(DC_AC_decode &"0110")) (5 downto 0) else |
6 when Barrel(15 downto 9)< huff_code_offset(to_integer(DC_AC_decode &"0111")) (6 downto 0) else |
7 when Barrel(15 downto 8)< huff_code_offset(to_integer(DC_AC_decode &"1000")) (7 downto 0) else |
8 when Barrel(15 downto 7)< huff_code_offset(to_integer(DC_AC_decode &"1001")) (8 downto 0) else |
9 when Barrel(15 downto 6)< huff_code_offset(to_integer(DC_AC_decode &"1010")) (9 downto 0) else |
10 when Barrel(15 downto 5)< huff_code_offset(to_integer(DC_AC_decode &"1011")) (10 downto 0) else |
11 when Barrel(15 downto 4)< huff_code_offset(to_integer(DC_AC_decode &"1100")) (11 downto 0) else |
12 when Barrel(15 downto 3)< huff_code_offset(to_integer(DC_AC_decode &"1101")) (12 downto 0) else |
13 when Barrel(15 downto 2)< huff_code_offset(to_integer(DC_AC_decode &"1110")) (13 downto 0) else |
14 when Barrel(15 downto 1) < huff_code_offset(to_integer(DC_AC_decode &"1111")) (14 downto 0) else |
15; |
|
shift<= |
1 when Barrel(15 downto 15)< huff_code_offset(to_integer(DC_AC_decode &"0001")) (0 downto 0) else |
2 when Barrel(15 downto 14)< huff_code_offset(to_integer(DC_AC_decode &"0010")) (1 downto 0) else |
3 when Barrel(15 downto 13)< huff_code_offset(to_integer(DC_AC_decode &"0011")) (2 downto 0) else |
4 when Barrel(15 downto 12)< huff_code_offset(to_integer(DC_AC_decode &"0100")) (3 downto 0) else |
5 when Barrel(15 downto 11)< huff_code_offset(to_integer(DC_AC_decode &"0101")) (4 downto 0) else |
6 when Barrel(15 downto 10)< huff_code_offset(to_integer(DC_AC_decode &"0110")) (5 downto 0) else |
7 when Barrel(15 downto 9)< huff_code_offset(to_integer(DC_AC_decode &"0111")) (6 downto 0) else |
8 when Barrel(15 downto 8)< huff_code_offset(to_integer(DC_AC_decode &"1000")) (7 downto 0) else |
9 when Barrel(15 downto 7)< huff_code_offset(to_integer(DC_AC_decode &"1001")) (8 downto 0) else |
10 when Barrel(15 downto 6)< huff_code_offset(to_integer(DC_AC_decode &"1010")) (9 downto 0) else |
11 when Barrel(15 downto 5)< huff_code_offset(to_integer(DC_AC_decode &"1011")) (10 downto 0) else |
12 when Barrel(15 downto 4)< huff_code_offset(to_integer(DC_AC_decode &"1100")) (11 downto 0) else |
13 when Barrel(15 downto 3)< huff_code_offset(to_integer(DC_AC_decode &"1101")) (12 downto 0) else |
14 when Barrel(15 downto 2)< huff_code_offset(to_integer(DC_AC_decode &"1110")) (13 downto 0) else |
15 when Barrel(15 downto 1) < huff_code_offset(to_integer(DC_AC_decode &"1111")) (14 downto 0) else |
16; |
|
|
--------------------------------------- |
process(clk,write_active) |
begin |
if clk'event and clk='1' then |
if sos_state=catch then |
ba<=barrel; |
end if; |
end if; |
end process; |
|
process(clk) |
begin |
|
if clk'event and clk='1' then |
if sos_state=decode then |
-- ba_1<=ba(15); --entscheide positiver Wert oder negativ 1 posiver Wert!!!!! |
|
if ba(15)='1' then |
case code_word(3 downto 0) is |
when X"0" => value<=X"0000"; |
when X"1" => value<=(0=>'1',others=>'0'); |
when X"2" => value<=(1=>'1',0=>ba(14),others=>'0'); |
when X"3" => value<=(2=>'1',1=>ba(14),0=>ba(13),others=>'0'); |
when X"4" => value<=(3=>'1',2=>ba(14),1=>ba(13),0=>ba(12),others=>'0'); |
when X"5" => value<=(4=>'1',3=>ba(14),2=>ba(13),1=>ba(12),0=>ba(11),others=>'0'); |
when X"6" => value<=(5=>'1',4=>ba(14),3=>ba(13),2=>ba(12),1=>ba(11),0=>ba(10),others=>'0'); |
when X"7" => value<=(6=>'1',5=>ba(14),4=>ba(13),3=>ba(12),2=>ba(11),1=>ba(10),0=>ba(9),others=>'0'); |
when others=>null; |
end case; |
else |
case code_word(3 downto 0) is |
when X"0" => value<=X"0000"; |
when X"1" => value<=to_signed(-1,16); |
when X"2" => value<="000000000000000"&ba(14)-3; |
when X"3" => value<="00000000000000"&ba(14)&ba(13)-7; |
when X"4" => value<="0000000000000"&ba(14)&ba(13)&ba(12)-15; |
when X"5" => value<="000000000000"&ba(14)&ba(13)&ba(12)&ba(11)-31; |
when X"6" => value<="00000000000"&ba(14)&ba(13)&ba(12)&ba(11)&ba(10)-63; |
when X"7" => value<="0000000000"&ba(14)&ba(13)&ba(12)&ba(11)&ba(10)&ba(9)-127; |
when others=>null; |
end case; |
|
|
end if; |
end if; |
end if; |
|
end process; |
|
-------------------------------------------------------------------------------------------- |
--Anzahl der Componenten lesen und welche Hufftabe genommen wird |
process (clk,write_active) |
begin |
if write_active='1' then |
if clk'event and clk='1' then |
if next_state=SOS_Header and state/=SOS_Header then |
SOS_number_comp<=input_reg(7 downto 0); |
SOS_Header_state<=selector; |
SOS_Header_index<=0; |
end if; |
|
if SOS_Header_Index < SOS_number_comp then |
if SOS_Header_state=selector then |
--SOS_selector<=input_reg(15 downto 7); |
SOS_header_state<=table; |
end if; |
if SOS_Header_state=table then |
SOS_comp_table(SOS_Header_index)<= input_reg(7 downto 0); |
|
SOS_header_state<=selector; |
SOS_Header_index<=SOS_Header_index+1; |
end if; |
end if; |
|
end if; |
end if; |
end process; |
-------------------------------------------------------------------------------------------- |
process(clk,write_active) |
begin |
if write_active='1' then |
if clk'event and clk='1' then |
if ((next_state=SOF0_length) or (next_state=DQT_length) or (next_state=DHT_length)or (next_state=SOS_length)) then |
Markerlength<=unsigned(input_reg(15 downto 0)); |
else |
Markerlength<=Markerlength-1; |
end if; |
end if; |
end if; |
end process; |
|
|
process(clk,write_active) --DQT read |
|
variable element: integer range 0 to 64:=0; |
variable destination: integer range 0 to 1; |
variable multible : integer range 0 to 1; |
begin |
if write_active='1' then |
if clk'event and clk='1' then |
if state=DQT_length0 then |
multible:=1; |
|
end if; |
if state=DQT_length then |
element:=64; --paralle wird Markerlength gesetzt |
|
end if; |
if state=DQT_active then |
if element=62 then |
if Markerlength<10 then -- Wenn mehrere Tabellen hintereinander hängen |
--der wert muss ausreichend gross sein 10 nur gewaehlt |
multible:=0; |
end if; |
end if; |
if (element=64 and multible=1) then |
|
destination:=to_integer(unsigned(input_reg (8 downto 8))); |
element:=0; |
|
end if; |
if element <64 then |
qtable(destination,zigzag(element))<=unsigned(input_reg(7 downto 0)); |
element:=element +1; |
end if; |
end if; |
end if; |
end if; |
end process; |
|
|
process(clk,write_active) |
begin |
|
if clk'event and clk='1' then |
if write_active='1' then |
input_reg (7 downto 0)<= data_in; |
input_reg (15 downto 8)<= input_reg(7 downto 0); |
input_reg (23 downto 16)<= input_reg (15 downto 8); |
end if; |
if eoi_detect(0)='1' then --else bit stuffing at 0xFFD9 !! |
input_reg (7 downto 0)<= X"00"; |
input_reg (15 downto 8)<= input_reg(7 downto 0); |
input_reg (23 downto 16)<= input_reg (15 downto 8); |
end if; |
end if; |
end process; |
|
|
state_machine: process(clk,write_active) |
begin |
|
|
|
if clk'event and clk='1' then |
if eoi_detect="11" and output_valid='1' then next_state<=EOI; |
end if; |
if (state=DHT_active and huff_table_end='1') then |
state<=DHT_destination; |
next_state<=DHT_number; |
dht_counter<=0; |
end if; |
if next_state=EOI then |
state<=EOI; |
end if; |
if write_active='1' then |
state<=next_state; |
case input_reg(15 downto 0) is |
when X"FFD8"=> next_state<=SOI; |
when x"FFE0"=> next_state<=APP0; |
when x"FFDB"=> next_state<=DQT_length0; |
when x"FFC0"=> next_state<=SOF0_length0; |
when x"FFC4"=> next_state<=DHT_length0; |
when x"FFDA"=> next_state<=SOS_length0; |
--when x"FFD9"=> eoi_detect(0)<='1'; |
when others => |
|
if next_state=DQT_length0 then next_state<=DQT_length; end if; |
if next_state=DQT_length then next_state<=DQT_active; end if; |
|
if next_state=SOF0_length0 then next_state<=SOF0_length; end if; |
if next_state=SOF0_length then next_state<=SOF0_precision; end if; |
if next_state=SOF0_precision then next_state<=SOF0_y_high; end if; |
if next_state=SOF0_y_high then next_state<=SOF0_y_low; end if; |
if next_state=SOF0_y_low then next_state<=SOF0_x_high; end if; |
if next_state=SOF0_x_high then next_state<=SOF0_x_low; end if; |
if next_state=SOF0_x_low then next_state<=SOF0_nr_comp; end if; |
if next_state=SOF0_nr_comp then next_state<=SOF0_active; end if; |
|
--SOS |
if next_state=SOS_length0 then next_state<=SOS_length; end if; |
if next_state=SOS_length then next_state<=SOS_header; end if; |
if next_state=SOS_header and markerlength=3 then --der scan hat keine Laengenmarke |
next_state<=SOS_init0; end if; |
if next_state=SOS_init0 then next_state<=SOS_init1; end if; |
if next_state=SOS_init1 then next_state<=SOS_init2; end if; |
if next_state=SOS_init2 then next_state<=SOS_init3; end if; |
if next_state=SOS_init3 then next_state<=SOS_scan; end if; |
|
--Hufftable |
if next_state=DHT_length0 then next_state<=DHT_length; end if; |
if next_state=DHT_length then next_state<=DHT_destination; end if; |
if next_state=DHT_destination then |
next_state<=DHT_Number; |
dht_counter<=0; |
end if; |
if next_state=DHT_Number then |
dht_counter<=dht_counter+1; |
end if; |
if next_state=DHT_Number and dht_counter=15 then |
next_state<=DHT_active; end if; |
--multible tables |
|
if next_state=DHT_active and Markerlength=2 then next_state<=idle; end if; |
end case; |
|
end if; |
end if; |
end process state_machine; |
|
-------------------------------------------------- |
--x_size,y_size:unsigned (15 downto 0); --picture size |
-------------------------------------------------- |
|
process(clk,write_active) --SOF0 einlesen |
|
begin |
if write_active='1' then |
if clk'event and clk='1' then |
if state=SOF0_y_high then |
y_size(15 downto 8) <= input_reg(15 downto 8); |
end if; |
if state=SOF0_y_low then |
y_size(7 downto 0) <= input_reg(15 downto 8); |
end if; |
if state=SOF0_x_high then |
x_size(15 downto 8) <= input_reg(15 downto 8); |
end if; |
if state=SOF0_x_low then |
x_size(7 downto 0) <= input_reg(15 downto 8); |
end if; |
if state=SOF0_nr_comp then |
SOF0_number_comp <= input_reg(15 downto 8); |
SOF0_Header_index<= 0; |
SOF0_header_state<=selector; |
end if; |
if SOF0_Header_Index < SOF0_number_comp then |
|
if SOF0_Header_state=selector then |
SOF0_Header_state<=Sampling; |
end if; |
if SOF0_Header_state=sampling then |
SOF0_comp_table(SOF0_Header_index)(15 downto 8)<=input_reg(15 downto 8); |
SOF0_Header_state<=table; |
end if; |
if SOF0_Header_state=table then |
SOF0_comp_table(SOF0_Header_index)(7 downto 0)<=input_reg(15 downto 8); |
SOF0_Header_state<=selector; |
SOF0_Header_index<=SOF0_Header_index+1; |
end if; |
end if; |
|
end if; |
end if; |
end process; |
---------------------------------------------------- |
process(clk,write_active) --Hufftable read |
variable dest:unsigned(1 downto 0); --destination |
variable DC_AC:unsigned(0 downto 0); --AC oder DC Table |
--'0' entspricht DC |
begin |
|
|
if clk'event and clk='1' then |
if wr='1' then |
if state=SOI then |
ADDR<=0; |
end if; |
if state=DHT_destination then |
index<=0; |
dest:=input_reg(9 downto 8);--0-1 Baseline |
DC_AC:=input_reg(12 downto 12); --0 DC / 1 AC |
|
end if; |
|
if state=DHT_Number then |
huff_table_end<='0'; |
huff_a<=to_unsigned(0,8); |
huff_code_number(index)<=input_reg(15 downto 8); |
h_code<=X"0000"; |
if index< 15 then |
index<=index+1; |
end if; |
if index=15 then |
index<=0; |
end if; |
end if; |
|
if state=DHT_active and huff_a>0 then |
huff_a<=huff_a-1; |
Huff_RAM(addr)<=input_reg(15 downto 8); |
addr<=addr+1; |
h_code<=h_code+1; |
end if; |
end if; |
--if next_state=DHT_active |
if state=DHT_active and huff_a=0 then |
huff_a<=huff_code_number(index); |
ram_pointer(to_integer(dest&DC_AC&to_unsigned(index,4)))<= addr; |
if index<15 then |
index<=index+1; |
h_code<=h_code (14 downto 0) &'0' ; --shift left |
|
huff_code_offset(to_integer(dest& DC_AC & to_unsigned(index,4)))<=h_code; |
end if; |
if index=15 then |
huff_table_end<='1'; |
end if; |
|
end if; |
end if; |
|
end process; |
huff_wr_en<='0' when ((huff_a=0 or huff_table_end='1')and (state=dht_active) and not (next_state=idle)) else '1'; |
|
|
--- syncronisation information |
-- sop.......... start of picture |
-- eop.......... end of picture |
process(clk) |
begin |
if clk'event and clk='1' then |
if state=sos_length then |
sop<='1'; |
else |
sop<='0'; |
end if; |
|
if state=EOI then |
eop<='1'; |
else |
eop<='0'; |
end if; |
end if; |
end process; |
|
end Behavioral; |
|
/jpeg.ghw
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
jpeg.ghw
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: jpeg_tb.vhd
===================================================================
--- jpeg_tb.vhd (nonexistent)
+++ jpeg_tb.vhd (revision 3)
@@ -0,0 +1,94 @@
+
+--------------------------------------------------------------------------------
+LIBRARY ieee;
+USE ieee.std_logic_1164.ALL;
+--USE ieee.std_logic_unsigned.all;
+USE ieee.numeric_std.ALL;
+ use work.jpeg_pack.all;
+
+ENTITY jpeg_tb IS
+END jpeg_tb;
+
+ARCHITECTURE behavior OF jpeg_tb IS
+
+ -- Component Declaration for the Unit Under Test (UUT)
+
+signal output_valid : std_logic:='0';
+signal data_out : signed (15 downto 0);
+signal sop,eop: std_logic;
+signal next_eob: std_logic;
+ --Inputs
+ signal clk : std_logic := '0';
+ signal zrl: unsigned (3 downto 0);
+ signal data_in : unsigned (7 downto 0);
+ signal wr : std_logic := '0';
+ --Outputs
+ --signal data_out : matrix_word;
+ signal wr_en : std_logic;
+
+ -- Clock period definitions
+ constant clk_period : time := 10 ns;
+
+subtype by_te is character;
+
+type f_byte is file of by_te;
+BEGIN
+
+process (wr_en,clk)
+--constant file_name: string:="test3.jpg";
+constant file_name: string:="test.jpg";
+file in_file: f_byte open read_mode is file_name;
+
+--variable in_line,out_line: line;
+variable good:boolean;
+variable a:character;
+
+begin
+--read(in_file,a);
+--data_in<=a;
+--wait until wr_en='1';
+--wait for 6 ns;
+--wr<='1';
+
+--when not endfile(in_file) loop
+if wr_en='0' then
+ --wr<='0';
+ elsif clk'event and clk='1' then
+ if not endfile (in_file) then
+ read(in_file,a);
+ end if;
+ data_in<=to_unsigned(character'pos(a),8);--very tricky the conversation
+ -- wr<='1';
+
+end if;
+end process;
+wr<='1' when wr_en='1' else'0';
+
+ clk_process :process
+ begin
+ clk <= '0';
+ wait for clk_period/2;
+ clk <= '1';
+ wait for clk_period/2;
+ end process;
+
+
+ -- Instantiate the Unit Under Test (UUT)
+ uut: entity work.huffman_decoder PORT MAP (
+
+ clk => clk,
+ next_eob=> next_eob,
+ zrl => zrl,
+ sop =>sop,
+ eop => eop,
+ output_valid=>output_valid,
+ data_out=>data_out,
+ wr => wr,
+ decoder_enable =>'1',
+ data_in => data_in,
+ wr_en=>wr_en
+ );
+
+
+
+END;
Index: Makefile
===================================================================
--- Makefile (nonexistent)
+++ Makefile (revision 3)
@@ -0,0 +1,26 @@
+###############################################################
+#
+# Purpose: Makefile for jpeg sniffer
+# Author.: Rene Doss (red)
+# Version: 0.1
+# License: Dossmatik GmbH
+#
+###############################################################
+
+
+
+
+all: huffman jpeg_tb
+ ghdl -e -Wa,--32 -Wl,-m32 jpeg_tb
+ ghdl -r jpeg_tb --stop-time=18000ns --wave=jpeg.ghw
+clean:
+ ghdl --clean
+
+
+
+huffman: huffman_decoder.vhd
+ ghdl -a -Wa,--32 huffman_decoder.vhd
+ ghdl -a -Wa,--32 jpeg_tb.vhd
+
+jpeg_tb: jpeg_tb.vhd j_main.vhd helpers.vhd
+ ghdl -a -Wa,--32 jpeg_tb.vhd
\ No newline at end of file