URL
https://opencores.org/ocsvn/huffmandecoder/huffmandecoder/trunk
Subversion Repositories huffmandecoder
[/] [huffmandecoder/] [trunk/] [huffman_decoder.vhd] - Rev 3
Compare with Previous | Blame | View Log
---------------------------------------------------------------------------------- -- 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;