X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=grlib-gpl-1.0.22-b4095%2Flib%2Fkuri%2Fmjpeg%2Fhuff.vhd.bak;fp=grlib-gpl-1.0.22-b4095%2Flib%2Fkuri%2Fmjpeg%2Fhuff.vhd.bak;h=39316f0c03b798d43de423d58e63db4cfcda8f50;hb=0f66c03430e5b64b8f5375e9434359025646d731;hp=0000000000000000000000000000000000000000;hpb=50c2ac50d71cc0904ff92bda30c4934adcdba5e9;p=fpga-leon-mjpeg%2Fleon-mjpeg.git diff --git a/grlib-gpl-1.0.22-b4095/lib/kuri/mjpeg/huff.vhd.bak b/grlib-gpl-1.0.22-b4095/lib/kuri/mjpeg/huff.vhd.bak new file mode 100644 index 00000000..39316f0c --- /dev/null +++ b/grlib-gpl-1.0.22-b4095/lib/kuri/mjpeg/huff.vhd.bak @@ -0,0 +1,1173 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library grlib; +use grlib.amba.all; +use grlib.stdlib.all; +use grlib.devices.all; + +library techmap; +use techmap.gencomp.all; + +library kuri; +use kuri.mjpeg.all; + +entity huff is + generic ( + memtech : integer := DEFMEMTECH; + shindex : integer := 0; + haddr : integer := 0; + hmask : integer := 16#fff#; + hirq : integer := 0; + pindex : integer := 0; + paddr : integer := 0; + pmask : integer := 16#fff#; + mhindex : integer := 0; + chprot : integer := 3); + port ( + rst : in std_ulogic; + clk : in std_ulogic; + ahbsi : in ahb_slv_in_type; + ahbso : out ahb_slv_out_type; + apbi : in apb_slv_in_type; + apbo : out apb_slv_out_type; + kready : in std_logic; + kstrobe : out std_logic; + kdata : out std_logic_vector(11 downto 0); + kaddress : out std_logic_vector(5 downto 0); + jpg_setting : out jpg_set_type; + error : in std_logic_vector(2 downto 0); + startgen : out std_logic; + kstrobeq : out std_logic; + kdataq : out std_logic_vector(7 downto 0); + kaddq : out std_logic_vector(7 downto 0); + krddataq : in std_logic_vector(7 downto 0); + krdq : out std_logic + ); +end; + +architecture rtl of huff is + +constant shconfig : ahb_config_type := ( + 0 => ahb_device_reg( VENDOR_CONTRIB, CONTRIB_CORE1, 0, 0, hirq), + 4 => ahb_membar(haddr, '0', '0', hmask), + others => zero32); + +constant pconfig : apb_config_type := ( + 0 => ahb_device_reg( VENDOR_CONTRIB, CONTRIB_CORE1, 0, 0, 0), + 1 => apb_iobar(paddr, pmask)); + +constant fdepth : integer := 512; + +constant const_4b4 : std_logic_vector(3 downto 0) := "0100"; +constant const_4b5 : std_logic_vector(3 downto 0) := "0101"; +constant const_4b6 : std_logic_vector(3 downto 0) := "0110"; +constant const_6b8 : std_logic_vector(5 downto 0) := "001000"; +constant const_u6b24 : UNSIGNED(5 downto 0) := "011000"; + +function sign_ex(data, bitnum : std_logic_vector) return std_logic_vector is + variable outb : std_logic_vector(11 downto 0); + variable minusjudge : std_logic; + variable tmp : integer; +begin + minusjudge := '0'; + if(bitnum = "0001")then + if(data(0) = '0')then + outb := "111111111111"; + else + outb := "000000000001"; + end if; + elsif(bitnum = "0010")then + if(data(1) = '0')then + tmp := to_integer(signed('1' & data(1 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(1 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "0011")then + if(data(2) = '0')then + tmp := to_integer(signed('1' & data(2 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(2 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "0100")then + if(data(3) = '0')then + tmp := to_integer(signed('1' & data(3 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(3 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "0101")then + if(data(4) = '0')then + tmp := to_integer(signed('1' & data(4 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(4 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "0110")then + if(data(5) = '0')then + tmp := to_integer(signed('1' & data(5 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(5 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "0111")then + if(data(6) = '0')then + tmp := to_integer(signed('1' & data(6 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(6 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "1000")then + if(data(7) = '0')then + tmp := to_integer(signed('1' & data(7 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(7 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "1001")then + if(data(8) = '0')then + tmp := to_integer(signed('1' & data(8 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(8 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "1010")then + if(data(9) = '0')then + tmp := to_integer(signed('1' & data(9 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(9 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; + elsif(bitnum = "1011")then + if(data(10) = '0')then + tmp := to_integer(signed('1' & data(10 downto 0))) + 1; + outb := std_logic_vector(to_signed(tmp, 12)); + else + tmp := to_integer(signed('0' & data(10 downto 0))); + outb := std_logic_vector(to_signed(tmp, 12)); + end if; +-- elsif(bitnum = "1100")then +-- if(data(11) = '0)then +-- tmp := to_integer(signed('1' & data(11 downto 0))) + 1; +-- outb := std_logic_vector(to_signed(tmp, 12)); +-- else +-- tmp := to_integer(signed('0' & data(11 downto 0))); +-- outb := std_logic_vector(to_signed(tmp, 12)); +-- end if; +-- elsif(bitnum ="0000")then +-- outb := (others => '0'); + else +-- report "sign extention over flow" severity note; + outb := (others => '0'); + end if; + + return(outb); +end; + +type fstate_type is (memwait, bytefetch, ffmemwait, ffcheck, markermode); +type dstate_type is (symreq, symcheck, valout, symng, symokvalng, serialwait, serialcheck, serialfinish, standby); + +type ahbs_reg is record + getscan : std_logic; + rdscan : std_logic; + getq : std_logic; + rdq : std_logic; + getcache : std_logic; + rdacache : std_logic; + rddcache : std_logic; + getmax : std_logic; + rdmax : std_logic; + getoffset : std_logic; + rdoffset : std_logic; + getval : std_logic; + rdval : std_logic; + hreadyff : std_logic; + hselff : std_logic; + haddkeep : std_logic_vector(15 downto 0); +-- hwriteff :std_logic; +end record; + +type apbs_reg is record + sampf : std_logic; + xmcumax : std_logic_vector(5 downto 0); + ymcumax : std_logic_vector(4 downto 0); + incaddy : std_logic_vector(15 downto 0); + incaddmcux : std_logic_vector(15 downto 0); + incaddmcuy : std_logic_vector(10 downto 0); + fbstartadd : std_logic_vector(31 downto 0); +-- error_reg : std_logic_vector(2 downto 0); + through_bit : std_logic; + hardonly : std_logic; +end record; + +type control_reg is record + fetch_state : fstate_type; + dec_state : dstate_type; + preg : apbs_reg; + hreg : ahbs_reg; + fifo_rp : std_logic_vector(8 downto 0); + fifo_wp : std_logic_vector(8 downto 0); + counter : std_logic_vector(1 downto 0); + fetch_reg : std_logic_vector(31 downto 0); + marker_reg : std_logic_vector(7 downto 0); + valuebit : std_logic_vector(5 downto 0); + byteselect : std_logic_vector(1 downto 0); + reqbit_keep : std_logic_vector(3 downto 0); + runlength_keep : std_logic_vector(3 downto 0); + valbit_keep : std_logic_vector(3 downto 0); + dcac : std_logic; + serial_counter : std_logic_vector(4 downto 0); + idcounter : std_logic_vector(3 downto 0); + memaddcnt : std_logic_vector(5 downto 0); + lastdc0 : std_logic_vector(11 downto 0); + lastdc1 : std_logic_vector(11 downto 0); + lastdc2 : std_logic_vector(11 downto 0); + byte3keep : std_logic_vector(23 downto 0); + cntdown : std_logic; + capture : std_logic_vector(1 downto 0); + skipcnt : std_logic_vector(15 downto 0); +end record; + +signal r, rin : control_reg; +signal read_en_fifo, write_en_fifo : std_logic; +signal read_pointer_fifo : std_logic_vector(8 downto 0); +signal write_pointer_fifo : std_logic_vector(8 downto 0); +signal data_out_fifo : std_logic_vector(31 downto 0); +signal data_in_fifo : std_logic_vector(31 downto 0); + +signal dccacheadd : std_logic_vector(9 downto 0); +signal dccachedin : std_logic_vector(7 downto 0); +signal dccachedout : std_logic_vector(7 downto 0); +signal dccacheen,dccachewr : std_logic; +signal accacheadd : std_logic_vector(9 downto 0); +signal accachedin : std_logic_vector(11 downto 0); +signal accachedout : std_logic_vector(11 downto 0); +signal accacheen,accachewr : std_logic; +signal sermaxadd : std_logic_vector(6 downto 0); +signal sermaxdin : std_logic_vector(16 downto 0); +signal sermaxdout : std_logic_vector(16 downto 0); +signal sermaxen,sermaxwr : std_logic; +signal seroffadd : std_logic_vector(6 downto 0); +signal seroffdin : std_logic_vector(16 downto 0); +signal seroffdout : std_logic_vector(16 downto 0); +signal seroffen,seroffwr : std_logic; +signal servaladd : std_logic_vector(9 downto 0); +signal servaldin : std_logic_vector(7 downto 0); +signal servaldout : std_logic_vector(7 downto 0); +signal servalen,servalwr : std_logic; + +signal debug_shiftnum : std_logic_vector(4 downto 0); +signal debug_sign_exin : std_logic_vector(10 downto 0); +signal debug_serialin : std_logic_vector(16 downto 0); +signal debug_vcache_symbit : std_logic_vector(4 downto 0); +signal debug_vcache_runlength : std_logic_vector(3 downto 0); +signal debug_vcache_valbit : std_logic_vector(3 downto 0); +signal debug_va : std_logic; +signal debug_fifoready : std_logic; + +begin + ramscan : syncram_2p generic map(tech => memtech, abits => 9, dbits => 32,sepclk => 0) + port map( clk, read_en_fifo, read_pointer_fifo, data_out_fifo, + clk, write_en_fifo, write_pointer_fifo, data_in_fifo); + huffdccache : syncram generic map(tech => memtech, abits => 10, dbits => 8) + port map( clk, dccacheadd, dccachedin, dccachedout, dccacheen, dccachewr); + huffaccache : syncram generic map(tech => memtech, abits => 10, dbits => 12) + port map( clk, accacheadd, accachedin, accachedout, accacheen, accachewr); + serialmax : syncram generic map(tech => memtech, abits => 7, dbits => 17) + port map( clk, sermaxadd, sermaxdin, sermaxdout, sermaxen, sermaxwr); + serialoffset : syncram generic map(tech => memtech, abits => 7, dbits => 17) + port map( clk, seroffadd, seroffdin, seroffdout, seroffen, seroffwr); + serialval : syncram generic map(tech => memtech, abits => 10, dbits => 8) + port map( clk, servaladd, servaldin, servaldout, servalen, servalwr); + + +comb_fetch : process(r, rst, ahbsi, apbi, data_out_fifo, dccachedout, accachedout, sermaxdout, seroffdout, servaldout, kready, error, krddataq) + variable v : control_reg; + variable virq : std_logic_vector(NAHBIRQ-1 downto 0); + variable vsready : std_logic; + variable write_point : integer; + variable read_point : integer; + variable num_ele : integer; + variable apbwrite : std_logic; + variable vprdata : std_logic_vector(31 downto 0); + variable vhrdata : std_logic_vector(31 downto 0); + variable vwriting :std_logic; + variable vreading : std_logic; + variable vdccacheadd : std_logic_vector(9 downto 0); + variable vdccachewr : std_logic; + variable vaccacheadd : std_logic_vector(9 downto 0); + variable vaccachewr : std_logic; + variable vsermaxadd : std_logic_vector(6 downto 0); + variable vsermaxwr : std_logic; + variable vseroffadd : std_logic_vector(6 downto 0); + variable vseroffwr : std_logic; + variable vservaladd : std_logic_vector(9 downto 0); + variable vservalwr : std_logic; + + variable vbytedata : std_logic_vector(7 downto 0); + variable vinsertdata : std_logic_vector(7 downto 0); + variable vbyte0, vbyte1, vbyte2, vbyte3 : std_logic_vector(7 downto 0); + variable vfetching : std_logic; + + variable vcache_symbit : std_logic_vector(4 downto 0); + variable vcache_runlength : std_logic_vector(3 downto 0); + variable vcache_valbit : std_logic_vector(3 downto 0); + + variable vint_plusv : integer; + variable vint_minusv : integer; + + variable vserial_symbit : std_logic_vector(4 downto 0); + variable vserial_runlength : std_logic_vector(3 downto 0); + variable vserial_valbit : std_logic_vector(3 downto 0); + variable vserial_tmpin : std_logic_vector(16 downto 0); + variable vserial_mask : std_logic_vector(16 downto 0); + variable vserial_judge : std_logic; + variable vserial_tmpadd : std_logic_vector(16 downto 0); + + variable vintshift : integer; + variable vshiftnum : std_logic_vector(4 downto 0); + variable vint_valuebit : integer; + variable vint_valbkp : integer; + variable vint_sercnt : integer; + variable vshiftout : std_logic_vector(15 downto 0); + variable vtmpshiftout : std_logic_vector(31 downto 0); + variable va : std_logic; + variable vid : std_logic; + variable vcompid : std_logic_vector(1 downto 0); + variable vkstrobe : std_logic; + variable vkdata : std_logic_vector(11 downto 0); + variable vint_csymbit : integer; + variable vint_reqbitkp : integer; + variable vint_cvalbit : integer; + variable vint_sersym : integer; + variable vint_serval : integer; + + variable vkaddq : std_logic_vector(7 downto 0); + variable vkrdq : std_logic; + variable vgetbyte : std_logic; + variable vstartgen : std_logic; + begin + + v := r; + virq := (others => '0'); + vdccachewr := '0'; vdccacheadd := (others => '0'); + vaccachewr := '0'; vaccacheadd := (others => '0'); + vsermaxwr := '0'; vsermaxadd := (others => '0'); + vseroffwr := '0'; vseroffadd := (others => '0'); + vservalwr := '0'; vservaladd := (others => '0'); + vkaddq := (others => '0'); vkrdq := '0'; + vserial_judge := '0'; + vkstrobe := '0'; vstartgen := '0'; + +-- apb controle part + apbwrite := apbi.psel(pindex) and apbi.pwrite and apbi.penable; + vprdata := (others => '0'); + case apbi.paddr(5 downto 2) is + when "0000" => + if apbwrite = '1' then + v.preg.fbstartadd := apbi.pwdata(31 downto 0); + end if; + vprdata := r.preg.fbstartadd(31 downto 0); + when "0001" => + if apbwrite = '1' then + v.preg.sampf := apbi.pwdata(22); + v.preg.ymcumax := apbi.pwdata(21 downto 17); + v.preg.xmcumax := apbi.pwdata(16 downto 11); + v.preg.incaddmcuy := apbi.pwdata(10 downto 0); + end if; + vprdata := "000000000" & r.preg.sampf & r.preg.ymcumax & r.preg.xmcumax & r.preg.incaddmcuy; + when "0010" => + if apbwrite = '1' then + v.preg.incaddy := apbi.pwdata(31 downto 16); + v.preg.incaddmcux := apbi.pwdata(15 downto 0); + end if; + vprdata := r.preg.incaddy & r.preg.incaddmcux; + when "0011" => + if apbwrite = '1' then + if apbi.pwdata(31) = '1' then + vstartgen := '1'; + end if; + v.preg.through_bit := apbi.pwdata(15); + v.preg.hardonly := apbi.pwdata(14); + v.marker_reg := apbi.pwdata(23 downto 16); + end if; + vprdata := "00000000" & r.marker_reg & r.preg.through_bit & r.preg.hardonly &"00000000000000" ; + when others => + end case; + +if(r.hreg.getcache = '1' or r.hreg.hreadyff = '0')then + if (r.hreg.haddkeep(15) = '1') then + vdccachewr := '1'; + vdccacheadd := r.hreg.haddkeep(11 downto 2); + else + vaccachewr := '1'; + vaccacheadd := r.hreg.haddkeep(11 downto 2); + end if; +else + vdccacheadd := ahbsi.haddr(11 downto 2); + vaccacheadd := ahbsi.haddr(11 downto 2); +end if; +if(r.hreg.getq = '1' or r.hreg.hreadyff = '0')then + vkaddq := r.hreg.haddkeep(9 downto 2); +else + vkaddq := ahbsi.haddr(9 downto 2); + vkrdq := '1'; +end if; +if(r.hreg.getmax = '1' or r.hreg.hreadyff = '0')then + vsermaxwr := '1'; + vsermaxadd := r.hreg.haddkeep(8 downto 2); +else + vsermaxadd := ahbsi.haddr(8 downto 2); +end if; +if(r.hreg.getoffset = '1' or r.hreg.hreadyff = '0')then + vseroffwr := '1'; + vseroffadd := r.hreg.haddkeep(8 downto 2); +else + vseroffadd := ahbsi.haddr(8 downto 2); +end if; +if(r.hreg.getval = '1' or r.hreg.hreadyff = '0')then + vservalwr := '1'; + vservaladd := r.hreg.haddkeep(11 downto 2); +else + vservaladd := ahbsi.haddr(11 downto 2); +end if; + +if(ahbsi.hready = '1' ) then + v.hreg.getscan := '0'; + v.hreg.rdscan := '0'; + v.hreg.getq := '0'; + v.hreg.rdq := '0'; + v.hreg.getcache := '0'; + v.hreg.rdacache := '0'; + v.hreg.rddcache := '0'; + v.hreg.getmax := '0'; + v.hreg.rdmax := '0'; + v.hreg.getoffset := '0'; + v.hreg.rdoffset := '0'; + v.hreg.getval := '0'; + v.hreg.rdval := '0'; + + v.hreg.hselff := ahbsi.hsel(shindex) and ahbsi.htrans(1); + vwriting := ahbsi.hwrite and v.hreg.hselff; + vreading := (not ahbsi.hwrite) and v.hreg.hselff; + if(ahbsi.haddr(19 downto 8) = "000000000000")then + if(vwriting = '1')then + v.hreg.getscan := '1'; + elsif(vreading = '1')then + v.hreg.rdscan := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 12) = "1100" )then + if(vwriting = '1')then + v.hreg.getq := '1'; + elsif(vreading = '1')then + v.hreg.rdq := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 12) = "0100" or ahbsi.haddr(15 downto 12) = "0101")then + if(vwriting = '1')then + v.hreg.getcache := '1'; + elsif(vreading = '1')then + v.hreg.rdacache := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 12) = "1000" or ahbsi.haddr(15 downto 12) = "1001")then + if(vwriting = '1')then + v.hreg.getcache := '1'; + elsif(vreading = '1')then + v.hreg.rddcache := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 10) = "000001")then + if(vwriting = '1')then + v.hreg.getmax := '1'; + elsif(vreading = '1')then + v.hreg.rdmax := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 10) = "000010")then + if(vwriting = '1')then + v.hreg.getoffset := '1'; + elsif(vreading = '1')then + v.hreg.rdoffset := '1'; + end if; + end if; + if(ahbsi.haddr(15 downto 13) = "001")then + if(vwriting = '1')then + v.hreg.getval := '1'; + elsif(vreading = '1')then + v.hreg.rdval := '1'; + end if; + end if; + v.hreg.haddkeep := ahbsi.haddr(15 downto 0); +end if; + +if( v.hreg.getscan = '1' or v.hreg.getq = '1' or v.hreg.getcache = '1' + or v.hreg.getmax = '1' or v.hreg.getoffset = '1' or v.hreg.getval = '1')then + v.hreg.hreadyff := not(v.hreg.hselff and not ahbsi.hwrite); + v.hreg.getscan := v.hreg.getscan and v.hreg.hreadyff; + v.hreg.getq := v.hreg.getq and v.hreg.hreadyff; + v.hreg.getcache := v.hreg.getcache and v.hreg.hreadyff; + v.hreg.getmax := v.hreg.getmax and v.hreg.hreadyff; + v.hreg.getoffset := v.hreg.getoffset and v.hreg.hreadyff; + v.hreg.getval := v.hreg.getval and v.hreg.hreadyff; +end if; + +-- FIFO # of element calculation + write_point := to_integer(unsigned(r.fifo_wp)); + read_point := to_integer(unsigned(r.fifo_rp)); + if (write_point >= read_point) then + num_ele := write_point - read_point; + else + num_ele := fdepth - read_point + write_point; + end if; + if num_ele > fdepth/2 then + vsready := '0'; + else + vsready := '1'; + end if; + debug_fifoready <= vsready; + + vhrdata := vsready & "0000000000000000000000000000000"; + if(r.hreg.rdscan = '1')then + vhrdata := data_out_fifo; + elsif(r.hreg.rdq ='1')then + vhrdata := "000000000000000000000000" &krddataq; + elsif(r.hreg.rdacache = '1')then + vhrdata := "00000000000000000000" & accachedout; + elsif(r.hreg.rddcache = '1')then + vhrdata := "000000000000000000000000" & dccachedout; + elsif(r.hreg.rdmax = '1')then + vhrdata := "000000000000000" & sermaxdout; + elsif(r.hreg.rdoffset = '1')then + vhrdata := "000000000000000" & seroffdout; + elsif(r.hreg.rdval = '1')then + vhrdata := "000000000000000000000000" & servaldout; + end if; + +--FIFO writing + if r.hreg.getscan = '1' then + write_point := write_point + 1; + if write_point = fdepth then + write_point := 0; + end if; + end if; + v.fifo_wp := std_logic_vector(to_unsigned(write_point,9)); + +--FIFO reading + if((r.fetch_state = bytefetch and r.byteselect = "00" and num_ele >= 1 and unsigned(r.valuebit)<= const_u6b24) + or (r.fetch_state = ffcheck and r.byteselect = "00" and num_ele >= 1 and unsigned(r.valuebit)<= const_u6b24)) then + read_point := read_point + 1; + if read_point = fdepth then + read_point := 0; + end if; + v.byte3keep(23 downto 0) := data_out_fifo(23 downto 0); + end if; + v.fifo_rp := std_logic_vector(to_unsigned(read_point,9)); + +-- byte select from FIFO output + if(r.byteselect = "00") then + vbytedata := data_out_fifo(31 downto 24); + elsif(r.byteselect = "01") then + vbytedata := r.byte3keep(23 downto 16); + elsif(r.byteselect = "10") then + vbytedata := r.byte3keep(15 downto 8); + else + vbytedata := r.byte3keep(7 downto 0); + end if; + + vgetbyte := '0'; + if((r.fetch_state = bytefetch and unsigned(r.valuebit) <= const_u6b24 ) + or (r.fetch_state = ffcheck and unsigned(r.valuebit) <= const_u6b24))then + v.byteselect := v.byteselect + 1; + vgetbyte := '1'; + end if; + +--data FF + if(r.fetch_state = ffcheck) then + vinsertdata := "11111111"; + else + vinsertdata := vbytedata; + end if; + +-- byte fetching to 32bit fetch_register + if( (r.fetch_state = bytefetch and vbytedata /= "11111111" and unsigned(r.valuebit) <= const_u6b24 and r.preg.through_bit = '0' ) + or (r.fetch_state = ffcheck and vbytedata = "00000000" and unsigned(r.valuebit) <= const_u6b24 and r.preg.through_bit = '0')) then + vfetching := '1'; + else + vfetching := '0'; + end if; + + if(vfetching = '1') then + vbyte0 := vinsertdata; + vbyte1 := r.fetch_reg(7 downto 0); + vbyte2 := r.fetch_reg(15 downto 8); + vbyte3 := r.fetch_reg(23 downto 16); + else + vbyte0 := r.fetch_reg(7 downto 0); + vbyte1 := r.fetch_reg(15 downto 8); + vbyte2 := r.fetch_reg(23 downto 16); + vbyte3 := r.fetch_reg(31 downto 24); + end if; + v.fetch_reg := vbyte3 & vbyte2 & vbyte1 & vbyte0; + +-- Marker register + if(r.fetch_state = ffcheck and vbytedata /= "00000000" and r.preg.through_bit = '0') then + v.marker_reg := vbytedata; + end if; + if(r.marker_reg /= "00000000")then + virq(hirq) := '1'; + end if; + +-- Through bit & skip counter calculation + if(r.fetch_state = ffcheck and r.preg.through_bit = '1' and vbytedata = "11011010")then + v.cntdown := '1'; + v.capture := "10"; + end if; + if(r.capture = "10")then + v.skipcnt(15 downto 8) := vbytedata; + end if; + if(r.capture = "01")then + v.skipcnt(7 downto 0) := vbytedata; + end if; + if(r.cntdown = '1' and vgetbyte = '1')then + if(r.capture = "10")then + v.capture := "01"; + end if; + if(r.capture = "01")then + v.capture := "00"; + end if; + if(r.capture = "00")then + v.skipcnt := r.skipcnt - 1; + end if; + if(r.skipcnt = "0000000000000011")then + v.preg.through_bit := '0'; + v.cntdown := '0'; + v.skipcnt := (others => '0'); + end if; + end if; +-- State machine transition (fetch part) + case r.fetch_state is + when memwait => + if (num_ele /= 0 and unsigned(r.valuebit) <= const_u6b24) then + v.fetch_state := bytefetch; + end if; + when bytefetch => + if(r.byteselect = "11" and unsigned(r.valuebit) <= const_u6b24 and num_ele = 0 and vbytedata /= "11111111") then + v.fetch_state := memwait; + elsif( vbytedata = "11111111" and r.byteselect = "11" and num_ele = 0 and unsigned(r.valuebit) <= const_u6b24) then + v.fetch_state := ffmemwait; + elsif( vbytedata = "11111111" and unsigned(r.valuebit) <= const_u6b24 and (r.byteselect /= "11" or (r.byteselect = "11" and num_ele /= 0))) then + v.fetch_state := ffcheck; + end if; + when ffmemwait => + if(num_ele /= 0) then + v.fetch_state := ffcheck; + end if; + when ffcheck => + if( (vbytedata = "00000000" and unsigned(r.valuebit) <=const_u6b24 and (r.byteselect /= "11" or num_ele /= 0)) + or (r.preg.through_bit = '1' and unsigned(r.valuebit)<=const_u6b24 and (r.byteselect /= "11" or num_ele /= 0) )) then + v.fetch_state := bytefetch; + elsif( (vbytedata = "00000000" and unsigned(r.valuebit)<=const_u6b24 and (r.byteselect = "11" and num_ele = 0)) + or( r.preg.through_bit = '1' and unsigned(r.valuebit)<=const_u6b24 and r.byteselect = "11" and num_ele = 0 )) then + v.fetch_state := memwait; + elsif ( vbytedata /= "00000000") then + v.fetch_state := markermode; + end if; + when markermode => + if(r.marker_reg = "00000000" and (r.byteselect /= "11" or( r.byteselect = "11" and num_ele /= 0))) then + v.fetch_state := bytefetch; + elsif(r.marker_reg = "00000000" and (r.byteselect = "11" and num_ele =0)) then + v.fetch_state := memwait; + end if; + if(r.preg.hardonly = '1' and r.marker_reg = x"D9")then + if(r.byteselect /= "11" or( r.byteselect = "11" and num_ele /= 0))then + v.marker_reg := "00000000"; + v.preg.through_bit := '1'; + elsif(r.byteselect = "11" and num_ele =0)then + v.marker_reg := "00000000"; + v.preg.through_bit := '1'; + end if; + end if; + when others => + end case; + + -- cache, serial mem output + if(r.dcac = '1') then + vcache_symbit := "0" & dccachedout(7 downto 4); + vcache_valbit := dccachedout(3 downto 0); + vcache_runlength := "0000"; + else + vcache_symbit := "0" & accachedout(11 downto 8); + vcache_runlength := accachedout(7 downto 4); + vcache_valbit := accachedout(3 downto 0); + end if; + vserial_symbit := r.serial_counter - "00010"; + vserial_runlength := servaldout(7 downto 4); + vserial_valbit := servaldout(3 downto 0); + + -- valuebit calculation + if(vfetching = '1') then + vint_plusv := 8; + else + vint_plusv := 0; + end if; + if(r.dec_state = symcheck) then + if(unsigned(r.reqbit_keep) >= unsigned(vcache_symbit) )then + vint_minusv := to_integer(unsigned(vcache_symbit)); + else + vint_minusv := 0; + end if; + elsif(r.dec_state = serialfinish) then + vint_minusv := to_integer(unsigned(vserial_symbit)); + elsif(r.dec_state = valout) then + vint_minusv := to_integer(unsigned(r.valbit_keep)); + else + vint_minusv := 0; + end if; + + v.valuebit := std_logic_vector(to_unsigned((to_integer(unsigned(r.valuebit)) + vint_plusv - vint_minusv), 6)); + if(r.fetch_state = markermode or r.preg.through_bit = '1') then + if((r.valuebit = "000001" and r.fetch_reg(0) = '1') + or (r.valuebit = "000010" and r.fetch_reg(1 downto 0) = "11") + or (r.valuebit = "000011" and r.fetch_reg(2 downto 0) = "111") + or (r.valuebit = "000100" and r.fetch_reg(3 downto 0) = "1111") + or (r.valuebit = "000101" and r.fetch_reg(4 downto 0) = "11111") + or (r.valuebit = "000110" and r.fetch_reg(5 downto 0) = "111111") + or (r.valuebit = "000111" and r.fetch_reg(6 downto 0) = "1111111")) then + v.valuebit := "000000"; + end if; + end if; + if(r.dec_state = symreq)then + if(r.valuebit >= const_6b8)then + v.reqbit_keep := "1000"; + else + v.reqbit_keep := r.valuebit(3 downto 0); + end if; + end if; + + -- runlength_keep valbit_keep register calculation + if(r.dec_state = serialfinish)then + v.runlength_keep := vserial_runlength; + v.valbit_keep := vserial_valbit; + elsif(r.dec_state = symcheck)then + v.runlength_keep := vcache_runlength; + v.valbit_keep := vcache_valbit; + end if; + + -- shiftnum calculation + + vint_valuebit := to_integer(unsigned(r.valuebit)); + vint_valbkp := to_integer(unsigned(r.valbit_keep)); + vint_sercnt := to_integer(unsigned(r.serial_counter)); + vintshift := 0; + + if(r.dec_state = symreq)then + if(vint_valuebit >= 8)then + vintshift := vint_valuebit - 8; + else + vintshift := 0; + end if; + elsif(r.dec_state = valout)then + vintshift := vint_valuebit - vint_valbkp; + elsif(r.dec_state = serialcheck)then + vintshift := 1 + vint_valuebit - vint_sercnt; + elsif(r.dec_state = serialwait)then + vintshift := 1 + vint_valuebit - vint_sercnt; + end if; + vshiftnum := std_logic_vector(to_unsigned(vintshift,5)); +-- shifter instantiation +debug_shiftnum <= vshiftnum; + vtmpshiftout := std_logic_vector(shift_right(unsigned(r.fetch_reg), vintshift)); + vshiftout := vtmpshiftout(15 downto 0); +-- write memory address generation + if (r.dec_state = symcheck and unsigned(vcache_symbit) <= unsigned(r.valuebit) and vcache_symbit /= "00000")then + va := '1'; + else + va := '0'; + end if; +debug_va <= va; +debug_vcache_symbit <= vcache_symbit; +debug_vcache_runlength <= vcache_runlength; +debug_vcache_valbit <= vcache_valbit; + +-- if((va = '1' or r.dec_state = serialfinish) and r.memaddcnt = "111111")then + if(r.dcac = '1')then + v.memaddcnt := "000000"; + elsif((va = '1' and vcache_runlength = "0000" and vcache_valbit = "0000") + or (r.dec_state = serialfinish and vserial_runlength = "0000" and vserial_valbit = "0000")) then + v.memaddcnt := "111111"; + elsif(va = '1')then + v.memaddcnt := r.memaddcnt + vcache_runlength + "0001"; + elsif(r.dec_state = serialfinish)then + v.memaddcnt := r.memaddcnt + vserial_runlength + "0001"; + end if; + +-- id, dcac calculation + if(r.dec_state = valout and r.memaddcnt = "000000")then + v.dcac := '0'; + elsif(r.dec_state = valout and r.memaddcnt = "111111") then + v.dcac := '1'; + end if; + + if(r.dec_state = valout and r.memaddcnt = "111111") then + v.idcounter := r.idcounter + '1'; + if(r.preg.sampf = '0')then + if(v.idcounter = "0110")then + v.idcounter := "0000"; + end if; + else + if(v.idcounter = "1000")then + v.idcounter := "0000"; + end if; + end if; + end if; + if(r.preg.sampf = '0')then + if(r.idcounter < const_4b4 )then + vid := '0'; + vcompid := "00"; + elsif(r.idcounter < const_4b5)then + vid := '1'; + vcompid := "01"; + else + vid := '1'; + vcompid := "10"; + end if; + else + if(r.idcounter < const_4b4)then + vid := '0'; + vcompid := "00"; + elsif(r.idcounter < const_4b6)then + vid := '1'; + vcompid := "01"; + else + vid := '1'; + vcompid := "10"; + end if; + end if; + +-- cache access + if(r.dec_state = symreq)then + if(r.dcac = '1')then + if(vint_valuebit >7)then + vdccacheadd := vid & '0' & vshiftout(7 downto 0); + elsif(vint_valuebit = 7)then + vdccacheadd := vid & "10" & vshiftout(6 downto 0); + elsif(vint_valuebit = 6)then + vdccacheadd := vid & "110" & vshiftout(5 downto 0); + elsif(vint_valuebit = 5)then + vdccacheadd := vid & "1110" & vshiftout(4 downto 0); + elsif(vint_valuebit = 4)then + vdccacheadd := vid & "11110" & vshiftout(3 downto 0); + elsif(vint_valuebit = 3)then + vdccacheadd := vid & "111110" & vshiftout(2 downto 0); + elsif(vint_valuebit = 2)then + vdccacheadd := vid & "1111110" & vshiftout(1 downto 0); + elsif(vint_valuebit = 1)then + vdccacheadd := vid & "11111110" & vshiftout(0); + end if; + vdccachewr := '0'; + else + if(vint_valuebit >7)then + vaccacheadd := vid & '0' & vshiftout(7 downto 0); + elsif(vint_valuebit = 7)then + vaccacheadd := vid & "10" & vshiftout(6 downto 0); + elsif(vint_valuebit = 6)then + vaccacheadd := vid & "110" & vshiftout(5 downto 0); + elsif(vint_valuebit = 5)then + vaccacheadd := vid & "1110" & vshiftout(4 downto 0); + elsif(vint_valuebit = 4)then + vaccacheadd := vid & "11110" & vshiftout(3 downto 0); + elsif(vint_valuebit = 3)then + vaccacheadd := vid & "111110" & vshiftout(2 downto 0); + elsif(vint_valuebit = 2)then + vaccacheadd := vid & "1111110" & vshiftout(1 downto 0); + elsif(vint_valuebit = 1)then + vaccacheadd := vid & "11111110" & vshiftout(0); + end if; + vaccachewr := '0'; + end if; + end if; + + -- Serial Part + vserial_mask := "00000000000000000"; + if(r.serial_counter = "01001")then + vserial_mask := "00000000011111111"; + elsif(r.serial_counter = "01010")then + vserial_mask := "00000000111111111"; + elsif(r.serial_counter = "01011")then + vserial_mask := "00000001111111111"; + elsif(r.serial_counter = "01100")then + vserial_mask := "00000011111111111"; + elsif(r.serial_counter = "01101")then + vserial_mask := "00000111111111111"; + elsif(r.serial_counter = "01110")then + vserial_mask := "00001111111111111"; + elsif(r.serial_counter = "01111")then + vserial_mask := "00011111111111111"; + elsif(r.serial_counter = "10000")then + vserial_mask := "00111111111111111"; + elsif(r.serial_counter = "10001")then + vserial_mask := "01111111111111111"; + end if; + vserial_tmpin := ('0' & vshiftout) and vserial_mask; + debug_serialin <= vserial_tmpin; + if(r.dec_state = symcheck or r.dec_state = serialcheck or r.dec_state = serialwait or r.dec_state = serialfinish)then + vsermaxadd := r.dcac & vid & r.serial_counter; + end if; + + if(r.dec_state = symcheck or r.dec_state = serialcheck or r.dec_state = serialwait or r.dec_state = serialfinish)then + vseroffadd := r.dcac & vid & r.serial_counter; + end if; + + if(signed(vserial_tmpin) <= to_01(signed(sermaxdout)))then + vserial_judge := '1'; + end if; + vserial_tmpadd := std_logic_vector(signed(vserial_tmpin) + signed(seroffdout)); + if(r.dec_state = serialcheck or r.dec_state = serialwait or r.dec_state = serialfinish)then + vservaladd := r.dcac & vid & vserial_tmpadd(7 downto 0); + end if; + if(r.dec_state = serialwait or r.dec_state = serialcheck or r.dec_state = serialfinish)then + vservalwr := '0'; + end if; + + if(r.dec_state = symreq)then + v.serial_counter := "01001"; + elsif((r.dec_state = symcheck and vint_valuebit > 8) + or (r.dec_state = serialcheck and to_integer(unsigned(r.serial_counter))<= vint_valuebit) + or (r.dec_state = serialwait and to_integer(unsigned(r.serial_counter))<= vint_valuebit )) + or (r.dec_state = serialcheck and vserial_judge = '1')then + v.serial_counter := r.serial_counter + 1; + end if; + -- Sign extention & zigzag memory access + debug_sign_exin <= vshiftout(10 downto 0); + vkdata := sign_ex(vshiftout(10 downto 0), r.valbit_keep ); + if(r.dec_state = valout and r.dcac = '1')then + if(vcompid = "00")then + vkdata := std_logic_vector(signed(vkdata) + signed(r.lastdc0)); + v.lastdc0 := vkdata; + elsif(vcompid = "01")then + vkdata := std_logic_vector(signed(vkdata) + signed(r.lastdc1)); + v.lastdc1 := vkdata; + else + vkdata := std_logic_vector(signed(vkdata) + signed(r.lastdc2)); + v.lastdc2 := vkdata; + end if; + end if; + if(r.dec_state = valout)then + vkstrobe := '1'; + else + vkstrobe := '0'; + end if; + +if(vstartgen = '1' or r.marker_reg = x"D9")then + v.lastdc0 := (others => '0'); + v.lastdc1 := (others => '0'); + v.lastdc2 := (others => '0'); +end if; + +-- Decord part state-machine +-- state = symreq, symcheck, valout, symng, symokvalng, serialwait, serialcheck, serialfinish, standby + vint_csymbit := to_integer(unsigned(vcache_symbit)); + vint_reqbitkp := to_integer(unsigned(r.reqbit_keep)); + vint_cvalbit := to_integer(unsigned(vcache_valbit)); + vint_sersym := to_integer(unsigned(vserial_symbit)); + vint_serval := to_integer(unsigned(vserial_valbit)); + + case r.dec_state is + when standby => + if(kready = '1' and r.valuebit /= "000000")then + v.dec_state := symreq; + end if; + when symreq => + if(r.valuebit = "000000")then + v.dec_state := symreq; + else + v.dec_state := symcheck; + end if; + when symcheck => + if(vint_csymbit /= 0 and vint_csymbit <= vint_reqbitkp and vint_csymbit + vint_cvalbit <= vint_valuebit )then + v.dec_state := valout; + elsif(vint_csymbit /= 0 and vint_csymbit <= vint_reqbitkp and vint_csymbit + vint_cvalbit > vint_valuebit )then + v.dec_state := symokvalng; + elsif(vint_reqbitkp = 8 and vint_csymbit = 0 and vint_valuebit >= 9)then + v.dec_state := serialcheck; + elsif(vint_reqbitkp = 8 and vint_csymbit = 0 and vint_valuebit < 9)then + v.dec_state := serialwait; + elsif(vint_reqbitkp < 8 and (vint_csymbit = 0 or vint_csymbit > vint_reqbitkp))then + v.dec_state := symng; + end if; + when symng => + if(vint_reqbitkp = vint_valuebit)then + v.dec_state := symng; + else + v.dec_state := symreq; + end if; + when valout => + if(r.memaddcnt = "111111")then + v.dec_state := standby; + else + v.dec_state := symreq; + end if; + when symokvalng => + if(vint_valbkp <= vint_valuebit)then + v.dec_state := valout; + else + v.dec_state := symokvalng; + end if; + when serialwait => + if(vint_sercnt > vint_valuebit) then + v.dec_state := serialwait; + else + v.dec_state := serialcheck; + end if; + when serialcheck => + if(vserial_judge = '1')then + v.dec_state := serialfinish; + elsif(vint_sercnt > vint_valuebit)then + v.dec_state := serialwait; + else + v.dec_state := serialcheck; + end if; + when serialfinish => + if(vint_valuebit < vint_sersym + vint_serval)then + v.dec_state := symokvalng; + else + v.dec_state := valout; + end if; + when others => + end case; + +-- reset part + if rst = '0' then + v.hreg.getscan := '0'; + v.hreg.rdscan := '0'; + v.hreg.getq := '0'; + v.hreg.rdq := '0'; + v.hreg.getcache := '0'; + v.hreg.rdacache := '0'; + v.hreg.rddcache := '0'; + v.hreg.haddkeep := (others => '0'); + v.hreg.getmax := '0'; + v.hreg.rdmax := '0'; + v.hreg.getoffset := '0'; + v.hreg.rdoffset := '0'; + v.hreg.getval := '0'; + v.hreg.rdval := '0'; + v.preg.sampf := '0'; + v.preg.xmcumax := (others => '0'); + v.preg.ymcumax := (others => '0'); + v.preg.incaddy := (others => '0'); + v.preg.incaddmcux := (others => '0'); + v.preg.incaddmcuy := (others => '0'); + v.preg.fbstartadd := (others => '0'); + v.preg.through_bit := '0'; + v.fetch_state := memwait; + v.dec_state := standby; + v.fifo_rp := (others => '0'); + v.fifo_wp := (others => '0'); + v.counter := (others => '0'); + v.fetch_reg := (others => '0'); + v.marker_reg := (others => '0'); + v.valuebit := (others => '0'); + v.byteselect := (others => '0'); + v.reqbit_keep := (others => '0'); + v.runlength_keep := (others => '0'); + v.valbit_keep := (others => '0'); + v.dcac := '1'; + v.serial_counter := (others => '0'); + v.idcounter := (others => '0'); + v.memaddcnt := (others => '0'); + v.lastdc0 := (others => '0'); + v.lastdc1 := (others => '0'); + v.lastdc2 := (others => '0'); + v.byte3keep := (others => '0'); + v.cntdown := '0'; + v.capture := "00"; + v.skipcnt := (others => '0'); + end if; + +-- signals + rin <= v; + write_en_fifo <= r.hreg.getscan; + write_pointer_fifo <= r.fifo_wp; + data_in_fifo <= ahbsi.hwdata; + read_en_fifo <= '1'; + read_pointer_fifo <= r.fifo_rp; + + dccachedin <= ahbsi.hwdata(7 downto 0); + dccacheadd <= vdccacheadd; + dccacheen <= '1'; + dccachewr <= vdccachewr; + accachedin <= ahbsi.hwdata(11 downto 0); + accacheadd <= vaccacheadd; + accacheen <= '1'; + accachewr <= vaccachewr; + sermaxdin <= ahbsi.hwdata(16 downto 0); + sermaxadd <= vsermaxadd; + sermaxen <= '1'; + sermaxwr <= vsermaxwr; + seroffdin <= ahbsi.hwdata(16 downto 0); + seroffadd <= vseroffadd; + seroffen <= '1'; + seroffwr <= vseroffwr; + seroffdin <= ahbsi.hwdata(16 downto 0); + servaladd <= vservaladd; + servalen <= '1'; + servalwr <= vservalwr; + servaldin <= ahbsi.hwdata(7 downto 0); + + jpg_setting.xmcumax <= r.preg.xmcumax; + jpg_setting.ymcumax <= r.preg.ymcumax; + jpg_setting.incaddy <= r.preg.incaddy; + jpg_setting.incaddmcux <= r.preg.incaddmcux; + jpg_setting.incaddmcuy <= r.preg.incaddmcuy; + jpg_setting.fbstartadd <= r.preg.fbstartadd; + startgen <= vstartgen; + jpg_setting.samp_fact <= r.preg.sampf; + + kstrobeq <= r.hreg.getq; + kdataq <= ahbsi.hwdata(7 downto 0); + + apbo.prdata <= vprdata; + ahbso.hirq <= virq; + ahbso.hrdata <= vhrdata; + + kdata <= vkdata; + kstrobe <= vkstrobe; + kaddress <= r.memaddcnt; + kaddq <= vkaddq; + krdq <= vkrdq; + end process; + + apbo.pirq <= (others => '0'); + apbo.pindex <= pindex; + apbo.pconfig <= pconfig; + ahbso.hconfig <= shconfig; + ahbso.hresp <= "00"; + ahbso.hsplit <= (others => '0'); + ahbso.hcache <= '0'; + ahbso.hready <= '1'; + ahbso.hindex <= shindex; + + -- registers + reg : process(clk) + begin + if rising_edge(clk) then + r <= rin; + end if; + end process; + +end;