------------------------------------------------------------------------------
--  Copyright (C) 2011, Kenichi Kurimoto
--
--  This program is free software; you can redistribute it and/or modify
--  it under the terms of the GNU General Public License as published by
--  the Free Software Foundation; either version 2 of the License, or
--  (at your option) any later version.
--
--  This program is distributed in the hope that it will be useful,
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--  GNU General Public License for more details.
--
--  You should have received a copy of the GNU General Public License
--  along with this program; if not, write to the Free Software
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
-----------------------------------------------------------------------------
-- Entity:      huffdctycc
-- File:        huffdctycc.vhd
-- Author:      Kenichi Kurimoto 
-- Description: huffman decoder,2D-DCT,upsample,and YCbCr-RGB translation
--                    for jpeg decode
------------------------------------------------------------------------------




library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.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 huffdctycc 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;
      ahbmi : in ahb_mst_in_type;
      ahbmo : out ahb_mst_out_type;
      ahbsi : in ahb_slv_in_type;
      ahbso : out ahb_slv_out_type;
      apbi  : in apb_slv_in_type;
      apbo  : out apb_slv_out_type;
      logan_sig : out std_logic_vector(31 downto 0)
   );
end;

architecture rtl of huffdctycc is

signal kready1, kready2, kready3, kready4, kready5, kready6, 
       kstrobe1, kstrobeq, kstrobe2, kstrobe3, kstrobe4, kstrobe5, kstrobe6: std_logic;
signal kdata1 : std_logic_vector(11 downto 0);
signal kaddress1 : std_logic_vector(5 downto 0);
signal kdata2 : std_logic_vector(11 downto 0);
signal kdataq1 : std_logic_vector(7 downto 0);
signal kdataq2 : std_logic_vector(7 downto 0);
signal kdata3 : std_logic_vector(15 downto 0);
signal kdata4 : std_logic_vector(15 downto 0);
signal kdata5 : std_logic_vector(7 downto 0);
signal kdata6 : std_logic_vector(23 downto 0);
signal error : std_logic_vector(2 downto 0);
signal jpg_setting : jpg_set_type;
signal startgen : std_logic;
signal kaddq : std_logic_vector(7 downto 0);
signal krdq : std_logic;
signal krddataq : std_logic_vector(7 downto 0);

signal count_r, count_rin :std_logic_vector(31 downto 0);

signal logan_sig2 : std_logic_vector(31 downto 0);

-- pragma translate_off
file out_file1 : text open write_mode is "aft_huff.txt";
file out_file2 : text open write_mode is "aft_huffmem.txt";
file out_file3 : text open write_mode is "aft_dct1.txt";
file out_file4 : text open write_mode is "aft_dctmem.txt";
file out_file5 : text open write_mode is "aft_dct2.txt";
file out_file6 : text open write_mode is "aft_yccmem.txt";
-- pragma translate_on

begin
   huffman : huff 
   generic map(memtech => memtech,shindex => shindex , haddr => haddr, hmask => hmask,
                hirq => hirq, pindex => pindex, paddr => paddr, pmask => pmask)
   port map(rst => rst, clk => clk, ahbsi => ahbsi, ahbso => ahbso, apbi => apbi, apbo => apbo,
             kready => kready1, kstrobe => kstrobe1, kdata => kdata1, kaddress => kaddress1, jpg_setting => jpg_setting, 
             error => error, startgen => startgen, kstrobeq => kstrobeq, kdataq => kdataq1,
             kaddq => kaddq, krddataq => krddataq,  krdq => krdq, logan_sig2 => logan_sig2);
   
   dctmem1 : huffmemcont
   generic map(memtech => memtech)
   port map(rst => rst, clk => clk, kready1 => kready1, kstrobe1 => kstrobe1, kaddress1 => kaddress1, kdata1 => kdata1, kready2 => kready2,
            kstrobe2 => kstrobe2, kdata2 => kdata2, error =>error(0), samp_fact => jpg_setting.samp_fact,
            kstrobeq1 => kstrobeq, kdataq1 => kdataq1, kdataq2 => kdataq2,
            kaddq => kaddq, krdq => krdq, krddataq => krddataq, startgen => startgen);
   
   dct1 : idct1
   port map(rst => rst, clk => clk, ready1 => kready2, strobe1 => kstrobe2, coeffin => kdata2,
            quantin => kdataq2, outdata => kdata3, ready2 => kready3, strobe2 => kstrobe3, startgen => startgen);
   
   dctmem2 : dctmem2cont
   generic map(memtech => memtech)
   port map(rst => rst, clk => clk, kready1 => kready3, kstrobe1 => kstrobe3, kdata1 => kdata3,
            kready2 => kready4, kstrobe2 => kstrobe4, kdata2 => kdata4, error => error(1), startgen => startgen);
   
   dct2 : idct2
   port map(rst => rst, clk => clk, ready1 => kready4, strobe1 => kstrobe4, coeffin => kdata4,
            outdata => kdata5, ready2 => kready5, strobe2 => kstrobe5, startgen => startgen); 
   
   yccmem : yccmemcont
   generic map(memtech => memtech)
   port map(rst => rst, clk => clk, kready1 => kready5, kstrobe1 => kstrobe5, kdata1 => kdata5,
            kready2 => kready6, kstrobe2 => kstrobe6, kdata2 => kdata6, samp_fact => jpg_setting.samp_fact,
            error => error(2), startgen => startgen);
   
   ycb : yccrgb
   generic map(memtech => memtech, hirq => hirq, mhindex => mhindex,
               chprot => chprot)
   port map(rst => rst, clk => clk, ahbmi => ahbmi, ahbmo => ahbmo, kready => kready6,
            kstrobe => kstrobe6, kdata => kdata6, xmcumax => jpg_setting.xmcumax, ymcumax => jpg_setting.ymcumax,
            incaddy => jpg_setting.incaddy, incaddmcux => jpg_setting.incaddmcux, incaddmcuy => jpg_setting.incaddmcuy, 
            fbstartadd => jpg_setting.fbstartadd, startgen => startgen);


huffcounter : process(clk, rst, kstrobe1, kaddress1, count_r)
  variable  count_v :std_logic_vector(31 downto 0);
begin
  count_v := count_r;
  if(kstrobe1 = '1' and kaddress1 = "111111") then
    count_v := count_v + 1;
  end if;
  if (rst='0')then
    count_v := (others=>'0');
  end if;
end process;

reg :process(clk)
begin
  if rising_edge(clk) then
    count_r <= count_rin;
  end if;
end process;

logan_sig <= logan_sig2
--logan_sig <= kstrobe2  &  kdata2  & kstrobe1 & kaddress1 & kdata1 ;
--    logan_sig <= count_r(16 downto 2)  & kstrobe3   &  kdata3    & kstrobe2  &  kdata2  & kstrobe1 & kaddress1 & kdata1 ;

--                                15           1           16        1             12       1            6           12      




-- pragma translate_off
writeout : process(clk,kstrobe1, kstrobe2, kstrobe3, kstrobe4, kstrobe5,kstrobe6, kdata1, kdata2, kdata3,kdata4,kdata5,kdata6)
variable lc1 : line;
variable lc2 : line;
variable lc3 : line;
variable lc4 : line;
variable lc5 : line;
variable lc6 : line;
variable data1 : std_logic_vector(11 downto 0);
variable data2 : std_logic_vector(11 downto 0);
variable data3 : std_logic_vector(15 downto 0);
variable data4 : std_logic_vector(15 downto 0);
variable data5 : std_logic_vector(7 downto 0);
variable data6 : std_logic_vector(23 downto 0);

begin
   if rising_edge(clk)then
       if (kstrobe1 = '1')then
--           data1 := kdata1;
           hwrite(lc1, kdata1, RIGHT, 3);
           writeline(out_file1,lc1);
       end if;
       if (kstrobe2 = '1')then
           hwrite(lc2, kdata2, RIGHT, 3);
           writeline(out_file2,lc2);
       end if;
       if(kstrobe3 = '1')then
           hwrite(lc3, kdata3, RIGHT, 4);
           writeline(out_file3,lc3);
       end if;
       if (kstrobe4 = '1')then
           hwrite(lc4, kdata4, RIGHT, 4);
           writeline(out_file4,lc4);
       end if;
       if(kstrobe5 = '1')then
           hwrite(lc5, kdata5, RIGHT, 2);
           writeline(out_file5,lc5);
       end if;
       if(kstrobe6 = '1')then
           hwrite(lc6, kdata6, RIGHT, 6);
           writeline(out_file6, lc6);
       end if;
   end if;
end process;
-- pragma translate_on

end;
   
