-- file Decim.vhd
-- Decim easy model controller implementation
-- copyright: (C) 2016-2020 MPSI Technologies GmbH
-- author: Alexander Wirthmueller (auto-generation)
-- date created: 10 May 2025
-- IP header --- ABOVE

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.Dbecore.all;
use work.Zuvsp.all;

entity Decim is
	port (
		reset: in std_logic;
		mclk: in std_logic;

		vsync: in std_logic;
		ixTExp: in std_logic_vector(3 downto 0);

		NRow: in std_logic_vector(10 downto 0);
		NCol: in std_logic_vector(10 downto 0);

		grayFromVideoinAXIS_tready: out std_logic;
		grayFromVideoinAXIS_tvalid: in std_logic;
		grayFromVideoinAXIS_tdata: in std_logic_vector(71 downto 0);
		grayFromVideoinAXIS_tlast: in std_logic;

		rgbFromVideoinAXIS_tready: out std_logic;
		rgbFromVideoinAXIS_tvalid: in std_logic;
		rgbFromVideoinAXIS_tdata: in std_logic_vector(35 downto 0);
		rgbFromVideoinAXIS_tlast: in std_logic;

		reqInvAcquire: in std_logic;
		ackInvAcquire: out std_logic;

		acquireIxTExp: in std_logic_vector(7 downto 0);

		reqInvConfig: in std_logic;
		ackInvConfig: out std_logic;

		configRgbNotGray: in std_logic_vector(7 downto 0);
		configEdge: in std_logic_vector(7 downto 0);
		configEdge2: in std_logic_vector(15 downto 0);
		configNDecim: in std_logic_vector(15 downto 0);

		getInfoTixVState: out std_logic_vector(7 downto 0);
		getInfoTkst: out std_logic_vector(31 downto 0);

		reqInvSet: in std_logic;
		ackInvSet: out std_logic;

		setRng: in std_logic_vector(7 downto 0);

		reqInvUnlock: in std_logic;
		ackInvUnlock: out std_logic;

		tkclksrcGetTkstTkst: in std_logic_vector(31 downto 0);

		reqPvwbufToHostif: in std_logic;
		ackPvwbufToHostif: out std_logic;
		dnePvwbufToHostif: in std_logic;
		avllenPvwbufToHostif: out std_logic_vector(31 downto 0);

		pvwbufToHostifAXIS_tready: in std_logic;
		pvwbufToHostifAXIS_tvalid: out std_logic;
		pvwbufToHostifAXIS_tdata: out std_logic_vector(63 downto 0);
		pvwbufToHostifAXIS_tlast: out std_logic;

		stateStore_dbg: out std_logic_vector(7 downto 0);
		stateStream_dbg: out std_logic_vector(7 downto 0)
	);
end Decim;

architecture Rtl of Decim is

	------------------------------------------------------------------------
	-- component declarations
	------------------------------------------------------------------------

	component Dpbram_size2kB_a64b64 is
		port (
			rstA: in std_logic;
			clkA: in std_logic;

			enA: in std_logic;
			weA: in std_logic;

			aA: in std_logic_vector(7 downto 0);
			drdA: out std_logic_vector(63 downto 0);
			dwrA: in std_logic_vector(63 downto 0);

			rstB: in std_logic;
			clkB: in std_logic;

			enB: in std_logic;
			weB: in std_logic;

			aB: in std_logic_vector(7 downto 0);
			drdB: out std_logic_vector(63 downto 0);
			dwrB: in std_logic_vector(63 downto 0)
		);
	end component;

	component Dpbram_size38kB_a8b64 is
		port (
			rstA: in std_logic;
			clkA: in std_logic;

			enA: in std_logic;
			weA: in std_logic;

			aA: in std_logic_vector(15 downto 0);
			drdA: out std_logic_vector(7 downto 0);
			dwrA: in std_logic_vector(7 downto 0);

			rstB: in std_logic;
			clkB: in std_logic;

			enB: in std_logic;
			weB: in std_logic;

			aB: in std_logic_vector(12 downto 0);
			drdB: out std_logic_vector(63 downto 0);
			dwrB: in std_logic_vector(63 downto 0)
		);
	end component;

	------------------------------------------------------------------------
	-- signal declarations
	------------------------------------------------------------------------

	constant tixVStateIdle: std_logic_vector(7 downto 0) := x"00";
	constant tixVStateAcq: std_logic_vector(7 downto 0) := x"01";
	constant tixVStateLock: std_logic_vector(7 downto 0) := x"02";

	---- main operation (op)
	type stateOp_t is (
		stateOpInit,
		stateOpInv,
		stateOpRun
	);
	signal stateOp: stateOp_t;

	signal ackInvAcquire_sig: std_logic;
	signal ackInvConfig_sig: std_logic;
	signal ackInvSet_sig: std_logic;
	signal ackInvUnlock_sig: std_logic;

	signal rng: std_logic;
	signal tixVState: std_logic_vector(7 downto 0);
	signal rgbNotGray: std_logic;

	signal edge: natural range 6 to 16;
	signal edge2: unsigned(10 downto 0); -- max. 1024, decim factor before >> 12 (or /4096)

	signal decimLast: natural range 0 to 38*1024-1; -- e.g. for RGB 11x11 of 1280x960, get 3*(1276*957/11/11)-1 = 30275

	-- IP sigs.op.cust --- INSERT

	---- preview buffer B/hostif-facing operation (pvwbufB)
	type statePvwbufB_t is (
		statePvwbufBInit,
		statePvwbufBIdle,
		statePvwbufBXferA, statePvwbufBXferB,
		statePvwbufBDone
	);
	signal statePvwbufB: statePvwbufB_t;

	signal enPvwbufB: std_logic;
	signal aPvwbufB: natural range 0 to 38*1024/8-1;
	signal aPvwbufB_vec: std_logic_vector(12 downto 0);

	-- IP sigs.pvwbufB.cust --- INSERT

	---- decimated value store operation (store)
	type stateStore_t is (
		stateStoreInit,
		stateStoreIdle,
		stateStoreWrite,
		stateStoreDone
	);
	signal stateStore: stateStore_t;

	signal enPvwbuf: std_logic;
	signal aPvwbuf: natural range 0 to 38*1024-1;
	signal aPvwbuf_vec: std_logic_vector(15 downto 0);
	signal dwrPvwbuf: std_logic_vector(7 downto 0);

	-- IP sigs.store.cust --- INSERT

	---- streaming operation (stream)
	type stateStream_t is (
		stateStreamInit,
		stateStreamRun,
		stateStreamEolA, stateStreamEolB,
		stateStreamEofA
	);
	signal stateStream: stateStream_t;

	signal tkst: std_logic_vector(31 downto 0);

	signal enAccbuf: std_logic;
	signal aAccbuf: natural range 0 to 255;
	signal aAccbuf_vec: std_logic_vector(7 downto 0);
	signal dwrAccbuf: std_logic_vector(63 downto 0);

	signal enAccbufB: std_logic;
	signal aAccbufB: natural range 0 to 255;
	signal aAccbufB_vec: std_logic_vector(7 downto 0);

	signal colacc: natural range 0 to 15;
	signal colaccLast: natural range 5 to 15;

	signal rowacc: natural range 0 to 15;
	signal rowaccLast: natural range 5 to 15;

	signal col: natural range 0 to 2000-1;
	signal row: natural range 0 to 1500-1;

	signal acc0: unsigned(19 downto 0);
	signal acc1: unsigned(19 downto 0);
	signal acc2: unsigned(19 downto 0);

	signal strbStore: std_logic;

	-- IP sigs.stream.cust --- INSERT

	---- myAccbuf
	signal drdAccbufB: std_logic_vector(63 downto 0);

	---- other
	-- IP sigs.oth.cust --- INSERT

begin

	------------------------------------------------------------------------
	-- sub-module instantiation
	------------------------------------------------------------------------

	myAccbuf : Dpbram_size2kB_a64b64
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enAccbuf,
			weA => '1',

			aA => aAccbuf_vec,
			drdA => open,
			dwrA => dwrAccbuf,

			rstB => reset,
			clkB => mclk,

			enB => enAccbufB,
			weB => '0',

			aB => aAccbufB_vec,
			drdB => drdAccbufB,
			dwrB => (others => '0')
		);

	myPvwbuf : Dpbram_size38kB_a8b64
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enPvwbuf,
			weA => '1',

			aA => aPvwbuf_vec,
			drdA => open,
			dwrA => dwrPvwbuf,

			rstB => reset,
			clkB => mclk,

			enB => enPvwbufB,
			weB => '0',

			aB => aPvwbufB_vec,
			drdB => pvwbufToHostifAXIS_tdata,
			dwrB => (others => '0')
		);

	------------------------------------------------------------------------
	-- implementation: main operation (op)
	------------------------------------------------------------------------

	-- IP impl.op.wiring --- BEGIN
	ackInvAcquire <= ackInvAcquire_sig;
	ackInvConfig <= ackInvConfig_sig;
	ackInvSet <= ackInvSet_sig;
	ackInvUnlock <= ackInvUnlock_sig;

	getInfoTixVState <= tixVState;
	-- IP impl.op.wiring --- END

	-- IP impl.op.wiring.cust --- LINE

	-- IP impl.op.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.op.vars --- RBEGIN
		variable ixTExp_lcl: std_logic_vector(3 downto 0);
		variable vsync_last: std_logic;
		-- IP impl.op.vars --- REND

	begin
		if reset='1' then
			-- IP impl.op.asyncrst --- BEGIN
			stateOp <= stateOpInit;
			ackInvAcquire_sig <= '0';
			ackInvConfig_sig <= '0';
			ackInvSet_sig <= '0';
			ackInvUnlock_sig <= '0';
			rng <= '0';
			tixVState <= (others => '0');
			rgbNotGray <= '0';
			edge <= 6;
			edge2 <= "00000100100";
			decimLast <= 0;

			-- IP impl.op.asyncrst --- END
			-- IP impl.op.asyncrst.cust --- IBEGIN
			ixTExp_lcl := (others => '0');
			vsync_last := '0';
			-- IP impl.op.asyncrst.cust --- IEND

		elsif rising_edge(mclk) then
			if (stateOp=stateOpInit or (stateOp/=stateOpInv and (reqInvAcquire='1' or reqInvConfig='1' or reqInvSet='1' or reqInvUnlock='1'))) then
				if reqInvAcquire='1' then
					-- IP impl.op.init.invAcquire --- IBEGIN
					if rng='1' then
						tixVState <= tixVStateAcq;
						ixTExp_lcl := acquireIxTExp(3 downto 0);
					end if;

					ackInvAcquire_sig <= '1';
					ackInvConfig_sig <= '0';
					ackInvSet_sig <= '0';
					ackInvUnlock_sig <= '0';
					-- IP impl.op.init.invAcquire --- IEND

					stateOp <= stateOpInv;

				elsif reqInvConfig='1' then
					-- IP impl.op.init.invConfig --- IBEGIN
					if configRgbNotGray=tru8 then
						rgbNotGray <= '1';
					else
						rgbNotGray <= '0';
					end if;
					edge <= to_integer(unsigned(configEdge));
					edge2 <= unsigned(configEdge2(10 downto 0));
					decimLast <= to_integer(unsigned(configNDecim) - 1);

					ackInvAcquire_sig <= '0';
					ackInvConfig_sig <= '1';
					ackInvSet_sig <= '0';
					ackInvUnlock_sig <= '0';
					-- IP impl.op.init.invConfig --- IEND

					stateOp <= stateOpInv;

				elsif reqInvSet='1' then
					-- IP impl.op.init.invSet --- IBEGIN
					if setRng=tru8 then
						rng <= '1';
					else
						rng <= '0';
					end if;
					tixVState <= tixVStateIdle;

					ackInvAcquire_sig <= '0';
					ackInvConfig_sig <= '0';
					ackInvSet_sig <= '1';
					ackInvUnlock_sig <= '0';
					-- IP impl.op.init.invSet --- IEND

					stateOp <= stateOpInv;

				elsif reqInvUnlock='1' then
					-- IP impl.op.init.invUnlock --- IBEGIN
					if tixVState=tixVStateLock then
						tixVState <= tixVStateIdle;
					end if;

					ackInvAcquire_sig <= '0';
					ackInvConfig_sig <= '0';
					ackInvSet_sig <= '0';
					ackInvUnlock_sig <= '1';
					-- IP impl.op.init.invUnlock --- IEND

					stateOp <= stateOpInv;

				else
					-- IP impl.op.syncrst --- RBEGIN
					ackInvAcquire_sig <= '0';
					ackInvConfig_sig <= '0';
					ackInvSet_sig <= '0';
					ackInvUnlock_sig <= '0';

					-- IP impl.op.syncrst --- REND
					-- IP impl.op.syncrst.cust --- IBEGIN
					vsync_last := vsync;
					-- IP impl.op.syncrst.cust --- IEND

					if rng='1' then
						stateOp <= stateOpRun;

					else
						stateOp <= stateOpInit;
					end if;
				end if;

			elsif stateOp=stateOpInv then
				if ((reqInvAcquire='0' and ackInvAcquire_sig='1') or (reqInvConfig='0' and ackInvConfig_sig='1') or (reqInvSet='0' and ackInvSet_sig='1') or (reqInvUnlock='0' and ackInvUnlock_sig='1')) then
					-- IP impl.op.inv.reset --- IBEGIN
					ackInvAcquire_sig <= '0';
					ackInvConfig_sig <= '0';
					ackInvSet_sig <= '0';
					ackInvUnlock_sig <= '0';
					-- IP impl.op.inv.reset --- IEND

					stateOp <= stateOpInit;
				end if;

			elsif stateOp=stateOpRun then
				-- IP impl.op.run --- IBEGIN
				if tixVState=tixVStateAcq and vsync_last='0' and vsync='1' and ixTExp=ixTExp_lcl then
					tixVState <= tixVStateLock;
				end if;

				vsync_last := vsync;
				-- IP impl.op.run --- IEND
			end if;
		end if;
	end process;
	-- IP impl.op.rising --- END

	------------------------------------------------------------------------
	-- implementation: preview buffer B/hostif-facing operation (pvwbufB)
	------------------------------------------------------------------------

	-- IP impl.pvwbufB.wiring --- BEGIN
	ackPvwbufToHostif <= '1' when (statePvwbufB=statePvwbufBXferA or statePvwbufB=statePvwbufBXferB or statePvwbufB=statePvwbufBDone) else '0';

	pvwbufToHostifAXIS_tvalid <= '1' when statePvwbufB=statePvwbufBXferB else '0';
	pvwbufToHostifAXIS_tlast <= '0' when (statePvwbufB=statePvwbufBXferB and aPvwbufB/=38*1024/8-1) else '1';

	enPvwbufB <= '1' when statePvwbufB=statePvwbufBXferA else '0';
	aPvwbufB_vec <= std_logic_vector(to_unsigned(aPvwbufB, 13));
	-- IP impl.pvwbufB.wiring --- END

	-- IP impl.pvwbufB.wiring.cust --- RBEGIN
	avllenPvwbufToHostif <= std_logic_vector(to_unsigned(38*1024, 32)) when statePvwbufB=statePvwbufBIdle else (others => '0');
	-- IP impl.pvwbufB.wiring.cust --- REND

	-- IP impl.pvwbufB.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.pvwbufB.vars --- BEGIN
		-- IP impl.pvwbufB.vars --- END

	begin
		if reset='1' then
			-- IP impl.pvwbufB.asyncrst --- BEGIN
			statePvwbufB <= statePvwbufBInit;
			aPvwbufB <= 0;

			-- IP impl.pvwbufB.asyncrst --- END
			-- IP impl.pvwbufB.asyncrst.cust --- INSERT

		elsif rising_edge(mclk) then
			if statePvwbufB=statePvwbufBInit then
				-- IP impl.pvwbufB.syncrst --- BEGIN
				aPvwbufB <= 0;

				-- IP impl.pvwbufB.syncrst --- END
				-- IP impl.pvwbufB.syncrst.cust --- INSERT

				if reqPvwbufToHostif='0' then
					statePvwbufB <= statePvwbufBIdle;
				end if;

			elsif statePvwbufB=statePvwbufBIdle then
				if reqPvwbufToHostif='1' then
					statePvwbufB <= statePvwbufBXferA;
				end if;

			elsif statePvwbufB=statePvwbufBXferA then
				statePvwbufB <= statePvwbufBXferB;

			elsif statePvwbufB=statePvwbufBXferB then
				if pvwbufToHostifAXIS_tready='1' then
					if aPvwbufB=38*1024/8-1 then
						statePvwbufB <= statePvwbufBDone;

					else
						aPvwbufB <= aPvwbufB + 1; -- IP impl.pvwbufB.xferB.inc --- ILINE

						statePvwbufB <= statePvwbufBXferA;
					end if;

				elsif reqPvwbufToHostif='0' then
					statePvwbufB <= statePvwbufBInit;
				end if;

			elsif statePvwbufB=statePvwbufBDone then
				if dnePvwbufToHostif='1' then
					statePvwbufB <= statePvwbufBInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.pvwbufB.rising --- END

	------------------------------------------------------------------------
	-- implementation: decimated value store operation (store)
	------------------------------------------------------------------------

	-- IP impl.store.wiring --- BEGIN
	enPvwbuf <= '1' when stateStore=stateStoreWrite else '0';
	aPvwbuf_vec <= std_logic_vector(to_unsigned(aPvwbuf, 16));
	-- IP impl.store.wiring --- END

	-- IP impl.store.wiring.cust --- LINE

	stateStore_dbg <= x"00" when stateStore=stateStoreInit
				else x"10" when stateStore=stateStoreIdle
				else x"20" when stateStore=stateStoreWrite
				else x"30" when stateStore=stateStoreDone
				else (others => '1');

	-- IP impl.store.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.store.vars --- RBEGIN
		variable decim0, decim1, decim2: unsigned(30 downto 0);

		constant imax: natural := 2;
		variable i: natural range 0 to imax;
		-- IP impl.store.vars --- REND

	begin
		if reset='1' then
			-- IP impl.store.asyncrst --- BEGIN
			stateStore <= stateStoreInit;
			aPvwbuf <= 0;
			dwrPvwbuf <= (others => '0');

			-- IP impl.store.asyncrst --- END
			-- IP impl.store.asyncrst.cust --- IBEGIN
			decim0 := (others => '0');
			decim1 := (others => '0');
			decim2 := (others => '0');
			
			i := 0;
			-- IP impl.store.asyncrst.cust --- IEND

		elsif rising_edge(mclk) then
			if (stateStore=stateStoreInit or rng='0') then
				-- IP impl.store.syncrst --- BEGIN
				aPvwbuf <= 0;
				dwrPvwbuf <= (others => '0');

				-- IP impl.store.syncrst --- END
				-- IP impl.store.syncrst.cust --- IBEGIN
				decim0 := (others => '0');
				decim1 := (others => '0');
				decim2 := (others => '0');
				
				i := 0;
				-- IP impl.store.syncrst.cust --- IEND

				if (rng='1' and vsync='1') then
					stateStore <= stateStoreIdle;

				else
					stateStore <= stateStoreInit;
				end if;

			elsif stateStore=stateStoreIdle then
				if strbStore='1' then
					-- IP impl.store.idle.copy --- IBEGIN
					decim2 := edge2 * acc2;
					decim1 := edge2 * acc1;
					decim0 := edge2 * acc0;

					dwrPvwbuf <= std_logic_vector(decim0(12+11 downto 12+4));
					
					i := 0;
					-- IP impl.store.idle.copy --- IEND

					stateStore <= stateStoreWrite;
				end if;

			elsif stateStore=stateStoreWrite then
				if aPvwbuf=decimLast then
					stateStore <= stateStoreDone;

				else
					aPvwbuf <= aPvwbuf + 1; -- IP impl.store.write.inc --- ILINE

					if (rgbNotGray='1' and i<2) then
						-- IP impl.store.write.nextWord --- IBEGIN
						i := i + 1;

						case i is
							when 1 =>
								dwrPvwbuf <= std_logic_vector(decim1(12+11 downto 12+4));
							when 2 =>
								dwrPvwbuf <= std_logic_vector(decim2(12+11 downto 12+4));
							when others =>
						end case;
						-- IP impl.store.write.nextWord --- IEND

						stateStore <= stateStoreWrite;

					else
						stateStore <= stateStoreIdle;
					end if;
				end if;

			elsif stateStore=stateStoreDone then
				if vsync='1' then
					stateStore <= stateStoreInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.store.rising --- END

	------------------------------------------------------------------------
	-- implementation: streaming operation (stream)
	------------------------------------------------------------------------

	-- IP impl.stream.wiring --- BEGIN
	getInfoTkst <= tkst;

	aAccbuf_vec <= std_logic_vector(to_unsigned(aAccbuf, 8));

	enAccbufB <= '1' when stateStream=stateStreamRun else '0';
	aAccbufB_vec <= std_logic_vector(to_unsigned(aAccbufB, 8));
	-- IP impl.stream.wiring --- END

	-- IP impl.stream.wiring.cust --- LINE

	stateStream_dbg <= x"00" when stateStream=stateStreamInit
				else x"10" when stateStream=stateStreamRun
				else x"20" when stateStream=stateStreamEolA
				else x"21" when stateStream=stateStreamEolB
				else x"30" when stateStream=stateStreamEofA
				else (others => '1');

	-- IP impl.stream.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.stream.vars --- RBEGIN
		variable acc0_lcl, acc1_lcl, acc2_lcl: unsigned(19 downto 0);

		variable row_next: natural range 0 to 1500+16-1;
		variable col_next: natural range 0 to 2000+16-1;
		-- IP impl.stream.vars --- REND

	begin
		if reset='1' then
			-- IP impl.stream.asyncrst --- BEGIN
			stateStream <= stateStreamInit;
			tkst <= (others => '0');
			enAccbuf <= '0';
			aAccbuf <= 0;
			dwrAccbuf <= (others => '0');
			aAccbufB <= 0;
			colacc <= 0;
			colaccLast <= 5;
			rowacc <= 0;
			rowaccLast <= 5;
			col <= 0;
			row <= 0;
			acc0 <= (others => '0');
			acc1 <= (others => '0');
			acc2 <= (others => '0');
			strbStore <= '0';

			-- IP impl.stream.asyncrst --- END
			-- IP impl.stream.asyncrst.cust --- IBEGIN
			acc0_lcl := (others => '0');
			acc1_lcl := (others => '0');
			acc2_lcl := (others => '0');

			row_next := 0;
			col_next := 0;
			-- IP impl.stream.asyncrst.cust --- IEND

		elsif rising_edge(mclk) then
			if (stateStream=stateStreamInit or rng='0') then
				-- IP impl.stream.syncrst --- RBEGIN
				enAccbuf <= '0';
				aAccbuf <= 0;
				dwrAccbuf <= (others => '0');
				aAccbufB <= 0;
				colacc <= 0;
				rowacc <= 0;
				col <= 0;
				row <= 0;
				acc0 <= (others => '0');
				acc1 <= (others => '0');
				acc2 <= (others => '0');
				strbStore <= '0';

				-- IP impl.stream.syncrst --- REND
				-- IP impl.stream.syncrst.cust --- IBEGIN
				acc0_lcl := (others => '0');
				acc1_lcl := (others => '0');
				acc2_lcl := (others => '0');
	
				row_next := 0;
				col_next := 0;
				-- IP impl.stream.syncrst.cust --- IEND

				if (rng='1' and (vsync='1' and tixVState/=tixVStateLock)) then
					-- IP impl.stream.init.start --- IBEGIN
					tkst <= tkclksrcGetTkstTkst;

					colaccLast <= edge-1;
					rowaccLast <= edge-1;
					-- IP impl.stream.init.start --- IEND

					stateStream <= stateStreamRun;

				else
					stateStream <= stateStreamInit;
				end if;

			elsif stateStream=stateStreamRun then
				-- IP impl.stream.run.pre --- IBEGIN
				if enAccbuf='1' then
					aAccbuf <= aAccbuf + 1;
				end if;
				-- IP impl.stream.run.pre --- IEND

				if ((rgbNotGray='0' and grayFromVideoinAXIS_tvalid='1') or (rgbNotGray='1' and rgbFromVideoinAXIS_tvalid='1')) then
					-- IP impl.stream.run.acc --- IBEGIN
					if colacc=0 then
						aAccbufB <= aAccbufB + 1;

						if rowacc=0 then
							acc0_lcl := (others => '0');
							acc1_lcl := (others => '0');
							acc2_lcl := (others => '0');
						else
							acc0_lcl := unsigned(drdAccbufB(19 downto 0));
							acc1_lcl := unsigned(drdAccbufB(39 downto 20));
							acc2_lcl := unsigned(drdAccbufB(59 downto 40));
						end if;
					end if;

					if rgbNotGray='0' then
						acc0_lcl := acc0_lcl + resize(unsigned(grayFromVideoinAXIS_tdata(11 downto 0)), 20);
					else
						acc2_lcl := acc2_lcl + resize(unsigned(rgbFromVideoinAXIS_tdata(35 downto 24)), 20);
						acc1_lcl := acc1_lcl + resize(unsigned(rgbFromVideoinAXIS_tdata(23 downto 12)), 20);
						acc0_lcl := acc0_lcl + resize(unsigned(rgbFromVideoinAXIS_tdata(11 downto 0)), 20);
					end if;
					-- IP impl.stream.run.acc --- IEND

					if colacc=colaccLast then
						-- IP impl.stream.run.colaccDone --- IBEGIN
						colacc <= 0;

						if rowacc=rowaccLast then
							-- relocate multiplication to store FSM to meet timing
							acc0 <= acc0_lcl;
							acc1 <= acc1_lcl;
							acc2 <= acc2_lcl;

							strbStore <= '1'; -- separate store FSM, aPvwbuf auto-increment

						else
							enAccbuf <= '1';

							dwrAccbuf(59 downto 40) <= std_logic_vector(acc2_lcl);
							dwrAccbuf(39 downto 20) <= std_logic_vector(acc1_lcl);
							dwrAccbuf(19 downto 0) <= std_logic_vector(acc0_lcl);

							strbStore <= '0';
						end if;

						col_next := col + edge;
						-- IP impl.stream.run.colaccDone --- IEND

						if col_next>=unsigned(NCol) then
							col <= 0; -- IP impl.stream.run.rowDone --- ILINE

							stateStream <= stateStreamEolA;

						else
							col <= col + 1; -- IP impl.stream.run.nextCol --- ILINE

							stateStream <= stateStreamRun;
						end if;

					else
						-- IP impl.stream.run.nextColacc --- IBEGIN
						colacc <= colacc + 1;
						col <= col + 1;

						strbStore <= '0';
						-- IP impl.stream.run.nextColacc --- IEND

						stateStream <= stateStreamRun;
					end if;

				else
					-- IP impl.stream.run.reset --- IBEGIN
					enAccbuf <= '0';

					strbStore <= '0';
					-- IP impl.stream.run.reset --- IEND

					stateStream <= stateStreamRun;
				end if;

			elsif stateStream=stateStreamEolA then
				-- IP impl.stream.eolA.pre --- IBEGIN
				enAccbuf <= '0';

				aAccbuf <= 0;
				aAccbufB <= 0;

				strbStore <= '0';
				-- IP impl.stream.eolA.pre --- IEND

				if rowacc=rowaccLast then
					-- IP impl.stream.eolA.rowaccDone --- IBEGIN
					rowacc <= 0;

					row_next := row + edge;
					-- IP impl.stream.eolA.rowaccDone --- IEND

					if row_next>=unsigned(NRow) then
						row <= 0; -- IP impl.stream.eolA.frameDone --- ILINE

						stateStream <= stateStreamEofA;

					else
						row <= row + 1; -- IP impl.stream.eolA.nextRow --- ILINE

						stateStream <= stateStreamEolB;
					end if;

				else
					-- IP impl.stream.eolA.nextRowacc --- IBEGIN
					rowacc <= rowacc + 1;
					row <= row + 1;
					-- IP impl.stream.eolA.nextRowacc --- IEND

					stateStream <= stateStreamEolB;
				end if;

			elsif stateStream=stateStreamEolB then
				if ((rgbNotGray='0' and grayFromVideoinAXIS_tlast='1') or (rgbNotGray='1' and rgbFromVideoinAXIS_tlast='1')) then
					stateStream <= stateStreamRun;
				end if;

			elsif stateStream=stateStreamEofA then
				if vsync='1' then
					stateStream <= stateStreamInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.stream.rising --- END

	------------------------------------------------------------------------
	-- implementation: other 
	------------------------------------------------------------------------

	
	-- IP impl.oth.cust --- INSERT

end Rtl;
