-- file Hdreng.vhd
-- Hdreng 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.Tivsp.all;

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

		resetMemclk: in std_logic;
		memclk: in std_logic;

		hdrmemAXI_awaddr: out std_logic_vector(17 downto 0);
		hdrmemAXI_awready: in std_logic;
		hdrmemAXI_awvalid: out std_logic;
		hdrmemAXI_bready: out std_logic;
		hdrmemAXI_bresp: in std_logic_vector(1 downto 0);
		hdrmemAXI_bvalid: in std_logic;
		hdrmemAXI_wdata: out std_logic_vector(127 downto 0);
		hdrmemAXI_wlast: out std_logic;
		hdrmemAXI_wready: in std_logic;
		hdrmemAXI_wvalid: out std_logic;

		reqToDdrifWr: out std_logic;
		ackToDdrifWr: in std_logic;

		hdrmemAXI_araddr: out std_logic_vector(17 downto 0);
		hdrmemAXI_arready: in std_logic;
		hdrmemAXI_arvalid: out std_logic;
		hdrmemAXI_rdata: in std_logic_vector(127 downto 0);
		hdrmemAXI_rlast: in std_logic;
		hdrmemAXI_rready: out std_logic;
		hdrmemAXI_rresp: in std_logic_vector(1 downto 0);
		hdrmemAXI_rvalid: in std_logic;

		reqToDdrifRd: out std_logic;
		ackToDdrifRd: 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);

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

		reqInvAssign: in std_logic;
		ackInvAssign: out std_logic;

		assignIxMem: in std_logic_vector(7 downto 0);

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

		reqInvSet: in std_logic;
		ackInvSet: out std_logic;

		setRng: in std_logic_vector(7 downto 0);

		tkclksrcGetTkstTkst: in std_logic_vector(31 downto 0)
	);
end Hdreng;

architecture Rtl of Hdreng is

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

	component Dpbram_size8kB_a32b128 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(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(8 downto 0);
			drdB: out std_logic_vector(127 downto 0);
			dwrB: in std_logic_vector(127 downto 0)
		);
	end component;

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

	constant tixVStateIdle: std_logic_vector(7 downto 0) := x"00";

	constant ixMemInvalid: std_logic_vector(7 downto 0) := x"FF";

	constant tixVStateAcq: std_logic_vector(7 downto 0) := x"01";
	constant tixVStateStall: std_logic_vector(7 downto 0) := x"02";

	---- continuous streaming from buffers to DDR memory (egrstr)
	type stateEgrstr_t is (
		stateEgrstrInit,
		stateEgrstrIdle,
		stateEgrstrLoad,
		stateEgrstrRun,
		stateEgrstrDone
	);
	signal stateEgrstr: stateEgrstr_t;

	signal enRowbufBEgrstr: std_logic;
	signal enRowbufBEgrstrm1: std_logic;

	signal aRowbufBEgrstr: natural range 0 to 8*1024/16-1;
	signal drdRowbufB: std_logic_vector(127 downto 0);
	type egrfifo_t is array (0 to 2) of std_logic_vector(127 downto 0);
	signal egrfifo: egrfifo_t;

	signal ixRdEgrfifo: natural range 0 to 2;
	signal ixWrEgrfifo: natural range 0 to 2;

	signal egrAXIS_tdata: std_logic_vector(127 downto 0);
	signal egrAXIS_tlast: std_logic;

	-- IP sigs.egrstr.cust --- INSERT

	---- continuous streaming from DDR memory (igrstr)
	type stateIgrstr_t is (
		stateIgrstrInit,
		stateIgrstrIdle,
		stateIgrstrRun,
		stateIgrstrDone
	);
	signal stateIgrstr: stateIgrstr_t;

	signal aRowbufBIgrstr: natural;
	signal burstIgrstr: natural range 0 to 31;

	-- IP sigs.igrstr.cust --- INSERT

	---- live stream forwarding (livefwd)

	signal rgbFromVideoinAXIS_tvalidm1: std_logic;
	signal rgbFromVideoinAXIS_tvalidm2: std_logic;

	signal rgbFromVideoinAXIS_tdatam1: std_logic_vector(35 downto 0);
	signal rgbFromVideoinAXIS_tdatam2: std_logic_vector(35 downto 0);

	signal rgbFromVideoinAXIS_tlastm1: std_logic;
	signal rgbFromVideoinAXIS_tlastm2: std_logic;

	-- IP sigs.livefwd.cust --- INSERT

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

	signal ackInvAssign_sig: std_logic;
	signal ackInvSet_sig: std_logic;

	signal rng: std_logic;
	signal ixMemNext: std_logic_vector(7 downto 0);
	signal rowLast: natural range 0 to 1500-1;

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

	---- stock release from buffer operation (stockrls)
	type stateStockrls_t is (
		stateStockrlsInit,
		stateStockrlsRun,
		stateStockrlsEol
	);
	signal stateStockrls: stateStockrls_t;

	signal enRowbufStockrls: std_logic;
	signal aRowbufStockrls: natural range 0 to 8*1024/4-1;
	signal stock: std_logic_vector(31 downto 0);

	-- IP sigs.stockrls.cust --- INSERT

	---- streaming operation (stream)
	type stateStream_t is (
		stateStreamInit,
		stateStreamIdle,
		stateStreamRun,
		stateStreamEol
	);
	signal stateStream: stateStream_t;

	signal tixVState: std_logic_vector(7 downto 0);

	signal tkst: std_logic_vector(31 downto 0);
	signal ixMem: std_logic_vector(7 downto 0);

	signal tkstAcq: std_logic_vector(31 downto 0);
	signal ixMemAcq: std_logic_vector(7 downto 0);

	signal a0: std_logic_vector(4 downto 0); -- 12 slots with (8+4) MB spacing
	signal liveBNotA: std_logic;

	signal enRowAbuf: std_logic;
	signal enRowBbuf: std_logic;

	signal enRowbufStream: std_logic;

	signal weRowAbuf: std_logic;
	signal weRowBbuf: std_logic;

	signal aRowAbuf: std_logic_vector(10 downto 0);
	signal aRowBbuf: std_logic_vector(10 downto 0);

	signal aRowbufStream: natural range 0 to 8*1024/4-1;
	signal dwrRowbuf: std_logic_vector(31 downto 0);

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

	---- stock buffer swap to-then-from DDR memory (swap)
	type stateSwap_t is (
		stateSwapInit,
		stateSwapStart,
		stateSwapIdle,
		stateSwapEgrA, stateSwapEgrB, stateSwapEgrC,
		stateSwapIgrA, stateSwapIgrB, stateSwapIgrC,
		stateSwapWaitA, stateSwapWaitB
	);
	signal stateSwap: stateSwap_t;

	signal addrEgr: std_logic_vector(12 downto 0);
	signal addrIgr: std_logic_vector(12 downto 0);

	signal a0Egrstr: natural range 0 to 511;
	signal lenEgrstr: natural range 0 to 16;

	signal burstSwap: natural range 0 to 31;
	signal burstSwapLast: natural range 0 to 31; -- for IMX335

	signal enRowbufB: std_logic;
	signal enRowAbufB: std_logic;
	signal enRowBbufB: std_logic;

	signal weRowbufB: std_logic;
	signal aRowbufB: std_logic_vector(8 downto 0);

	signal hdrmemAXI_awaddr_sig: std_logic_vector(17 downto 0);

	signal hdrmemAXI_araddr_sig: std_logic_vector(17 downto 0);

	-- IP sigs.swap.cust --- INSERT

	---- mclk to memclk CDC sampling (mclkToMemclkSample)

	signal rng_memclk: std_logic;
	signal rng_to_memclkm1: std_logic;
	signal rng_to_memclkm2: std_logic;
	signal a0_memclk: std_logic_vector(4 downto 0);
	signal a0_to_memclkm1: std_logic_vector(4 downto 0);
	signal a0_to_memclkm2: std_logic_vector(4 downto 0);
	signal liveBNotA_memclk: std_logic;
	signal liveBNotA_to_memclkm1: std_logic;
	signal liveBNotA_to_memclkm2: std_logic;
	signal rgbFromVideoinAXIS_tlast_sig_memclk: std_logic;
	signal rgbFromVideoinAXIS_tlast_sig_to_memclkm1: std_logic;
	signal rgbFromVideoinAXIS_tlast_sig_to_memclkm2: std_logic;
	signal vsync_sig_memclk: std_logic;
	signal vsync_sig_to_memclkm1: std_logic;
	signal vsync_sig_to_memclkm2: std_logic;

	-- IP sigs.mclkToMemclkSample.cust --- INSERT

	---- mclk to memclk CDC stretching (mclkToMemclkStretch)

	signal rng_to_memclk: std_logic;
	signal a0_to_memclk: std_logic_vector(4 downto 0);
	signal liveBNotA_to_memclk: std_logic;
	signal rgbFromVideoinAXIS_tlast_sig_to_memclk: std_logic;
	signal vsync_sig_to_memclk: std_logic;

	-- IP sigs.mclkToMemclkStretch.cust --- INSERT

	---- myRowAbuf
	signal drdRowAbuf: std_logic_vector(31 downto 0);
	signal drdRowAbufB: std_logic_vector(127 downto 0);

	---- myRowBbuf
	signal drdRowBbuf: std_logic_vector(31 downto 0);
	signal drdRowBbufB: std_logic_vector(127 downto 0);

	---- handshake
	-- swap to egrstr
	signal reqSwapToEgrstr: std_logic;
	signal ackSwapToEgrstr: std_logic;
	signal dneSwapToEgrstr: std_logic;

	-- swap to igrstr
	signal reqSwapToIgrstr: std_logic;
	signal ackSwapToIgrstr: std_logic;
	signal dneSwapToIgrstr: std_logic;

	-- swap to egrstr
	signal egrAXIS_tready: std_logic;
	signal egrAXIS_tvalid: std_logic;

	---- other
	signal vsync_sig: std_logic;
	signal rgbFromVideoinAXIS_tlast_sig: std_logic;
	-- IP sigs.oth.cust --- IBEGIN

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

	-- each ixTExp increment corresponds to an eight-fold decrease in exposure time
	-- (longest exposure first)

	-- compare incoming live data to stock data

	-- output: 32-bit RGBE format with shared exponent

	function getExp8of12
		parameter (
			lin: unsigned(11 downto 0)
		)
	return natural is

		variable exp8: natural := 0;

	begin
		--if lin(11)='1' then
		--	exp8 := 4;
		--elsif lin(10)='1' then
		--	exp8 := 3;
		--elsif lin(9)='1' then
		--	exp8 := 2;
		--elsif lin(8)='1' then
		--	exp8 := 1;
		--else
		--	exp8 := 0;
		--end if;

		for i in 11 downto 8 loop
			if lin(i)='1' then
				exp8 := i-7;
				exit;
			end if;
		end loop;

		return exp8;
	end function;


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

begin

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

	myRowAbuf : Dpbram_size8kB_a32b128
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enRowAbuf,
			weA => weRowAbuf,

			aA => aRowAbuf,
			drdA => drdRowAbuf,
			dwrA => dwrRowbuf,

			rstB => resetMemclk,
			clkB => memclk,

			enB => enRowAbufB,
			weB => weRowbufB,

			aB => aRowbufB,
			drdB => drdRowAbufB,
			dwrB => hdrmemAXI_rdata
		);

	myRowBbuf : Dpbram_size8kB_a32b128
		port map (
			rstA => reset,
			clkA => mclk,

			enA => enRowBbuf,
			weA => weRowBbuf,

			aA => aRowBbuf,
			drdA => drdRowBbuf,
			dwrA => dwrRowbuf,

			rstB => resetMemclk,
			clkB => memclk,

			enB => enRowBbufB,
			weB => weRowbufB,

			aB => aRowbufB,
			drdB => drdRowBbufB,
			dwrB => hdrmemAXI_rdata
		);

	------------------------------------------------------------------------
	-- implementation: continuous streaming from buffers to DDR memory (egrstr)
	------------------------------------------------------------------------

	-- IP impl.egrstr.wiring --- BEGIN
	drdRowbufB <= drdRowAbufB when liveBNotA_memclk='1' else drdRowBbufB;

	ackSwapToEgrstr <= '1' when (stateEgrstr=stateEgrstrRun or stateEgrstr=stateEgrstrDone) else '0';
	dneSwapToEgrstr <= '1' when stateEgrstr=stateEgrstrDone else '0';

	egrAXIS_tvalid <= '1' when stateEgrstr=stateEgrstrRun else '0';
	-- IP impl.egrstr.wiring --- END

	-- IP impl.egrstr.wiring.cust --- LINE

	-- IP impl.egrstr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.egrstr.vars --- RBEGIN
		variable wordEgrLast: natural range 0 to 15;
		variable wordEgrRd: natural range 0 to 15;
		variable wordEgrWr: natural range 0 to 15;

		variable i: natural range 0 to 2; -- correct choice for register-less BlockRAM
		-- IP impl.egrstr.vars --- REND

	begin
		if resetMemclk='1' then
			-- IP impl.egrstr.asyncrst --- BEGIN
			stateEgrstr <= stateEgrstrInit;
			enRowbufBEgrstr <= '0';
			enRowbufBEgrstrm1 <= '0';
			aRowbufBEgrstr <= 0;
			egrfifo <= (others => (others => '0'));
			ixRdEgrfifo <= 0;
			ixWrEgrfifo <= 0;
			egrAXIS_tdata <= (others => '0');
			egrAXIS_tlast <= '1';

			-- IP impl.egrstr.asyncrst --- END
			-- IP impl.egrstr.asyncrst.cust --- IBEGIN
			wordEgrLast := 0;
			wordEgrRd := 0;
			wordEgrWr := 0;

			i := 0;
			-- IP impl.egrstr.asyncrst.cust --- IEND

		elsif rising_edge(memclk) then
			if stateEgrstr=stateEgrstrInit then
				-- IP impl.egrstr.syncrst --- BEGIN
				enRowbufBEgrstr <= '0';
				enRowbufBEgrstrm1 <= '0';
				aRowbufBEgrstr <= 0;
				egrfifo <= (others => (others => '0'));
				ixRdEgrfifo <= 0;
				ixWrEgrfifo <= 0;
				egrAXIS_tdata <= (others => '0');
				egrAXIS_tlast <= '1';

				-- IP impl.egrstr.syncrst --- END
				-- IP impl.egrstr.syncrst.cust --- IBEGIN
				wordEgrLast := 0;
				wordEgrRd := 0;
				wordEgrWr := 0;

				i := 0;
				-- IP impl.egrstr.syncrst.cust --- IEND

				stateEgrstr <= stateEgrstrIdle;

			elsif stateEgrstr=stateEgrstrIdle then
				if reqSwapToEgrstr='1' then
					-- IP impl.egrstr.idle.start --- IBEGIN
					enRowbufBEgrstr <= '1';
					aRowbufBEgrstr <= a0Egrstr;

					wordEgrLast := lenEgrstr - 1;
					wordEgrRd := 0;
					wordEgrWr := 0;

					i := 0;
					-- IP impl.egrstr.idle.start --- IEND

					stateEgrstr <= stateEgrstrLoad;
				end if;

			elsif stateEgrstr=stateEgrstrLoad then
				if i=0 then
					-- IP impl.egrstr.load.one --- IBEGIN
					enRowbufBEgrstr <= '1';
					aRowbufBEgrstr <= aRowbufBEgrstr + 1;

					i := i + 1;
					-- IP impl.egrstr.load.one --- IEND

					stateEgrstr <= stateEgrstrLoad;

				elsif i=1 then
					-- IP impl.egrstr.load.two --- IBEGIN
					enRowbufBEgrstr <= '1';
					aRowbufBEgrstr <= aRowbufBEgrstr + 1;

					egrfifo(ixWrEgrfifo) <= drdRowbufB;
					ixWrEgrfifo <= 1;

					i := i + 1;
					-- IP impl.egrstr.load.two --- IEND

					stateEgrstr <= stateEgrstrLoad;

				else
					-- IP impl.egrstr.load.done --- IBEGIN
					enRowbufBEgrstr <= '1';
					enRowbufBEgrstrm1 <= '1';

					aRowbufBEgrstr <= aRowbufBEgrstr + 1;

					egrfifo(ixWrEgrfifo) <= drdRowbufB;
					ixWrEgrfifo <= 2;

					egrAXIS_tdata <= egrfifo(ixRdEgrfifo);
					ixRdEgrfifo <= 1;

					egrAXIS_tlast <= '0';

					wordEgrRd := 0; -- corresponding to egrAXIS_tdata
					wordEgrWr := 3; -- corresponding to aRowbufBEgrstr
					-- IP impl.egrstr.load.done --- IEND

					stateEgrstr <= stateEgrstrRun;
				end if;

			elsif stateEgrstr=stateEgrstrRun then
				-- IP impl.egrstr.run.pre --- IBEGIN
				-- update post FIFO-to-stream
				if egrAXIS_tready='1' then
					if ixRdEgrfifo=2 then
						ixRdEgrfifo <= 0;
					else
						ixRdEgrfifo <= ixRdEgrfifo + 1;
					end if;
				end if;

				-- update post buf-to-FIFO
				if enRowbufBEgrstrm1='1' then
					egrfifo(ixWrEgrfifo) <= drdRowbufB;

					if ixWrEgrfifo=2 then
						ixWrEgrfifo <= 0;
					else
						ixWrEgrfifo <= ixWrEgrfifo + 1;
					end if;
				end if;
				-- IP impl.egrstr.run.pre --- IEND

				if (egrAXIS_tready='1' and egrAXIS_tlast='1') then
					-- IP impl.egrstr.run.done --- IBEGIN
					-- proceed
					enRowbufBEgrstr <= '0';
					-- IP impl.egrstr.run.done --- IEND

					stateEgrstr <= stateEgrstrDone;

				else
					-- IP impl.egrstr.run.nextWord --- IBEGIN
					if egrAXIS_tready='1' then
						-- initiate FIFO-to-stream
						egrAXIS_tdata <= egrfifo(ixRdEgrfifo);

						wordEgrRd := wordEgrRd + 1;

						if wordEgrRd=wordEgrLast then
							egrAXIS_tlast <= '1';
						end if;
					end if;

					-- initiate buf-to-FIFO
					enRowbufBEgrstrm1 <= enRowbufBEgrstr;

					if egrAXIS_tready='1' and wordEgrWr/=wordEgrLast then
						enRowbufBEgrstr <= '1';
						aRowbufBEgrstr <= aRowbufBEgrstr + 1;

						wordEgrWr := wordEgrWr + 1;

					else
						enRowbufBEgrstr <= '0';
					end if;
					-- IP impl.egrstr.run.nextWord --- IEND

					stateEgrstr <= stateEgrstrRun;
				end if;

			elsif stateEgrstr=stateEgrstrDone then
				if reqSwapToEgrstr='0' then
					stateEgrstr <= stateEgrstrInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.egrstr.rising --- END

	------------------------------------------------------------------------
	-- implementation: continuous streaming from DDR memory (igrstr)
	------------------------------------------------------------------------

	-- IP impl.igrstr.wiring --- BEGIN
	hdrmemAXI_rready <= '1' when stateIgrstr=stateIgrstrRun else '0';

	ackSwapToIgrstr <= '1' when (stateIgrstr=stateIgrstrRun or stateIgrstr=stateIgrstrDone) else '0';
	dneSwapToIgrstr <= '1' when stateIgrstr=stateIgrstrDone else '0';
	-- IP impl.igrstr.wiring --- END

	-- IP impl.igrstr.wiring.cust --- LINE

	-- IP impl.igrstr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.igrstr.vars --- BEGIN
		-- IP impl.igrstr.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.igrstr.asyncrst --- BEGIN
			stateIgrstr <= stateIgrstrInit;
			aRowbufBIgrstr <= 0;
			burstIgrstr <= 0;

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

		elsif rising_edge(memclk) then
			if stateIgrstr=stateIgrstrInit then
				-- IP impl.igrstr.syncrst --- BEGIN
				aRowbufBIgrstr <= 0;
				burstIgrstr <= 0;

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

				stateIgrstr <= stateIgrstrIdle;

			elsif stateIgrstr=stateIgrstrIdle then
				if reqSwapToIgrstr='1' then
					stateIgrstr <= stateIgrstrRun;
				end if;

			elsif stateIgrstr=stateIgrstrRun then
				if hdrmemAXI_rvalid='1' then
					if (aRowbufBIgrstr=8*1024/16-1 or (burstIgrstr=burstSwap and hdrmemAXI_rlast='1')) then
						stateIgrstr <= stateIgrstrDone;

					else
						-- IP impl.igrstr.run.inc --- IBEGIN
						if hdrmemAXI_rlast='1' then
							burstIgrstr <= burstIgrstr + 1;
						end if;

						aRowbufBIgrstr <= aRowbufBIgrstr + 1;
						-- IP impl.igrstr.run.inc --- IEND

						stateIgrstr <= stateIgrstrRun;
					end if;
				end if;

			elsif stateIgrstr=stateIgrstrDone then
				if reqSwapToIgrstr='0' then
					stateIgrstr <= stateIgrstrInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.igrstr.rising --- END

	------------------------------------------------------------------------
	-- implementation: live stream forwarding (livefwd)
	------------------------------------------------------------------------

	-- IP impl.livefwd.wiring --- BEGIN
	-- IP impl.livefwd.wiring --- END

	-- IP impl.livefwd.wiring.cust --- LINE

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

	begin
		if reset='1' then
			-- IP impl.livefwd.asyncrst --- BEGIN
			rgbFromVideoinAXIS_tvalidm1 <= '0';
			rgbFromVideoinAXIS_tvalidm2 <= '0';
			rgbFromVideoinAXIS_tdatam1 <= (others => '0');
			rgbFromVideoinAXIS_tdatam2 <= (others => '0');
			rgbFromVideoinAXIS_tlastm1 <= '1';
			rgbFromVideoinAXIS_tlastm2 <= '1';

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

		elsif rising_edge(mclk) then
			-- IP impl.livefwd --- IBEGIN
			rgbFromVideoinAXIS_tvalidm1 <= rgbFromVideoinAXIS_tvalid;
			rgbFromVideoinAXIS_tvalidm2 <= rgbFromVideoinAXIS_tvalidm1;
			rgbFromVideoinAXIS_tdatam1 <= rgbFromVideoinAXIS_tdata;
			rgbFromVideoinAXIS_tdatam2 <= rgbFromVideoinAXIS_tdatam1;
			rgbFromVideoinAXIS_tlastm1 <= rgbFromVideoinAXIS_tlast;
			rgbFromVideoinAXIS_tlastm2 <= rgbFromVideoinAXIS_tlastm1;
			-- IP impl.livefwd --- IEND
		end if;
	end process;
	-- IP impl.livefwd.rising --- END

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

	-- IP impl.op.wiring --- BEGIN
	ackInvAssign <= ackInvAssign_sig;
	ackInvSet <= ackInvSet_sig;

	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 --- BEGIN
		-- IP impl.op.vars --- END

	begin
		if reset='1' then
			-- IP impl.op.asyncrst --- BEGIN
			stateOp <= stateOpInit;
			ackInvAssign_sig <= '0';
			ackInvSet_sig <= '0';
			rng <= '0';
			ixMemNext <= ixMemInvalid;

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

		elsif rising_edge(mclk) then
			if (stateOp=stateOpInit or (stateOp/=stateOpInv and (reqInvAssign='1' or reqInvSet='1'))) then
				if reqInvAssign='1' then
					-- IP impl.op.init.invAssign --- IBEGIN
					if rng='1' then
						ixMemNext <= assignIxMem;
					end if;

					ackInvAssign_sig <= '1';
					ackInvSet_sig <= '0';
					-- IP impl.op.init.invAssign --- IEND

					stateOp <= stateOpInv;

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

					ackInvAssign_sig <= '0';
					ackInvSet_sig <= '1';
					-- IP impl.op.init.invSet --- IEND

					stateOp <= stateOpInv;

				else
					-- IP impl.op.syncrst --- RBEGIN
					ackInvAssign_sig <= '0';
					ackInvSet_sig <= '0';

					-- IP impl.op.syncrst --- REND
					-- IP impl.op.syncrst.cust --- INSERT

					stateOp <= stateOpInit;
				end if;

			elsif stateOp=stateOpInv then
				if ((reqInvAssign='0' and ackInvAssign_sig='1') or (reqInvSet='0' and ackInvSet_sig='1')) then
					-- IP impl.op.inv.reset --- IBEGIN
					ackInvAssign_sig <= '0';
					ackInvSet_sig <= '0';
					-- IP impl.op.inv.reset --- IEND

					stateOp <= stateOpInit;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.op.rising --- END

	------------------------------------------------------------------------
	-- implementation: stock release from buffer operation (stockrls)
	------------------------------------------------------------------------

	-- IP impl.stockrls.wiring --- BEGIN
	enRowbufStockrls <= '1' when (stateStockrls=stateStockrlsRun or stateStockrls=stateStockrlsEol) else '0';
	stock <= drdRowAbuf when liveBNotA='1' else drdRowBbuf;
	-- IP impl.stockrls.wiring --- END

	-- IP impl.stockrls.wiring.cust --- LINE

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

	begin
		if reset='1' then
			-- IP impl.stockrls.asyncrst --- BEGIN
			stateStockrls <= stateStockrlsInit;
			aRowbufStockrls <= 0;

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

		elsif rising_edge(mclk) then
			if (stateStockrls=stateStockrlsInit or rng='0') then
				-- IP impl.stockrls.syncrst --- BEGIN
				aRowbufStockrls <= 0;

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

				if (rng='1' and vsync='1' and unsigned(ixTExp)/=0) then
					stateStockrls <= stateStockrlsRun;

				else
					stateStockrls <= stateStockrlsInit;
				end if;

			elsif stateStockrls=stateStockrlsRun then
				if rgbFromVideoinAXIS_tvalid='1' then
					aRowbufStockrls <= aRowbufStockrls + 1; -- IP impl.stockrls.run.inc --- ILINE

					if rgbFromVideoinAXIS_tlast='1' then
						stateStockrls <= stateStockrlsEol;

					else
						stateStockrls <= stateStockrlsRun;
					end if;
				end if;

			elsif stateStockrls=stateStockrlsEol then
				if vsync='1' then
					stateStockrls <= stateStockrlsInit;

				else
					aRowbufStockrls <= 0; -- IP impl.stockrls.eol.reset --- ILINE

					stateStockrls <= stateStockrlsRun;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.stockrls.rising --- END

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

	-- IP impl.stream.wiring --- BEGIN
	getInfoTixVState <= tixVState;

	getInfoTkst <= tkst;
	getInfoIxMem <= ixMem;

	getInfoIxMemAcq <= ixMemAcq;

	enRowAbuf <= '1' when ((liveBNotA='0' and enRowbufStream='1') or (liveBNotA='1' and enRowbufStockrls='1')) else '0';
	enRowBbuf <= '1' when ((liveBNotA='1' and enRowbufStream='1') or (liveBNotA='0' and enRowbufStockrls='1')) else '0';

	weRowAbuf <= '1' when liveBNotA='0' else '0';
	weRowBbuf <= '1' when liveBNotA='1' else '0';
	-- IP impl.stream.wiring --- END

	-- IP impl.stream.wiring.cust --- RBEGIN
	aRowAbuf <= std_logic_vector(to_unsigned(aRowbufStream, 11)) when liveBNotA='0'
				else std_logic_vector(to_unsigned(aRowbufStockrls, 11));

	aRowBbuf <= std_logic_vector(to_unsigned(aRowbufStream, 11)) when liveBNotA='1'
				else std_logic_vector(to_unsigned(aRowbufStockrls, 11));
	-- IP impl.stream.wiring.cust --- REND

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

		variable rshift: natural range 0 to 4;
		variable live: std_logic_vector(3*12-1 downto 0);
		variable r,g,b,pvt: unsigned(11 downto 0);
		variable exp: natural range 0 to 255;
		-- IP impl.stream.vars --- REND

	begin
		if reset='1' then
			-- IP impl.stream.asyncrst --- BEGIN
			stateStream <= stateStreamInit;
			tixVState <= tixVStateIdle;
			tkst <= (others => '0');
			ixMem <= ixMemInvalid;
			tkstAcq <= (others => '0');
			ixMemAcq <= ixMemInvalid;
			a0 <= (others => '0');
			liveBNotA <= '0';
			enRowbufStream <= '0';
			aRowbufStream <= 0;
			dwrRowbuf <= (others => '0');

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

		elsif rising_edge(mclk) then
			if (stateStream=stateStreamInit or rng='0') then
				-- IP impl.stream.syncrst --- RBEGIN
				tkst <= (others => '0');
				ixMem <= ixMemInvalid;
				tkstAcq <= (others => '0');
				ixMemAcq <= ixMemInvalid;
				a0 <= (others => '0');
				liveBNotA <= '0';
				enRowbufStream <= '0';
				aRowbufStream <= 0;
				dwrRowbuf <= (others => '0');
	
				-- IP impl.stream.syncrst --- REND
				-- IP impl.stream.syncrst.cust --- IBEGIN
				col_lcl := 0;
				-- IP impl.stream.syncrst.cust --- IEND

				if rng='0' then
					tixVState <= tixVStateIdle; -- IP impl.stream.init.toIdle --- ILINE

					stateStream <= stateStreamInit;

				else
					stateStream <= stateStreamIdle;
				end if;

			elsif stateStream=stateStreamIdle then
				if (ixMemNext/=ixMemInvalid and ixMemNext/=ixMem and vsync='1' and unsigned(ixTExp)=0) then
					-- IP impl.stream.idle.start --- IBEGIN
					tkstAcq <= tkclksrcGetTkstTkst;
					ixMemAcq <= ixMemNext;
					a0 <= std_logic_vector( (unsigned(ixMemNext(3 downto 0)) & "0") + ("0" & unsigned(ixMemNext(3 downto 0))) );
					tixVState <= tixVStateAcq;
					-- IP impl.stream.idle.start --- IEND

					stateStream <= stateStreamRun;

				elsif ixMemNext=ixMem then
					tixVState <= tixVStateStall; -- IP impl.stream.idle.stall --- ILINE

					stateStream <= stateStreamIdle;
				end if;

			elsif stateStream=stateStreamRun then
				if rgbFromVideoinAXIS_tvalidm2='1' then
					-- IP impl.stream.run --- IBEGIN
					for i in 0 to 2 loop
						if rgbFromVideoinAXIS_tdatam2(12*i+11 downto 12*i+8)="1111" and unsigned(ixTExp)/=4 then -- first four bits one (>= 3840/4096 93.8%)
							live(12*i+12-1 downto 12*i) := (others => '1');
						elsif rgbFromVideoinAXIS_tdatam2(12*i+11 downto 12*i+8)="0000" and unsigned(ixTExp)/=0 then -- only last eight bits non-zero (< 256/4096 = 6.3%)
							live(12*i+12-1 downto 12*i) := (others => '0');
						else
							live(12*i+12-1 downto 12*i) := rgbFromVideoinAXIS_tdatam2(12*i+12-1 downto 12*i); -- TBD: work with _tdatam1 to simplify stockrls
						end if;
					end loop;

					-- detect "done" i.e. skip this ixTExp if none of the channels reads 1111_1111
					if stock(31 downto 24)="11111111" or stock(23 downto 16)="11111111" or stock(15 downto 8)="11111111" or unsigned(ixTExp)=0 then
						-- live is r & g & b
						r := unsigned(live(12*2+12-1 downto 12*2));
						g := unsigned(live(12*1+12-1 downto 12*1));
						b := unsigned(live(12*0+12-1 downto 12*0));

						if r>g and r>b then
							pvt := r;
						elsif g>b then
							pvt := g;
						else
							pvt := b;
						end if;

						if unsigned(ixTExp)=0 then
							exp := 0;
						else
							exp := to_integer(unsigned(stock(7 downto 0)) + 3);
						end if;

						rshift := getExp8of12(pvt);

						dwrRowbuf(31 downto 24) <= std_logic_vector(r(8+rshift-1 downto rshift));
						dwrRowbuf(23 downto 16) <= std_logic_vector(g(8+rshift-1 downto rshift));
						dwrRowbuf(15 downto 8) <= std_logic_vector(b(8+rshift-1 downto rshift));
						dwrRowbuf(7 downto 0) <= std_logic_vector(to_unsigned(exp + rshift, 8));

					else
						dwrRowbuf <= stock;
					end if;

					enRowbufStream <= '1';

					if col_lcl/=0 then
						aRowbufStream <= aRowbufStream + 1;
					end if;

					col_lcl := col_lcl + 1; -- in next clock cycle
					-- IP impl.stream.run --- IEND

					if col_lcl=unsigned(NCol) then
						stateStream <= stateStreamEol;

					else
						stateStream <= stateStreamRun;
					end if;

				else
					enRowbufStream <= '0'; -- IP impl.stream.run.reset --- ILINE

					stateStream <= stateStreamRun;
				end if;

			elsif stateStream=stateStreamEol then
				-- IP impl.stream.eol.pre --- IBEGIN
				enRowbufStream <= '0';
				aRowbufStream <= 0;

				col_lcl := 0;
				-- IP impl.stream.eol.pre --- IEND

				if vsync='1' then
					liveBNotA <= '0'; -- IP impl.stream.eol.expDone --- ILINE

					if unsigned(ixTExp)=0 then
						-- IP impl.stream.eol.done --- IBEGIN
						ixMem <= ixMemAcq;
						tkst <= tkstAcq;
						-- IP impl.stream.eol.done --- IEND

						stateStream <= stateStreamIdle;

					else
						stateStream <= stateStreamRun;
					end if;

				else
					-- IP impl.stream.eol.nextRow --- IBEGIN
					liveBNotA <= not liveBNotA;
					-- IP impl.stream.eol.nextRow --- IEND

					stateStream <= stateStreamRun;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.stream.rising --- END

	------------------------------------------------------------------------
	-- implementation: stock buffer swap to-then-from DDR memory (swap)
	------------------------------------------------------------------------

	-- IP impl.swap.wiring --- BEGIN
	enRowAbufB <= '1' when (liveBNotA_memclk='1' and enRowbufB='1') else '0';
	enRowBbufB <= '1' when (liveBNotA_memclk='0' and enRowbufB='1') else '0';

	weRowbufB <= '1' when (stateSwap=stateSwapIgrA or stateSwap=stateSwapIgrB) else '0';

	hdrmemAXI_awaddr <= hdrmemAXI_awaddr_sig;
	hdrmemAXI_awvalid <= '1' when stateSwap=stateSwapEgrB else '0';

	hdrmemAXI_wdata <= egrAXIS_tdata;
	hdrmemAXI_wlast <= '0' when ((reqSwapToEgrstr='1' and ackSwapToEgrstr='0') or egrAXIS_tlast='0') else '1';
	hdrmemAXI_wvalid <= egrAXIS_tvalid;

	reqToDdrifWr <= '1' when stateSwap=stateSwapEgrB else '0';

	hdrmemAXI_araddr <= hdrmemAXI_araddr_sig;
	hdrmemAXI_arvalid <= '1' when stateSwap=stateSwapIgrA else '0';

	reqToDdrifRd <= '1' when stateSwap=stateSwapIgrA else '0';

	reqSwapToEgrstr <= '1' when (stateSwap=stateSwapEgrB or stateSwap=stateSwapEgrC) else '0';

	reqSwapToIgrstr <= '1' when (stateSwap=stateSwapIgrA or stateSwap=stateSwapIgrB or stateSwap=stateSwapIgrC) else '0';

	egrAXIS_tready <= hdrmemAXI_wready;
	-- IP impl.swap.wiring --- END

	-- IP impl.swap.wiring.cust --- RBEGIN

	-- cf. source.egr (+ separate source.egrstr), pack.igr (+ separate pack.igrstr)

	-- sufficient DDR bandwidth for store-then-load

	---- shared buffer
	enRowbufB <= enRowbufBEgrstr when stateSwap=stateSwapEgrA or stateSwap=stateSwapEgrB or stateSwap=stateSwapEgrC
				else '1' when stateIgrstr=stateIgrstrRun
				else '0';

	aRowbufB <= std_logic_vector(to_unsigned(aRowbufBEgrstr, 9)) when stateSwap=stateSwapEgrA or stateSwap=stateSwapEgrB or stateSwap=stateSwapEgrC
					else std_logic_vector(to_unsigned(aRowbufBIgrstr, 9)) when stateSwap=stateSwapIgrA or stateSwap=stateSwapIgrB
					else (others => '0');

	---- egress portion

	-- buf size 8 kB or 32 bursts of 16x16 byte

	-- for now, up to 16 frames, fills 192/256 MByte

	-- one frame is 1024 + 512 = 1536 rows, or 12 MByte
	-- i.e. first frame from 0000_0000_0000 to 0101_1111_1111, second from 0110_0000_0000 to 1100_0000_0000
	-- addrEgr = (frame << 9) + (frame << 8) then increment by one each row

	-- ddrif adds 0000_0000 (16 beats per burst, 16 bytes / 4 words per beat)
	hdrmemAXI_awaddr_sig(4 downto 0) <= std_logic_vector(to_unsigned(burstSwap, 5));
	hdrmemAXI_awaddr_sig(17 downto 5) <= addrEgr; -- one row behind addrIgr

	---- ingress portion
	hdrmemAXI_araddr_sig(4 downto 0) <= std_logic_vector(to_unsigned(burstSwap, 5));
	hdrmemAXI_araddr_sig(17 downto 5) <= addrIgr; -- one row ahead of addrEgr
	-- IP impl.swap.wiring.cust --- REND

	-- IP impl.swap.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.swap.vars --- RBEGIN
		variable row_lcl: natural range 0 to 1499;

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

	begin
		if resetMemclk='1' then
			-- IP impl.swap.asyncrst --- BEGIN
			stateSwap <= stateSwapInit;
			addrEgr <= (others => '0');
			addrIgr <= (others => '0');
			a0Egrstr <= 0;
			lenEgrstr <= 0;
			burstSwap <= 0;
			burstSwapLast <= 19;

			-- IP impl.swap.asyncrst --- END
			-- IP impl.swap.asyncrst.cust --- IBEGIN
			i := 0;
			-- IP impl.swap.asyncrst.cust --- IEND

		elsif rising_edge(memclk) then
			if stateSwap=stateSwapInit then
				-- IP impl.swap.syncrst --- RBEGIN
				-- IP impl.swap.syncrst --- REND
				-- IP impl.swap.syncrst.cust --- IBEGIN
				i := 0;
				-- IP impl.swap.syncrst.cust --- IEND

				if (rng_memclk='1' and vsync_sig_memclk='1' and rgbFromVideoinAXIS_tlast_sig_memclk='1') then
					stateSwap <= stateSwapStart;

				else
					stateSwap <= stateSwapInit;
				end if;

			elsif stateSwap=stateSwapStart then
				if rng_memclk='0' then
					stateSwap <= stateSwapInit;

				elsif i=imax then
					-- IP impl.swap.start.done --- IBEGIN
					addrEgr <= a0_memclk & "00000000";
					addrIgr <= a0_memclk & "00000000";

					row_lcl := 0;
					-- IP impl.swap.start.done --- IEND

					stateSwap <= stateSwapIgrA;

				else
					-- IP impl.swap.start.inc --- IBEGIN
					-- make sure a0_memclk CDC completes at ixTExp=0
					i := i + 1;
					-- IP impl.swap.start.inc --- IEND

					stateSwap <= stateSwapStart;
				end if;

			elsif stateSwap=stateSwapIdle then
				if rng_memclk='0' then
					stateSwap <= stateSwapInit;

				elsif rgbFromVideoinAXIS_tlast_sig_memclk='0' then
					stateSwap <= stateSwapEgrA;
				end if;

			elsif stateSwap=stateSwapEgrA then
				-- IP impl.swap.egrA.setAddr --- IBEGIN
				a0Egrstr <= to_integer(to_unsigned(burstSwap, 5) & "0000");
				lenEgrstr <= 16;
				-- IP impl.swap.egrA.setAddr --- IEND

				stateSwap <= stateSwapEgrB;

			elsif stateSwap=stateSwapEgrB then
				if (ackToDdrifWr='1' and hdrmemAXI_awready='1') then
					stateSwap <= stateSwapEgrC;
				end if;

			elsif stateSwap=stateSwapEgrC then
				if dneSwapToEgrstr='1' then
					addrEgr <= std_logic_vector(unsigned(addrEgr) + 1); -- IP impl.swap.egrC.inc --- ILINE

					if rng_memclk='0' then
						stateSwap <= stateSwapInit;

					elsif burstSwap=burstSwapLast then
						-- IP impl.swap.egrC.bufDone --- IBEGIN
						burstSwap <= 0;
						-- IP impl.swap.egrC.bufDone --- IEND

						if row_lcl=rowLast then
							stateSwap <= stateSwapInit;

						else
							stateSwap <= stateSwapIgrA;
						end if;

					else
						-- IP impl.swap.egrC.nextBurst --- IBEGIN
						burstSwap <= burstSwap + 1;
						-- IP impl.swap.egrC.nextBurst --- IEND

						stateSwap <= stateSwapEgrA;
					end if;
				end if;

			elsif stateSwap=stateSwapIgrA then
				if (ackToDdrifRd='1' and hdrmemAXI_arready='1') then
					stateSwap <= stateSwapIgrB;
				end if;

			elsif stateSwap=stateSwapIgrB then
				if burstSwap=burstSwapLast then
					stateSwap <= stateSwapIgrC;

				else
					burstSwap <= burstSwap + 1; -- IP impl.swap.igrB.nextBurst --- ILINE

					stateSwap <= stateSwapIgrA;
				end if;

			elsif stateSwap=stateSwapIgrC then
				if dneSwapToIgrstr='1' then
					-- IP impl.swap.igrC.done --- IBEGIN
					addrIgr <= std_logic_vector(unsigned(addrIgr) + 1);

					burstSwap <= 0;

					row_lcl := row_lcl + 1;
					-- IP impl.swap.igrC.done --- IEND

					if rng_memclk='0' then
						stateSwap <= stateSwapInit;

					elsif row_lcl=1 then
						stateSwap <= stateSwapWaitA;

					else
						stateSwap <= stateSwapWaitB;
					end if;
				end if;

			elsif stateSwap=stateSwapWaitA then
				if rgbFromVideoinAXIS_tlast_sig_memclk='0' then
					stateSwap <= stateSwapWaitB;
				end if;

			elsif stateSwap=stateSwapWaitB then
				if rgbFromVideoinAXIS_tlast_sig_memclk='1' then
					stateSwap <= stateSwapIdle;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.swap.rising --- END

	------------------------------------------------------------------------
	-- implementation: mclk to memclk CDC sampling (mclkToMemclkSample)
	------------------------------------------------------------------------

	-- IP impl.mclkToMemclkSample.wiring --- BEGIN
	-- IP impl.mclkToMemclkSample.wiring --- END

	-- IP impl.mclkToMemclkSample.wiring.cust --- LINE

	-- IP impl.mclkToMemclkSample.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.mclkToMemclkSample.vars --- BEGIN
		-- IP impl.mclkToMemclkSample.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.mclkToMemclkSample.asyncrst --- BEGIN
			rng_memclk <= '0';
			rng_to_memclkm1 <= '0';
			rng_to_memclkm2 <= '0';
			a0_memclk <= (others => '0');
			a0_to_memclkm1 <= (others => '0');
			a0_to_memclkm2 <= (others => '0');
			liveBNotA_memclk <= '0';
			liveBNotA_to_memclkm1 <= '0';
			liveBNotA_to_memclkm2 <= '0';
			rgbFromVideoinAXIS_tlast_sig_memclk <= '0';
			rgbFromVideoinAXIS_tlast_sig_to_memclkm1 <= '0';
			rgbFromVideoinAXIS_tlast_sig_to_memclkm2 <= '0';
			vsync_sig_memclk <= '0';
			vsync_sig_to_memclkm1 <= '0';
			vsync_sig_to_memclkm2 <= '0';

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

		elsif rising_edge(memclk) then
			if rng_to_memclkm1=rng_to_memclkm2 then
				rng_memclk <= rng_to_memclkm2;
			end if;
			rng_to_memclkm1 <= rng_to_memclk;
			rng_to_memclkm2 <= rng_to_memclkm1;

			if a0_to_memclkm1=a0_to_memclkm2 then
				a0_memclk <= a0_to_memclkm2;
			end if;
			a0_to_memclkm1 <= a0_to_memclk;
			a0_to_memclkm2 <= a0_to_memclkm1;

			if liveBNotA_to_memclkm1=liveBNotA_to_memclkm2 then
				liveBNotA_memclk <= liveBNotA_to_memclkm2;
			end if;
			liveBNotA_to_memclkm1 <= liveBNotA_to_memclk;
			liveBNotA_to_memclkm2 <= liveBNotA_to_memclkm1;

			if rgbFromVideoinAXIS_tlast_sig_to_memclkm1=rgbFromVideoinAXIS_tlast_sig_to_memclkm2 then
				rgbFromVideoinAXIS_tlast_sig_memclk <= rgbFromVideoinAXIS_tlast_sig_to_memclkm2;
			end if;
			rgbFromVideoinAXIS_tlast_sig_to_memclkm1 <= rgbFromVideoinAXIS_tlast_sig_to_memclk;
			rgbFromVideoinAXIS_tlast_sig_to_memclkm2 <= rgbFromVideoinAXIS_tlast_sig_to_memclkm1;

			if vsync_sig_to_memclkm1=vsync_sig_to_memclkm2 then
				vsync_sig_memclk <= vsync_sig_to_memclkm2;
			end if;
			vsync_sig_to_memclkm1 <= vsync_sig_to_memclk;
			vsync_sig_to_memclkm2 <= vsync_sig_to_memclkm1;

		end if;
	end process;
	-- IP impl.mclkToMemclkSample.rising --- END

	------------------------------------------------------------------------
	-- implementation: mclk to memclk CDC stretching (mclkToMemclkStretch)
	------------------------------------------------------------------------

	-- IP impl.mclkToMemclkStretch.wiring --- BEGIN
	-- IP impl.mclkToMemclkStretch.wiring --- END

	-- IP impl.mclkToMemclkStretch.wiring.cust --- LINE

	-- IP impl.mclkToMemclkStretch.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.mclkToMemclkStretch.vars --- BEGIN
		constant imax: natural := 1;

		variable rng_i: natural range 0 to imax;
		variable a0_i: natural range 0 to imax;
		variable liveBNotA_i: natural range 0 to imax;
		variable rgbFromVideoinAXIS_tlast_sig_i: natural range 0 to imax;
		variable vsync_sig_i: natural range 0 to imax;
		-- IP impl.mclkToMemclkStretch.vars --- END

	begin
		if reset='1' then
			-- IP impl.mclkToMemclkStretch.asyncrst --- BEGIN
			rng_to_memclk <= '0';
			a0_to_memclk <= (others => '0');
			liveBNotA_to_memclk <= '0';
			rgbFromVideoinAXIS_tlast_sig_to_memclk <= '0';
			vsync_sig_to_memclk <= '0';

			rng_i := 0;
			a0_i := 0;
			liveBNotA_i := 0;
			rgbFromVideoinAXIS_tlast_sig_i := 0;
			vsync_sig_i := 0;
			-- IP impl.mclkToMemclkStretch.asyncrst --- END
			-- IP impl.mclkToMemclkStretch.asyncrst.cust --- INSERT

		elsif rising_edge(mclk) then
			if rng_i=imax then
				if rng/=rng_to_memclk then
					rng_to_memclk <= rng;
					rng_i := 0;
				end if;
			else
				rng_i := rng_i + 1;
			end if;

			if a0_i=imax then
				if a0/=a0_to_memclk then
					a0_to_memclk <= a0;
					a0_i := 0;
				end if;
			else
				a0_i := a0_i + 1;
			end if;

			if liveBNotA_i=imax then
				if liveBNotA/=liveBNotA_to_memclk then
					liveBNotA_to_memclk <= liveBNotA;
					liveBNotA_i := 0;
				end if;
			else
				liveBNotA_i := liveBNotA_i + 1;
			end if;

			if rgbFromVideoinAXIS_tlast_sig_i=imax then
				if rgbFromVideoinAXIS_tlast_sig/=rgbFromVideoinAXIS_tlast_sig_to_memclk then
					rgbFromVideoinAXIS_tlast_sig_to_memclk <= rgbFromVideoinAXIS_tlast_sig;
					rgbFromVideoinAXIS_tlast_sig_i := 0;
				end if;
			else
				rgbFromVideoinAXIS_tlast_sig_i := rgbFromVideoinAXIS_tlast_sig_i + 1;
			end if;

			if vsync_sig_i=imax then
				if vsync_sig/=vsync_sig_to_memclk then
					vsync_sig_to_memclk <= vsync_sig;
					vsync_sig_i := 0;
				end if;
			else
				vsync_sig_i := vsync_sig_i + 1;
			end if;

		end if;
	end process;
	-- IP impl.mclkToMemclkStretch.rising --- END

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

	
	-- IP impl.oth.cust --- IBEGIN
	vsync_sig <= vsync;
	rgbFromVideoinAXIS_tlast_sig <= rgbFromVideoinAXIS_tlast;
	-- IP impl.oth.cust --- IEND

end Rtl;
