-- file Corner.vhd
-- Corner 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 Corner is
	port (
		reset: in std_logic;
		mclk: in std_logic;

		vsync: in std_logic;
		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;

		reqInvAcquire: in std_logic;
		ackInvAcquire: out std_logic;

		reqInvFromRpuifAcquire: in std_logic;
		ackInvFromRpuifAcquire: out std_logic;

		reqInvConfig: in std_logic;
		ackInvConfig: out std_logic;

		configLinNotLog: in std_logic_vector(7 downto 0);
		configThd: in std_logic_vector(7 downto 0);
		configRow0: in std_logic_vector(15 downto 0);
		configRow1: in std_logic_vector(15 downto 0);
		configCol0: in std_logic_vector(15 downto 0);
		configCol1: in std_logic_vector(15 downto 0);

		getInfoTixVState: out std_logic_vector(7 downto 0);
		getInfoTkst: out std_logic_vector(31 downto 0);
		getInfoScoreMin: out std_logic_vector(7 downto 0);
		getInfoScoreMax: out std_logic_vector(7 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;

		reqInvFromRpuifUnlock: in std_logic;
		ackInvFromRpuifUnlock: out std_logic;

		tkclksrcGetTkstTkst: in std_logic_vector(31 downto 0);

		reqCoobufToHostif: in std_logic;
		ackCoobufToHostif: out std_logic;
		dneCoobufToHostif: in std_logic;
		avllenCoobufToHostif: out std_logic_vector(31 downto 0);

		coobufToHostifAXIS_tready: in std_logic;
		coobufToHostifAXIS_tvalid: out std_logic;
		coobufToHostifAXIS_tdata: out std_logic_vector(63 downto 0);
		coobufToHostifAXIS_tlast: out std_logic
	);
end Corner;

architecture Rtl of Corner is

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

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

			enA: in std_logic;
			weA: in std_logic;

			aA: in std_logic_vector(8 downto 0);
			drdA: out std_logic_vector(31 downto 0);
			dwrA: in std_logic_vector(31 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_size2kB_a8b8 is
		port (
			rstA: in std_logic;
			clkA: in std_logic;

			enA: in std_logic;
			weA: in std_logic;

			aA: in std_logic_vector(10 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(10 downto 0);
			drdB: out std_logic_vector(7 downto 0);
			dwrB: in std_logic_vector(7 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";

	---- coordinate buffer B/hostif-facing operation (coobufB)
	type stateCoobufB_t is (
		stateCoobufBInit,
		stateCoobufBIdle,
		stateCoobufBXferA, stateCoobufBXferB,
		stateCoobufBDone
	);
	signal stateCoobufB: stateCoobufB_t;

	signal enCoobufB: std_logic;
	signal aCoobufB: natural range 0 to 2*1024/8-1;
	signal aCoobufB_vec: std_logic_vector(7 downto 0);

	-- IP sigs.coobufB.cust --- INSERT

	---- Harris corner detection and score pipeline operation (corner)
	type stateCorner_t is (
		stateCornerInit,
		stateCornerRun,
		stateCornerEolA, stateCornerEolB
	);
	signal stateCorner: stateCorner_t;

	signal dIgrm1: std_logic_vector(47 downto 0); -- 6x 8bits
	signal lat: natural range 0 to 2000-1; -- pipeline latency in counts of ceScore active
	signal ceScore: std_logic;
	signal abcde: natural range 0 to 4;
	signal dx: std_logic_vector(44 downto 0); -- 5x 9bits
	signal dy: std_logic_vector(44 downto 0); -- 5x 9bits

	-- IP sigs.corner.cust --- INSERT

	---- intermediate result streaming operation (imdstream)
	type stateImdstream_t is (
		stateImdstreamInit,
		stateImdstreamSkip,
		stateImdstreamRun,
		stateImdstreamHold,
		stateImdstreamEol
	);
	signal stateImdstream: stateImdstream_t;

	signal shift: natural range 0 to 47;
	signal scoreMin: std_logic_vector(7 downto 0);
	signal scoreMax: std_logic_vector(7 downto 0);

	signal ceMaxsel: std_logic;
	signal fghij: natural;

	signal enImdbuf: std_logic;
	signal enImd0buf: std_logic;
	signal enImd1buf: std_logic;
	signal enImd2buf: std_logic;
	signal enImd3buf: std_logic;
	signal enImd4buf: std_logic;

	signal aImdbuf: natural range 0 to 2*1024-1;
	signal aImdbuf_vec: std_logic_vector(10 downto 0);

	signal enImdbufB: std_logic;

	signal aImdbufB: natural range 0 to 2*1024-1;
	signal aImdbufB_vec: std_logic_vector(10 downto 0);

	signal dImd: std_logic_vector(39 downto 0);

	-- IP sigs.imdstream.cust --- INSERT

	---- intermediate result streaming operation (maxsel)
	type stateMaxsel_t is (
		stateMaxselInit,
		stateMaxselRun,
		stateMaxselEol
	);
	signal stateMaxsel: stateMaxsel_t;

	signal tkst: std_logic_vector(31 downto 0);

	type maximds_t is array (0 to 4) of std_logic_vector(7 downto 0);
	signal maximds: maximds_t;
	signal maximdsm1: maximds_t;

	type ixMaximds_t is array (0 to 4) of natural range 0 to 4;
	signal ixMaximds: ixMaximds_t;
	signal IxMaximdsm1: ixMaximds_t;

	type unqMaximds_t is array (0 to 4) of boolean;
	signal unqMaximds: unqMaximds_t;
	signal unqMaximdsm1: unqMaximds_t;

	signal ixMax: natural range 0 to 4;
	signal unqMax: boolean;

	signal enCoobuf: std_logic;

	signal aCoobuf: natural range 0 to 2*1024/4-1;
	signal aCoobuf_vec: std_logic_vector(8 downto 0);

	signal dwrCoobuf: std_logic_vector(31 downto 0);

	-- IP sigs.maxsel.cust --- INSERT

	---- 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 linNotLog: std_logic;
	signal thd: natural range 0 to 255;

	signal row0: natural range 0 to 1500-1;
	signal row1: natural range 0 to 1500-1;
	signal col0: natural range 0 to 2000-1;
	signal col1: natural range 0 to 2000-1;

	signal colLast: natural range 0 to 2000-1;
	signal rowLast: natural range 0 to 1500-1;

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

	---- Harris score pipeline operation (score)
	type stateScore_t is (
		stateScoreInit,
		stateScoreRun
	);
	signal stateScore: stateScore_t;

	signal xsqr: std_logic_vector(89 downto 0); -- stage 1; 5x 18bits, set by modules xsqr0 to xsqr4
	signal ysqr: std_logic_vector(89 downto 0); -- 5x 18bits, set by modules ysqr0 to ysqr4
	signal xy: std_logic_vector(89 downto 0); -- 5x 18bits, set by modules xy0 to xy4

	signal colsumXA: std_logic_vector(37 downto 0); -- stage 2
	signal colsumYA: std_logic_vector(37 downto 0);
	signal colsumXYA: std_logic_vector(37 downto 0);

	signal xsqr4p1: std_logic_vector(17 downto 0);
	signal xsqr4p2: std_logic_vector(17 downto 0);

	signal ysqr4p1: std_logic_vector(17 downto 0);
	signal ysqr4p2: std_logic_vector(17 downto 0);

	signal xy4p1: std_logic_vector(17 downto 0);
	signal xy4p2: std_logic_vector(17 downto 0);

	signal colsumXB: std_logic_vector(19 downto 0); -- stage 3
	signal colsumYB: std_logic_vector(19 downto 0);
	signal colsumXYB: std_logic_vector(19 downto 0);

	signal colsumXC: std_logic_vector(20 downto 0); -- stage 4
	signal colsumYC: std_logic_vector(20 downto 0);
	signal colsumXYC: std_logic_vector(20 downto 0);

	signal colsumX: std_logic_vector(104 downto 0); -- stage 5; 5x 21bits
	signal colsumY: std_logic_vector(104 downto 0); -- 5x 21bits
	signal colsumXY: std_logic_vector(104 downto 0); -- 5x 21bits

	signal sumXA: std_logic_vector(43 downto 0); -- stage 6
	signal sumYA: std_logic_vector(43 downto 0);
	signal sumXYA: std_logic_vector(43 downto 0);

	signal colsumX4p1: std_logic_vector(20 downto 0);
	signal colsumX4p2: std_logic_vector(20 downto 0);

	signal colsumY4p1: std_logic_vector(20 downto 0);
	signal colsumY4p2: std_logic_vector(20 downto 0);

	signal colsumXY4p1: std_logic_vector(20 downto 0);
	signal colsumXY4p2: std_logic_vector(20 downto 0);

	signal sumXB: std_logic_vector(22 downto 0); -- stage 7
	signal sumYB: std_logic_vector(22 downto 0);
	signal sumXYB: std_logic_vector(22 downto 0);

	signal sumX: std_logic_vector(22 downto 0); -- stage 8
	signal sumY: std_logic_vector(22 downto 0);
	signal sumXY: std_logic_vector(22 downto 0);

	signal sumIII: std_logic_vector(23 downto 0); -- stage 9
	signal termI: std_logic_vector(45 downto 0);
	signal termII: std_logic_vector(45 downto 0);
	signal termIII: std_logic_vector(47 downto 0); -- stage 10
	signal diffI_II: std_logic_vector(46 downto 0);
	signal termIIIk: std_logic_vector(43 downto 0); -- stage 11
	signal diffI_IIp1: std_logic_vector(46 downto 0);
	signal r: std_logic_vector(47 downto 0); -- stage 12
	signal rexp: std_logic_vector(7 downto 0); -- stage 13
	signal rshift: natural range 0 to 39;

	-- IP sigs.score.cust --- INSERT

	---- myImd0buf
	signal drdImd0bufB: std_logic_vector(7 downto 0);

	---- myImd1buf
	signal drdImd1bufB: std_logic_vector(7 downto 0);

	---- myImd2buf
	signal drdImd2bufB: std_logic_vector(7 downto 0);

	---- myImd3buf
	signal drdImd3bufB: std_logic_vector(7 downto 0);

	---- myImd4buf
	signal drdImd4bufB: std_logic_vector(7 downto 0);

	---- other
	signal sprsNotFull: std_logic := '1';
	-- IP sigs.oth.cust --- IBEGIN

	------------------------------------------------------------------------
	-- functional description
	------------------------------------------------------------------------

	-- pipelined Harris corner detection algorithm

	-- IP sigs.oth.cust --- IEND

begin

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

	myCoobuf : Dpbram_size2kB_a32b64
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enCoobuf,
			weA => '1',

			aA => aCoobuf_vec,
			drdA => open,
			dwrA => dwrCoobuf,

			rstB => reset,
			clkB => mclk,

			enB => enCoobufB,
			weB => '0',

			aB => aCoobufB_vec,
			drdB => coobufToHostifAXIS_tdata,
			dwrB => (others => '0')
		);

	myImd0buf : Dpbram_size2kB_a8b8
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enImd0buf,
			weA => '1',

			aA => aImdbuf_vec,
			drdA => open,
			dwrA => rexp,

			rstB => reset,
			clkB => mclk,

			enB => enImdbufB,
			weB => '0',

			aB => aImdbufB_vec,
			drdB => drdImd0bufB,
			dwrB => (others => '0')
		);

	myImd1buf : Dpbram_size2kB_a8b8
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enImd1buf,
			weA => '1',

			aA => aImdbuf_vec,
			drdA => open,
			dwrA => rexp,

			rstB => reset,
			clkB => mclk,

			enB => enImdbufB,
			weB => '0',

			aB => aImdbufB_vec,
			drdB => drdImd1bufB,
			dwrB => (others => '0')
		);

	myImd2buf : Dpbram_size2kB_a8b8
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enImd2buf,
			weA => '1',

			aA => aImdbuf_vec,
			drdA => open,
			dwrA => rexp,

			rstB => reset,
			clkB => mclk,

			enB => enImdbufB,
			weB => '0',

			aB => aImdbufB_vec,
			drdB => drdImd2bufB,
			dwrB => (others => '0')
		);

	myImd3buf : Dpbram_size2kB_a8b8
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enImd3buf,
			weA => '1',

			aA => aImdbuf_vec,
			drdA => open,
			dwrA => rexp,

			rstB => reset,
			clkB => mclk,

			enB => enImdbufB,
			weB => '0',

			aB => aImdbufB_vec,
			drdB => drdImd3bufB,
			dwrB => (others => '0')
		);

	myImd4buf : Dpbram_size2kB_a8b8
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enImd4buf,
			weA => '1',

			aA => aImdbuf_vec,
			drdA => open,
			dwrA => rexp,

			rstB => reset,
			clkB => mclk,

			enB => enImdbufB,
			weB => '0',

			aB => aImdbufB_vec,
			drdB => drdImd4bufB,
			dwrB => (others => '0')
		);

	------------------------------------------------------------------------
	-- implementation: coordinate buffer B/hostif-facing operation (coobufB)
	------------------------------------------------------------------------

	-- IP impl.coobufB.wiring --- BEGIN
	ackCoobufToHostif <= '1' when (stateCoobufB=stateCoobufBXferA or stateCoobufB=stateCoobufBXferB or stateCoobufB=stateCoobufBDone) else '0';

	coobufToHostifAXIS_tvalid <= '1' when stateCoobufB=stateCoobufBXferB else '0';
	coobufToHostifAXIS_tlast <= '0' when (stateCoobufB=stateCoobufBXferA or (stateCoobufB=stateCoobufBXferB and aCoobufB/=2*1024/8-1)) else '1';

	enCoobufB <= '1' when stateCoobufB=stateCoobufBXferA else '0';
	aCoobufB_vec <= std_logic_vector(to_unsigned(aCoobufB, 8));
	-- IP impl.coobufB.wiring --- END

	-- IP impl.coobufB.wiring.cust --- RBEGIN
	avllenCoobufToHostif <= std_logic_vector(to_unsigned(2*1024, 32)) when stateCoobufB=stateCoobufBIdle else (others => '0');
	-- IP impl.coobufB.wiring.cust --- REND

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

	begin
		if reset='1' then
			-- IP impl.coobufB.asyncrst --- BEGIN
			stateCoobufB <= stateCoobufBInit;
			aCoobufB <= 0;

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

		elsif rising_edge(mclk) then
			if stateCoobufB=stateCoobufBInit then
				-- IP impl.coobufB.syncrst --- BEGIN
				aCoobufB <= 0;

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

				if reqCoobufToHostif='0' then
					stateCoobufB <= stateCoobufBIdle;
				end if;

			elsif stateCoobufB=stateCoobufBIdle then
				if reqCoobufToHostif='1' then
					stateCoobufB <= stateCoobufBXferA;
				end if;

			elsif stateCoobufB=stateCoobufBXferA then
				stateCoobufB <= stateCoobufBXferB;

			elsif stateCoobufB=stateCoobufBXferB then
				if coobufToHostifAXIS_tready='1' then
					if aCoobufB=2*1024/8-1 then
						stateCoobufB <= stateCoobufBDone;

					else
						aCoobufB <= aCoobufB + 1; -- IP impl.coobufB.xferB.inc --- ILINE

						stateCoobufB <= stateCoobufBXferA;
					end if;

				elsif reqCoobufToHostif='0' then
					stateCoobufB <= stateCoobufBInit;
				end if;

			elsif stateCoobufB=stateCoobufBDone then
				if dneCoobufToHostif='1' then
					stateCoobufB <= stateCoobufBInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.coobufB.rising --- END

	------------------------------------------------------------------------
	-- implementation: Harris corner detection and score pipeline operation (corner)
	------------------------------------------------------------------------

	-- IP impl.corner.wiring --- BEGIN
	-- IP impl.corner.wiring --- END

	-- IP impl.corner.wiring.cust --- LINE

	-- IP impl.corner.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.corner.vars --- RBEGIN
		variable col_lcl: natural range 0 to 1999;
		variable postcol_lcl: natural range 0 to 1999;
		-- IP impl.corner.vars --- REND

	begin
		if reset='1' then
			-- IP impl.corner.asyncrst --- BEGIN
			stateCorner <= stateCornerInit;
			dIgrm1 <= (others => '0');
			lat <= 22;
			ceScore <= '0';
			abcde <= 0;
			dx <= (others => '0');
			dy <= (others => '0');

			-- IP impl.corner.asyncrst --- END
			-- IP impl.corner.asyncrst.cust --- IBEGIN
			col_lcl := 0;
			postcol_lcl := 0;
			-- IP impl.corner.asyncrst.cust --- IEND

		elsif rising_edge(mclk) then
			if (stateCorner=stateCornerInit or rng='0') then
				-- IP impl.corner.syncrst --- BEGIN
				dIgrm1 <= (others => '0');
				lat <= 22;
				ceScore <= '0';
				abcde <= 0;
				dx <= (others => '0');
				dy <= (others => '0');

				-- IP impl.corner.syncrst --- END
				-- IP impl.corner.syncrst.cust --- IBEGIN
				col_lcl := 0;
				postcol_lcl := 0;
				-- IP impl.corner.syncrst.cust --- IEND

				if (rng='1' and vsync='1') then
					stateCorner <= stateCornerRun;

				else
					stateCorner <= stateCornerInit;
				end if;

			elsif stateCorner=stateCornerRun then
				-- IP impl.corner.run.pre --- IBEGIN
				if ceScore='1' then
					if abcde=4 then
						abcde <= 0;
					else
						abcde <= abcde + 1;
					end if;
				end if;
				-- IP impl.corner.run.pre --- IEND

				if (vsync='0' and grayFromVideoinAXIS_tvalid='1') then
					-- IP impl.corner.run --- IBEGIN
					for i in 0 to 4 loop
						dx((4-i+1)*9-1 downto (4-i)*9) <= std_logic_vector(signed('0' & grayFromVideoinAXIS_tdata((4-i)*12+11 downto (4-i)*12+4)) - signed('0' & dIgrm1((4-i)*8+7 downto (4-i)*8)));
						dy((4-i+1)*9-1 downto (4-i)*9) <= std_logic_vector(signed('0' & grayFromVideoinAXIS_tdata((4-i)*12+11 downto (4-i)*12+4)) - signed('0' & grayFromVideoinAXIS_tdata((4-i+1)*12+11 downto (4-i+1)*12+4)));
					end loop;

					for i in 0 to 5 loop
						dIgrm1(i*8+7 downto i*8) <= grayFromVideoinAXIS_tdata(i*12+11 downto i*12+4);
					end loop;

					ceScore <= '1';

					col_lcl := col_lcl + 1;
					-- IP impl.corner.run --- IEND

					if grayFromVideoinAXIS_tlast='1' then
						postcol_lcl := 0; -- IP impl.corner.run.done --- ILINE

						if sprsNotFull='0' then
							stateCorner <= stateCornerEolA;

						else
							stateCorner <= stateCornerEolB;
						end if;

					else
						stateCorner <= stateCornerRun;
					end if;

				else
					ceScore <= '0'; -- IP impl.corner.run.reset --- ILINE

					stateCorner <= stateCornerRun;
				end if;

			elsif stateCorner=stateCornerEolA then
				if postcol_lcl=lat+2 then
					ceScore <= '0'; -- IP impl.corner.eolA.reset --- ILINE

					if vsync='1' then
						stateCorner <= stateCornerInit;

					else
						-- IP impl.corner.eolA.restart --- IBEGIN
						abcde <= 0;

						col_lcl := 0;
						-- IP impl.corner.eolA.restart --- IEND

						stateCorner <= stateCornerRun;
					end if;

				else
					-- IP impl.corner.eolA.inc --- IBEGIN
					ceScore <= '1';

					postcol_lcl := postcol_lcl + 1;
					-- IP impl.corner.eolA.inc --- IEND

					if sprsNotFull='0' then
						stateCorner <= stateCornerEolA;

					else
						stateCorner <= stateCornerEolB;
					end if;
				end if;

			elsif stateCorner=stateCornerEolB then
				ceScore <= '0'; -- IP impl.corner.eolB --- ILINE

				stateCorner <= stateCornerEolA;
			end if;
		end if;
	end process;
	-- IP impl.corner.rising --- END

	------------------------------------------------------------------------
	-- implementation: intermediate result streaming operation (imdstream)
	------------------------------------------------------------------------

	-- IP impl.imdstream.wiring --- BEGIN
	getInfoScoreMin <= scoreMin;
	getInfoScoreMax <= scoreMax;

	enImd0buf <= '1' when (enImdbuf='1' and fghij=0) else '0';
	enImd1buf <= '1' when (enImdbuf='1' and fghij=1) else '0';
	enImd2buf <= '1' when (enImdbuf='1' and fghij=2) else '0';
	enImd3buf <= '1' when (enImdbuf='1' and fghij=3) else '0';
	enImd4buf <= '1' when (enImdbuf='1' and fghij=4) else '0';

	aImdbuf_vec <= std_logic_vector(to_unsigned(aImdbuf, 11));

	aImdbufB_vec <= std_logic_vector(to_unsigned(aImdbufB, 11));
	-- IP impl.imdstream.wiring --- END

	-- IP impl.imdstream.wiring.cust --- LINE

	-- IP impl.imdstream.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.imdstream.vars --- RBEGIN
		variable col_lcl: natural range 0 to 2000-1;

		variable shift_lcl: natural range 0 to 47;

		variable scoreMin_lcl: std_logic_vector(7 downto 0);
		variable scoreMax_lcl: std_logic_vector(7 downto 0);
		-- IP impl.imdstream.vars --- REND

	begin
		if reset='1' then
			-- IP impl.imdstream.asyncrst --- BEGIN
			stateImdstream <= stateImdstreamInit;
			shift <= 0;
			scoreMin <= (others => '1');
			scoreMax <= (others => '0');
			ceMaxsel <= '0';
			fghij <= 0;
			enImdbuf <= '0';
			aImdbuf <= 0;
			enImdbufB <= '0';
			aImdbufB <= 0;
			dImd <= (others => '0');

			-- IP impl.imdstream.asyncrst --- END
			-- IP impl.imdstream.asyncrst.cust --- IBEGIN
			col_lcl := 0;
			shift_lcl := 0;
			scoreMin_lcl := (others => '1');
			scoreMax_lcl := (others => '0');
			-- IP impl.imdstream.asyncrst.cust --- IEND

		elsif rising_edge(mclk) then
			if (stateImdstream=stateImdstreamInit or rng='0') then
				-- IP impl.imdstream.syncrst --- BEGIN
				shift <= 0;
				scoreMin <= (others => '1');
				scoreMax <= (others => '0');
				ceMaxsel <= '0';
				fghij <= 0;
				enImdbuf <= '0';
				aImdbuf <= 0;
				enImdbufB <= '0';
				aImdbufB <= 0;
				dImd <= (others => '0');

				-- IP impl.imdstream.syncrst --- END
				-- IP impl.imdstream.syncrst.cust --- IBEGIN
				col_lcl := 0;
				shift_lcl := 0;
				scoreMin_lcl := (others => '1');
				scoreMax_lcl := (others => '0');
				-- IP impl.imdstream.syncrst.cust --- IEND

				if (rng='1' and (vsync='1' and tixVState/=tixVStateLock)) then
					stateImdstream <= stateImdstreamSkip;

				else
					stateImdstream <= stateImdstreamInit;
				end if;

			elsif stateImdstream=stateImdstreamSkip then
				if ceScore='1' then
					if col_lcl=lat then
						col_lcl := 0; -- IP impl.imdstream.skip.done --- ILINE

						stateImdstream <= stateImdstreamRun;

					else
						col_lcl := col_lcl + 1; -- IP impl.imdstream.skip.inc --- ILINE

						stateImdstream <= stateImdstreamSkip;
					end if;
				end if;

			elsif stateImdstream=stateImdstreamRun then
				if ceScore='1' then
					-- IP impl.imdstream.run --- IBEGIN
					-- min/max update
					if unsigned(rexp)<unsigned(scoreMin_lcl) then
						scoreMin_lcl := rexp;
					end if;
					
					if unsigned(rexp)>unsigned(scoreMax_lcl) then
						scoreMax_lcl := rexp;
					end if;
					
					if rshift>shift_lcl then
						shift_lcl := rshift;
					end if;

					-- store
					enImdbuf <= '1';

					-- load
					enImdbufB <= '1';

					if col_lcl>0 then
						ceMaxsel <= '1';

						case fghij is
							when 3 =>
								dImd <= drdImd0bufB & drdImd1bufB & drdImd2bufB & drdImd3bufB & drdImd4bufB;
							when 4 =>
								dImd <= drdImd1bufB & drdImd2bufB & drdImd3bufB & drdImd4bufB & drdImd0bufB;
							when 0 =>
								dImd <= drdImd2bufB & drdImd3bufB & drdImd4bufB & drdImd0bufB & drdImd1bufB;
							when 1 =>
								dImd <= drdImd3bufB & drdImd4bufB & drdImd0bufB & drdImd1bufB & drdImd2bufB;
							when 2 =>
								dImd <= drdImd4bufB & drdImd0bufB & drdImd1bufB & drdImd2bufB & drdImd3bufB;
							when others =>
						end case;
					end if;

					if fghij=4 then
						fghij <= 0;
					else
						fghij <= fghij + 1;
					end if;

					if col_lcl/=0 and col_lcl/=colLast then
						aImdbuf <= aImdbuf + 1;
						aImdbufB <= aImdbufB + 1;
					end if;
					-- IP impl.imdstream.run --- IEND

					if col_lcl=colLast then
						stateImdstream <= stateImdstreamEol;

					else
						col_lcl := col_lcl + 1; -- IP impl.imdstream.run.nextCol --- ILINE

						if sprsNotFull='0' then
							stateImdstream <= stateImdstreamRun;

						else
							stateImdstream <= stateImdstreamHold;
						end if;
					end if;
				end if;

			elsif stateImdstream=stateImdstreamHold then
				-- IP impl.imdstream.hold --- IBEGIN
				enImdbuf <= '0';
				enImdbufB <= '0';

				ceMaxsel <= '0';
				-- IP impl.imdstream.hold --- IEND

				stateImdstream <= stateImdstreamRun;

			elsif stateImdstream=stateImdstreamEol then
				-- IP impl.imdstream.eol.pre --- IBEGIN
				enImdbuf <= '0';
				enImdbufB <= '0';

				ceMaxsel <= '0';
				-- IP impl.imdstream.eol.pre --- IEND

				if vsync='1' then
					-- IP impl.imdstream.eol.done --- IBEGIN
					if shift_lcl>=40 then
						shift <= 40;
					else
						shift <= shift_lcl;
					end if;

					scoreMin <= scoreMin_lcl;
					scoreMax <= scoreMax_lcl;
					-- IP impl.imdstream.eol.done --- IEND

					stateImdstream <= stateImdstreamInit;

				else
					-- IP impl.imdstream.eol.restart --- IBEGIN
					fghij <= 0;

					aImdbuf <= 0;
					aImdbufB <= 0;

					col_lcl := 0;
					-- IP impl.imdstream.eol.restart --- IEND

					stateImdstream <= stateImdstreamSkip;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.imdstream.rising --- END

	------------------------------------------------------------------------
	-- implementation: intermediate result streaming operation (maxsel)
	------------------------------------------------------------------------

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

	aCoobuf_vec <= std_logic_vector(to_unsigned(aCoobuf, 9));
	-- IP impl.maxsel.wiring --- END

	-- IP impl.maxsel.wiring.cust --- LINE

	-- IP impl.maxsel.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.maxsel.vars --- RBEGIN
		variable postNotLive: boolean;
		
		constant imax: natural := 2; -- post-live cycles
		variable i: natural range 0 to imax;

		variable colmax_lcl: natural range 0 to 4;

		variable row_lcl: natural range 0 to 1500-1;
		variable col_lcl: natural range 0 to 2000-1;

		variable d0_1, d0_2, d0_3, d0_4, d1_2, d1_3, d1_4, d2_3, d2_4, d3_4: signed(8 downto 0);
		variable ge0_1, ge0_2, ge0_3, ge0_4, ge1_2, ge1_3, ge1_4, ge2_3, ge2_4, ge3_4: boolean;
		variable eq0, eq1, eq2, eq3, eq4: boolean; -- equal to any of the other elements

		variable e0_1, e0_2, e0_3, e0_4, e1_2, e1_3, e1_4, e2_3, e2_4, e3_4: signed(8 downto 0);
		variable gf0_1, gf0_2, gf0_3, gf0_4, gf1_2, gf1_3, gf1_4, gf2_3, gf2_4, gf3_4: boolean;
		variable er0, er1, er2, er3, er4: boolean; -- equal to any of the other elements

		variable flag: boolean;
		-- IP impl.maxsel.vars --- REND

	begin
		if reset='1' then
			-- IP impl.maxsel.asyncrst --- RBEGIN
			stateMaxsel <= stateMaxselInit;
			tkst <= (others => '0');
			maximds <= (others => (others => '0'));
			ixMaximds <= (others => 0);
			ixMaximdsm1 <= (others => 0);
			unqMaximds <= (others => false);
			unqMaximdsm1 <= (others => false);
			ixMax <= 0;
			unqMax <= false;
			enCoobuf <= '0';
			aCoobuf <= 0;
			dwrCoobuf <= (others => '0');

			postNotLive := false;
			i := 0;
			colmax_lcl := 0;
			row_lcl := 0;
			col_lcl := 0;
			-- IP impl.maxsel.asyncrst --- REND
			-- IP impl.maxsel.asyncrst.cust --- INSERT

		elsif rising_edge(mclk) then
			if (stateMaxsel=stateMaxselInit or rng='0') then
				-- IP impl.maxsel.syncrst --- RBEGIN
				maximds <= (others => (others => '0'));
				ixMaximds <= (others => 0);
				ixMaximdsm1 <= (others => 0);
				unqMaximds <= (others => false);
				unqMaximdsm1 <= (others => false);

				ixMax <= 0;
				unqMax <= false;

				enCoobuf <= '0';
				aCoobuf <= 0;
				dwrCoobuf <= (others => '0');

				postNotLive := false;

				i := 0;

				colmax_lcl := 0;

				row_lcl := 0;
				col_lcl := 0;
				-- IP impl.maxsel.syncrst --- REND
				-- IP impl.maxsel.syncrst.cust --- INSERT

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

					stateMaxsel <= stateMaxselRun;

				else
					stateMaxsel <= stateMaxselInit;
				end if;

			elsif stateMaxsel=stateMaxselRun then
				-- IP impl.maxsel.run.pre --- IBEGIN
				if enCoobuf='1' then
					aCoobuf <= aCoobuf + 1;
				end if;
				-- IP impl.maxsel.run.pre --- IEND

				if ceMaxsel='1' or postNotLive then
					-- IP impl.maxsel.run --- IBEGIN
					-- find maximum element in incoming column
					d0_1 := signed('0' & dImd(39 downto 32)) - signed('0' & dImd(31 downto 24));
					ge0_1 := (d0_1(8) = '0');
					d0_2 := signed('0' & dImd(39 downto 32)) - signed('0' & dImd(23 downto 16));
					ge0_2 := (d0_2(8) = '0');
					d0_3 := signed('0' & dImd(39 downto 32)) - signed('0' & dImd(15 downto 8));
					ge0_3 := (d0_3(8) = '0');
					d0_4 := signed('0' & dImd(39 downto 32)) - signed('0' & dImd(7 downto 0));
					ge0_4 := (d0_4(8) = '0');

					eq0 := ((d0_1 = 0) or (d0_2 = 0) or (d0_3 = 0) or (d0_4 = 0));

					d1_2 := signed('0' & dImd(31 downto 24)) - signed('0' & dImd(23 downto 16));
					ge1_2 := (d1_2(8) = '0');
					d1_3 := signed('0' & dImd(31 downto 24)) - signed('0' & dImd(15 downto 8));
					ge1_3 := (d1_3(8) = '0');
					d1_4 := signed('0' & dImd(31 downto 24)) - signed('0' & dImd(7 downto 0));
					ge1_4 := (d1_4(8) = '0');

					eq1 := ((d0_1 = 0) or (d1_2 = 0) or (d1_3 = 0) or (d1_4 = 0));

					d2_3 := signed('0' & dImd(23 downto 16)) - signed('0' & dImd(15 downto 8));
					ge2_3 := (d2_3(8) = '0');
					d2_4 := signed('0' & dImd(23 downto 16)) - signed('0' & dImd(7 downto 0));
					ge2_4 := (d2_4(8) = '0');

					eq2 := ((d0_2 = 0) or (d1_2 = 0) or (d2_3 = 0) or (d2_4 = 0));

					d3_4 := signed('0' & dImd(15 downto 8)) - signed('0' & dImd(7 downto 0));
					ge3_4 := (d3_4(8) = '0');

					eq3 := ((d0_3 = 0) or (d1_3 = 0) or (d2_3 = 0) or (d3_4 = 0));

					eq4 := ((d0_4 = 0) or (d1_4 = 0) or (d2_4 = 0) or (d3_4 = 0));

					if (ge0_1 and ge0_2 and ge0_3 and ge0_4) then
						maximds(colmax_lcl) <= dImd(39 downto 32);
						ixMaximds(colmax_lcl) <= 0;
						unqMaximds(colmax_lcl) <= eq0;

					elsif (not ge0_1 and ge1_2 and ge1_3 and ge1_4) then
						maximds(colmax_lcl) <= dImd(31 downto 24);
						ixMaximds(colmax_lcl) <= 1;
						unqMaximds(colmax_lcl) <= eq1;

					elsif (not ge0_2 and not ge1_2 and ge2_3 and ge2_4) then
						maximds(colmax_lcl) <= dImd(23 downto 16);
						ixMaximds(colmax_lcl) <= 2;
						unqMaximds(colmax_lcl) <= eq2;

					elsif (not ge0_3 and not ge1_3 and not ge2_3 and ge3_4) then
						maximds(colmax_lcl) <= dImd(15 downto 8);
						ixMaximds(colmax_lcl) <= 3;
						unqMaximds(colmax_lcl) <= eq3;

					else
						maximds(colmax_lcl) <= dImd(7 downto 0);
						ixMaximds(colmax_lcl) <= 4;
						unqMaximds(colmax_lcl) <= eq4;
					end if;

					maximdsm1 <= maximds;
					ixMaximdsm1 <= ixMaximds;
					unqMaximdsm1 <= unqMaximds;

					-- find maximum among columns
					-- insufficient to just check if new maximd is max because current max might be overwritten (with a non-max)
					e0_1 := signed('0' & maximds(0)) - signed('0' & maximds(1));
					gf0_1 := (e0_1(8) = '0');
					e0_2 := signed('0' & maximds(0)) - signed('0' & maximds(2));
					gf0_2 := (e0_2(8) = '0');
					e0_3 := signed('0' & maximds(0)) - signed('0' & maximds(3));
					gf0_3 := (e0_3(8) = '0');
					e0_4 := signed('0' & maximds(0)) - signed('0' & maximds(4));
					gf0_4 := (e0_4(8) = '0');

					er0 := ((e0_1 = 0) or (e0_2 = 0) or (e0_3 = 0) or (e0_4 = 0));

					e1_2 := signed('0' & maximds(1)) - signed('0' & maximds(2));
					gf1_2 := (e1_2(8) = '0');
					e1_3 := signed('0' & maximds(1)) - signed('0' & maximds(3));
					gf1_3 := (e1_3(8) = '0');
					e1_4 := signed('0' & maximds(1)) - signed('0' & maximds(4));
					gf1_4 := (e1_4(8) = '0');

					er1 := ((e0_1 = 0) or (e1_2 = 0) or (e1_3 = 0) or (e1_4 = 0));

					e2_3 := signed('0' & maximds(2)) - signed('0' & maximds(3));
					gf2_3 := (e2_3(8) = '0');
					e2_4 := signed('0' & maximds(2)) - signed('0' & maximds(4));
					gf2_4 := (e2_4(8) = '0');

					er2 := ((e0_2 = 0) or (e1_2 = 0) or (e2_3 = 0) or (e2_4 = 0));

					e3_4 := signed('0' & maximds(3)) - signed('0' & maximds(4));
					gf3_4 := (e3_4(8) = '0');

					er3 := ((e0_3 = 0) or (e1_3 = 0) or (e2_3 = 0) or (e3_4 = 0));

					er4 := ((e0_4 = 0) or (e1_4 = 0) or (e2_4 = 0) or (e3_4 = 0));

					if (gf0_1 and gf0_2 and gf0_3 and gf0_4) then
						ixMax <= 0;
						unqMax <= er0;

					elsif (not gf0_1 and gf1_2 and gf1_3 and gf1_4) then
						ixMax <= 1;
						unqMax <= er1;

					elsif (not gf0_2 and not gf1_2 and gf2_3 and gf2_4) then
						ixMax <= 2;
						unqMax <= er2;

					elsif (not gf0_3 and not gf1_3 and not gf2_3 and gf3_4) then
						ixMax <= 3;
						unqMax <= er3;

					else
						ixMax <= 4;
						unqMax <= er4;
					end if;

					-- flag and store
					flag := false;

--					if unqMax then
--						if (colmax_lcl=0 and ixMax=3 and unqMaximdsm1(3) and unsigned(maximdsm1(3))>thd) then
--							flag := '1';
--						elsif (colmax_lcl=1 and ixMax=4 and unqMaximdsm1(4) and unsigned(maximdsm1(4))>thd) then
--							flag := '1';
--						elsif (colmax_lcl=2 and ixMax=0 and unqMaximdsm1(0) and unsigned(maximdsm1(0))>thd) then
--							flag := '1';
--						elsif (colmax_lcl=3 and ixMax=1 and unqMaximdsm1(1) and unsigned(maximdsm1(1))>thd) then
--							flag := '1';
--						elsif (colmax_lcl=4 and ixMax=2 and unqMaximdsm1(2) and unsigned(maximdsm1(2))>thd) then
--							flag := '1';
--						end if;
--					end if;
					if (colmax_lcl=0 and ixMax=3 and unsigned(maximdsm1(3))>thd) then
						flag := true;
					elsif (colmax_lcl=1 and ixMax=4 and unsigned(maximdsm1(4))>thd) then
						flag := true;
					elsif (colmax_lcl=2 and ixMax=0 and unsigned(maximdsm1(0))>thd) then
						flag := true;
					elsif (colmax_lcl=3 and ixMax=1 and unsigned(maximdsm1(1))>thd) then
						flag := true;
					elsif (colmax_lcl=4 and ixMax=2 and unsigned(maximdsm1(2))>thd) then
						flag := true;
					end if;

					if col_lcl<col0 or col_lcl>col1 or row_lcl<row0 or row_lcl>row1 or aCoobuf=2*1024/4-1 then
						flag := false;
					end if;

					if flag then
						enCoobuf <= '1';

						dwrCoobuf(31 downto 16) <= std_logic_vector(to_unsigned(row_lcl, 16));
						dwrCoobuf(15 downto 0) <= std_logic_vector(to_unsigned(col_lcl, 16));

					else
						enCoobuf <= '0';
					end if;

					if colmax_lcl=4 then
						colmax_lcl := 0;
					else
						colmax_lcl := colmax_lcl + 1;
					end if;
					-- IP impl.maxsel.run --- IEND

					if col_lcl+imax=colLast then
						if not postNotLive then
							-- IP impl.maxsel.run.toPost --- IBEGIN
							postNotLive := true;
							i := 0;
							-- IP impl.maxsel.run.toPost --- IEND

							stateMaxsel <= stateMaxselRun;

						else
							if i=imax then
								stateMaxsel <= stateMaxselEol;

							else
								i := i + 1; -- IP impl.maxsel.run.inc --- ILINE

								stateMaxsel <= stateMaxselRun;
							end if;
						end if;

					else
						col_lcl := col_lcl + 1; -- IP impl.maxsel.run.nextCol --- ILINE

						stateMaxsel <= stateMaxselRun;
					end if;

				else
					enCoobuf <= '0'; -- IP impl.maxsel.run.reset --- ILINE

					stateMaxsel <= stateMaxselRun;
				end if;

			elsif stateMaxsel=stateMaxselEol then
				if (row_lcl=rowLast or vsync='1') then
					-- IP impl.maxsel.eol.done --- IBEGIN
					enCoobuf <= '1';
					dwrCoobuf <= (others => '1');
					-- IP impl.maxsel.eol.done --- IEND

					stateMaxsel <= stateMaxselInit;

				else
					-- IP impl.maxsel.eol.nextRow --- IBEGIN
					row_lcl := row_lcl + 1;

					maximds <= (others => (others => '0'));
					ixMaximds <= (others => 0);
					ixMaximdsm1 <= (others => 0);
					unqMaximds <= (others => false);
					unqMaximdsm1 <= (others => false);

					ixMax <= 0;
					unqMax <= false;

					enCoobuf <= '0';

					postNotLive := false;

					colmax_lcl := 0;
					col_lcl := 0;
					-- IP impl.maxsel.eol.nextRow --- IEND

					stateMaxsel <= stateMaxselRun;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.maxsel.rising --- END

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

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

	getInfoTixVState <= tixVState;

	colLast <= to_integer(unsigned(NCol) - 1);
	rowLast <= to_integer(unsigned(NRow) - 1);
	-- 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 vsync_last: std_logic;
		-- IP impl.op.vars --- REND

	begin
		if reset='1' then
			-- IP impl.op.asyncrst --- RBEGIN
			stateOp <= stateOpInit;
			ackInvAcquire_sig <= '0';
			ackInvConfig_sig <= '0';
			ackInvSet_sig <= '0';
			ackInvUnlock_sig <= '0';
			rng <= '0';
			tixVState <= (others => '0');
			linNotLog <= '0';
			thd <= 80;
			row0 <= 0;
			row1 <= 1499;
			col0 <= 0;
			col1 <= 1999;

			vsync_last := '0';
			-- IP impl.op.asyncrst --- REND
			-- IP impl.op.asyncrst.cust --- INSERT

		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 tixVState=tixVStateIdle then
						tixVState <= tixVStateAcq;
					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 configLinNotLog=tru8 then
						linNotLog <= '1';
					else
						linNotLog <= '0';
					end if;
					thd <= to_integer(unsigned(configThd));
					row0 <= to_integer(unsigned(configRow0));
					row1 <= to_integer(unsigned(configRow1));
					col0 <= to_integer(unsigned(configCol0));
					col1 <= to_integer(unsigned(configCol1));

					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;

					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';

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

					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' 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: Harris score pipeline operation (score)
	------------------------------------------------------------------------

	-- IP impl.score.wiring --- BEGIN
	-- IP impl.score.wiring --- END

	-- IP impl.score.wiring.cust --- LINE

	-- IP impl.score.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.score.vars --- RBEGIN
		variable x: unsigned(50 downto 0);

		variable msb: natural range 0 to 47;
		-- IP impl.score.vars --- REND

	begin
		if reset='1' then
			-- IP impl.score.asyncrst --- BEGIN
			stateScore <= stateScoreInit;
			xsqr <= (others => '0');
			ysqr <= (others => '0');
			xy <= (others => '0');
			colsumXA <= (others => '0');
			colsumYA <= (others => '0');
			colsumXYA <= (others => '0');
			xsqr4p1 <= (others => '0');
			xsqr4p2 <= (others => '0');
			ysqr4p1 <= (others => '0');
			ysqr4p2 <= (others => '0');
			xy4p1 <= (others => '0');
			xy4p2 <= (others => '0');
			colsumXB <= (others => '0');
			colsumYB <= (others => '0');
			colsumXYB <= (others => '0');
			colsumXC <= (others => '0');
			colsumYC <= (others => '0');
			colsumXYC <= (others => '0');
			colsumX <= (others => '0');
			colsumY <= (others => '0');
			colsumXY <= (others => '0');
			sumXA <= (others => '0');
			sumYA <= (others => '0');
			sumXYA <= (others => '0');
			colsumX4p1 <= (others => '0');
			colsumX4p2 <= (others => '0');
			colsumY4p1 <= (others => '0');
			colsumY4p2 <= (others => '0');
			colsumXY4p1 <= (others => '0');
			colsumXY4p2 <= (others => '0');
			sumXB <= (others => '0');
			sumYB <= (others => '0');
			sumXYB <= (others => '0');
			sumX <= (others => '0');
			sumY <= (others => '0');
			sumXY <= (others => '0');
			sumIII <= (others => '0');
			termI <= (others => '0');
			termII <= (others => '0');
			termIII <= (others => '0');
			diffI_II <= (others => '0');
			termIIIk <= (others => '0');
			diffI_IIp1 <= (others => '0');
			r <= (others => '0');
			rexp <= (others => '0');
			rshift <= 0;

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

		elsif rising_edge(mclk) then
			if stateScore=stateScoreInit then
				-- IP impl.score.syncrst --- BEGIN
				xsqr <= (others => '0');
				ysqr <= (others => '0');
				xy <= (others => '0');
				colsumXA <= (others => '0');
				colsumYA <= (others => '0');
				colsumXYA <= (others => '0');
				xsqr4p1 <= (others => '0');
				xsqr4p2 <= (others => '0');
				ysqr4p1 <= (others => '0');
				ysqr4p2 <= (others => '0');
				xy4p1 <= (others => '0');
				xy4p2 <= (others => '0');
				colsumXB <= (others => '0');
				colsumYB <= (others => '0');
				colsumXYB <= (others => '0');
				colsumXC <= (others => '0');
				colsumYC <= (others => '0');
				colsumXYC <= (others => '0');
				colsumX <= (others => '0');
				colsumY <= (others => '0');
				colsumXY <= (others => '0');
				sumXA <= (others => '0');
				sumYA <= (others => '0');
				sumXYA <= (others => '0');
				colsumX4p1 <= (others => '0');
				colsumX4p2 <= (others => '0');
				colsumY4p1 <= (others => '0');
				colsumY4p2 <= (others => '0');
				colsumXY4p1 <= (others => '0');
				colsumXY4p2 <= (others => '0');
				sumXB <= (others => '0');
				sumYB <= (others => '0');
				sumXYB <= (others => '0');
				sumX <= (others => '0');
				sumY <= (others => '0');
				sumXY <= (others => '0');
				sumIII <= (others => '0');
				termI <= (others => '0');
				termII <= (others => '0');
				termIII <= (others => '0');
				diffI_II <= (others => '0');
				termIIIk <= (others => '0');
				diffI_IIp1 <= (others => '0');
				r <= (others => '0');
				rexp <= (others => '0');
				rshift <= 0;

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

				stateScore <= stateScoreRun;

			elsif stateScore=stateScoreRun then
				-- IP impl.score.run --- IBEGIN
				if ceScore='1' then
					-- stage 1 (replaces dxsqr, dysqr, xy)
					for i in 0 to 4 loop
						xsqr(i*18+17 downto i*18) <= std_logic_vector(signed(dx(i*9+8 downto i*9)) * signed(dx(i*9+8 downto i*9)));
						ysqr(i*18+17 downto i*18) <= std_logic_vector(signed(dy(i*9+8 downto i*9)) * signed(dy(i*9+8 downto i*9)));
						xy(i*18+17 downto i*18) <= std_logic_vector(signed(dx(i*9+8 downto i*9)) * signed(dy(i*9+8 downto i*9)));
					end loop;

					-- stage 2 (replaces colsumXA, colsumYA, colsumXYA)
					for i in 0 to 1 loop
						colsumXA(i*19+18 downto i*19) <= std_logic_vector(resize(signed(xsqr(2*i*18+35 downto 2*i*18+18)), 19) + resize(signed(xsqr(2*i*18+17 downto 2*i*18)), 19));
						colsumYA(i*19+18 downto i*19) <= std_logic_vector(resize(signed(ysqr(2*i*18+35 downto 2*i*18+18)), 19) + resize(signed(ysqr(2*i*18+17 downto 2*i*18)), 19));
						colsumXYA(i*19+18 downto i*19) <= std_logic_vector(resize(signed(xy(2*i*18+35 downto 2*i*18+18)), 19) + resize(signed(xy(2*i*18+17 downto 2*i*18)), 19));
					end loop;
					xsqr4p1 <= xsqr(4*18+17 downto 4*18);
					ysqr4p1 <= ysqr(4*18+17 downto 4*18);
					xy4p1 <= xy(4*18+17 downto 4*18);

					-- stage 3 (replaces colsumXB, colsumYB, colsumXYB)
					colsumXB <= std_logic_vector(resize(signed(colsumXA(37 downto 19)), 20) + resize(signed(colsumXA(18 downto 0)), 20));
					colsumYB <= std_logic_vector(resize(signed(colsumYA(37 downto 19)), 20) + resize(signed(colsumYA(18 downto 0)), 20));
					colsumXYB <= std_logic_vector(resize(signed(colsumXYA(37 downto 19)), 20) + resize(signed(colsumXYA(18 downto 0)), 20));
					xsqr4p2 <= xsqr4p1;
					ysqr4p2 <= ysqr4p1;
					xy4p2 <= xy4p1;

					-- stage 4 (replaces colsumXC, colsumYC, colsumXYC)
					colsumXC <= std_logic_vector(resize(signed(colsumXB), 21) + resize(signed(xsqr4p2), 21));
					colsumYC <= std_logic_vector(resize(signed(colsumYB), 21) + resize(signed(ysqr4p2), 21));
					colsumXYC <= std_logic_vector(resize(signed(colsumXYB), 21) + resize(signed(xy4p2), 21));

					-- stage 5 (replaces FSM copy)
					if abcde=0 then
						colsumX((4-4+1)*21-1 downto (4-4)*21) <= colsumXC;
						colsumY((4-4+1)*21-1 downto (4-4)*21) <= colsumYC;
						colsumXY((4-4+1)*21-1 downto (4-4)*21) <= colsumXYC;
					elsif abcde=1 then
						colsumX((4-0+1)*21-1 downto (4-0)*21) <= colsumXC;
						colsumY((4-0+1)*21-1 downto (4-0)*21) <= colsumYC;
						colsumXY((4-0+1)*21-1 downto (4-0)*21) <= colsumXYC;
					elsif abcde=2 then
						colsumX((4-1+1)*21-1 downto (4-1)*21) <= colsumXC;
						colsumY((4-1+1)*21-1 downto (4-1)*21) <= colsumYC;
						colsumXY((4-1+1)*21-1 downto (4-1)*21) <= colsumXYC;
					elsif abcde=3 then
						colsumX((4-2+1)*21-1 downto (4-2)*21) <= colsumXC;
						colsumY((4-2+1)*21-1 downto (4-2)*21) <= colsumYC;
						colsumXY((4-2+1)*21-1 downto (4-2)*21) <= colsumXYC;
					elsif abcde=4 then
						colsumX((4-3+1)*21-1 downto (4-3)*21) <= colsumXC;
						colsumY((4-3+1)*21-1 downto (4-3)*21) <= colsumYC;
						colsumXY((4-3+1)*21-1 downto (4-3)*21) <= colsumXYC;
					end if;

					-- stage 6 (replaces sumXA, sumYA, sumXYA)
					for i in 0 to 1 loop
						sumXA(i*22+21 downto i*22) <= std_logic_vector(resize(signed(colsumX(2*i*21+41 downto 2*i*21+21)), 22) + resize(signed(colsumX(2*i*21+20 downto 2*i*21)), 22));
						sumYA(i*22+21 downto i*22) <= std_logic_vector(resize(signed(colsumY(2*i*21+41 downto 2*i*21+21)), 22) + resize(signed(colsumY(2*i*21+20 downto 2*i*21)), 22));
						sumXYA(i*22+21 downto i*22) <= std_logic_vector(resize(signed(colsumXY(2*i*21+41 downto 2*i*21+21)), 22) + resize(signed(colsumXY(2*i*21+20 downto 2*i*21)), 22));
					end loop;
					colsumX4p1 <= colsumX(4*21+20 downto 4*21);
					colsumY4p1 <= colsumY(4*21+20 downto 4*21);
					colsumXY4p1 <= colsumXY(4*21+20 downto 4*21);

					-- stage 7 (replaces sumXB, sumYB, sumXYB)
					sumXB <= std_logic_vector(resize(signed(sumXA(43 downto 22)), 23) + resize(signed(sumXA(21 downto 0)), 23));
					sumYB <= std_logic_vector(resize(signed(sumYA(43 downto 22)), 23) + resize(signed(sumYA(21 downto 0)), 23));
					sumXYB <= std_logic_vector(resize(signed(sumXYA(43 downto 22)), 23) + resize(signed(sumXYA(21 downto 0)), 23));
					colsumX4p2 <= colsumX4p1;
					colsumY4p2 <= colsumY4p1;
					colsumXY4p2 <= colsumXY4p1;

					-- stage 8 (replaces sumX, sumY, sumXY); max. sum is of 25 18-bit elements, thus 23 bit result is sufficient
					sumX <= std_logic_vector(signed(sumXB) + resize(signed(colsumX4p2), 23));
					sumY <= std_logic_vector(signed(sumYB) + resize(signed(colsumY4p2), 23));
					sumXY <= std_logic_vector(signed(sumXYB) + resize(signed(colsumXY4p2), 23));

					-- stage 9 (replaces sumIII, termII, termI)
					sumIII <= std_logic_vector(resize(signed(sumX), 24) + resize(signed(sumY), 24));
					termII <= std_logic_vector(signed(sumXY) * signed(sumXY));
					termI <= std_logic_vector(signed(sumX) * signed(sumY));

					-- stage 10 (replaces termIII, diffI_II)
					termIII <= std_logic_vector(signed(sumIII) * signed(sumIII));
					diffI_II <= std_logic_vector(resize(signed(termI), 47) - resize(signed(termII), 47));

					-- stage 11 (replaces FSM factk)
					x := unsigned(std_logic_vector'(std_logic_vector'("0" & termIII) & "00")) + unsigned(std_logic_vector'("000" & termIII)); -- x5
					termIIIk <= std_logic_vector(x(50 downto 7)); -- /128

					diffI_IIp1 <= diffI_II;

					-- stage 12 (replaces r)
					r <= std_logic_vector(resize(signed(diffI_IIp1), 48) - resize(signed(termIIIk), 48));

					-- stage 13 (replaces FSM exp)
					for i in 0 to 47 loop
						if r(i)='1' then
							msb := i;
						end if;
					end loop;

					if linNotLog='0' then
						if msb<2 then
							rexp <= "000000" & r(1 downto 0);
						elsif msb=47 then
							rexp <= (others => '0');
						else
							rexp <= std_logic_vector(to_unsigned(msb-1, 6)) & r(msb-1 downto msb-2);
						end if;

					else
						if (msb<7 or msb=47) then
							rshift <= 0;
						else
							rshift <= msb - 7;
						end if;
	
						if msb=47 then
							rexp <= (others => '0');
						elsif msb<shift then
							rexp <= (others => '0');
						elsif msb>shift+7 then
							rexp <= (others => '1');
						else
							rexp <= r(shift+7 downto shift);
						end if;
					end if;
				end if;
				-- IP impl.score.run --- IEND
			end if;
		end if;
	end process;
	-- IP impl.score.rising --- END

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

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

end Rtl;
