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

-- module parameters:
-- memclkIntNotExt (memory clock origin): false
-- fMemclk: 250000
-- wA (AXI address width [bit]): 33
-- wAConst (constant portion of AXI address width [bit]): 7
-- aConst (constant portion of AXI address): 0000001
-- wD (AXI data width 128/512 [bit]): 512
-- NRd (number of read channels): 2
-- flexNBeatRds (read channel flexible beats per burst): false;false
-- NBeatRd (number of beats per read burst): 4
-- wDRds (read channel data widths <= wD [bit]): 128;128
-- clkRds (read channel clocks): memclk;memclk
-- ratioClkRds (read channel clock ratios wrt. memory clock): 1.0;1.0
-- NWr (number of write channels): 2
-- flexNBeatWrs (write channel flexible beats per burst): false;false
-- NBeatWr (number of beats per read burst): 4
-- wDWrs (write channel data widths <= wD [bit]): 128;128
-- clkWrs (write channel clocks): memclk;memclk
-- ratioClkWrs (write channel clock ratios wrt. memory clock): 1.0;1.0
-- phyNotAxi (interface level): false
-- wAPhy (PHY address width [bit]): 20
-- wDPhy (PHY data width [bit]): 16
-- memclk (memory clock): memclk
-- ratioMemclk (memory clock ratio wrt. master clock): 5.33

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

use work.Dbecore.all;
use work.Tivsp.all;

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

		resetMemclk: in std_logic;
		memclk: in std_logic;

		tkclk: in std_logic;

		getStatsNRdA: out std_logic_vector(31 downto 0);
		getStatsNRdB: out std_logic_vector(31 downto 0);
		getStatsNWrA: out std_logic_vector(31 downto 0);
		getStatsNWrB: out std_logic_vector(31 downto 0);

		reqRdA: in std_logic;
		ackRdA: out std_logic;

		rdAAXI_araddr: in std_logic_vector(17 downto 0);
		rdAAXI_arready: out std_logic;
		rdAAXI_arvalid: in std_logic;
		rdAAXI_rdata: out std_logic_vector(127 downto 0);
		rdAAXI_rlast: out std_logic;
		rdAAXI_rready: in std_logic;
		rdAAXI_rresp: out std_logic_vector(1 downto 0);
		rdAAXI_rvalid: out std_logic;

		reqRdB: in std_logic;
		ackRdB: out std_logic;

		rdBAXI_araddr: in std_logic_vector(17 downto 0);
		rdBAXI_arready: out std_logic;
		rdBAXI_arvalid: in std_logic;
		rdBAXI_rdata: out std_logic_vector(127 downto 0);
		rdBAXI_rlast: out std_logic;
		rdBAXI_rready: in std_logic;
		rdBAXI_rresp: out std_logic_vector(1 downto 0);
		rdBAXI_rvalid: out std_logic;

		reqWrA: in std_logic;
		ackWrA: out std_logic;

		wrAAXI_awaddr: in std_logic_vector(17 downto 0);
		wrAAXI_awready: out std_logic;
		wrAAXI_awvalid: in std_logic;
		wrAAXI_wdata: in std_logic_vector(127 downto 0);
		wrAAXI_wlast: in std_logic;
		wrAAXI_wready: out std_logic;
		wrAAXI_wvalid: in std_logic;

		reqWrB: in std_logic;
		ackWrB: out std_logic;

		wrBAXI_awaddr: in std_logic_vector(17 downto 0);
		wrBAXI_awready: out std_logic;
		wrBAXI_awvalid: in std_logic;
		wrBAXI_wdata: in std_logic_vector(127 downto 0);
		wrBAXI_wlast: in std_logic;
		wrBAXI_wready: out std_logic;
		wrBAXI_wvalid: in std_logic;

		ddrAXI_arid: out std_logic_vector(5 downto 0);
		ddrAXI_araddr: out std_logic_vector(32 downto 0);
		ddrAXI_arburst: out std_logic_vector(1 downto 0);
		ddrAXI_arcache: out std_logic_vector(3 downto 0);
		ddrAXI_arlen: out std_logic_vector(7 downto 0);
		ddrAXI_arlock: out std_logic_vector(0 downto 0);
		ddrAXI_arprot: out std_logic_vector(2 downto 0);
		ddrAXI_arqos: out std_logic_vector(3 downto 0);
		ddrAXI_arready: in std_logic;
		ddrAXI_arregion: out std_logic_vector(3 downto 0);
		ddrAXI_arsize: out std_logic_vector(2 downto 0);
		ddrAXI_arvalid: out std_logic;

		ddrAXI_rid: in std_logic_vector(5 downto 0);
		ddrAXI_rdata: in std_logic_vector(511 downto 0);
		ddrAXI_rlast: in std_logic;
		ddrAXI_rready: out std_logic;
		ddrAXI_rresp: in std_logic_vector(1 downto 0);
		ddrAXI_rvalid: in std_logic;

		ddrAXI_awid: out std_logic_vector(5 downto 0);
		ddrAXI_awaddr: out std_logic_vector(32 downto 0);
		ddrAXI_awburst: out std_logic_vector(1 downto 0);
		ddrAXI_awcache: out std_logic_vector(3 downto 0);
		ddrAXI_awlen: out std_logic_vector(7 downto 0);
		ddrAXI_awlock: out std_logic_vector(0 downto 0);
		ddrAXI_awprot: out std_logic_vector(2 downto 0);
		ddrAXI_awqos: out std_logic_vector(3 downto 0);
		ddrAXI_awready: in std_logic;
		ddrAXI_awregion: out std_logic_vector(3 downto 0);
		ddrAXI_awsize: out std_logic_vector(2 downto 0);
		ddrAXI_awvalid: out std_logic;

		ddrAXI_wdata: out std_logic_vector(511 downto 0);
		ddrAXI_wlast: out std_logic;
		ddrAXI_wready: in std_logic;
		ddrAXI_wstrb: out std_logic_vector(63 downto 0);
		ddrAXI_wvalid: out std_logic;

		ddrAXI_bid: in std_logic_vector(5 downto 0);
		ddrAXI_bready: out std_logic;
		ddrAXI_bresp: in std_logic_vector(1 downto 0);
		ddrAXI_bvalid: in std_logic
	);
end Ddrif;

architecture Rtl of Ddrif is

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

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

	constant wD: natural := 512;

	constant NBeatRd: natural := 4;
	constant NBeatWr: natural := 4;

	---- rdA geared egress operation (rdAGearEgr)
	type stateRdAGearEgr_t is (
		stateRdAGearEgrInit,
		stateRdAGearEgrIdle,
		stateRdAGearEgrAddr,
		stateRdAGearEgrWaitFull,
		stateRdAGearEgrXfer
	);
	signal stateRdAGearEgr: stateRdAGearEgr_t;

	constant rdAWD: natural := 128;

	signal rdAAXI_rdata_oprt: std_logic_vector(rdAWD-1 downto 0);
	signal rdAAXI_rlast_oprt: std_logic;

	signal rdAReady: boolean;
	signal rdAA: std_logic_vector(17 downto 0);

	-- IP sigs.rdAGearEgr.cust --- INSERT

	---- rdA geared ingress operation (rdAGearIgr)
	type stateRdAGearIgr_t is (
		stateRdAGearIgrInit,
		stateRdAGearIgrIdle,
		stateRdAGearIgrAddr,
		stateRdAGearIgrXfer
	);
	signal stateRdAGearIgr: stateRdAGearIgr_t;

	signal reqRdA_sig: std_logic;

	signal rdAAXI_araddr_sig: std_logic_vector(17 downto 0);
	signal rdAAXI_arvalid_sig: std_logic;
	signal rdAAXI_rready_sig: std_logic;

	signal rdAFull: boolean;
	type rdbuf_t is array (0 to NBeatRd-1) of std_logic_vector(wD-1 downto 0);
	signal rdABuf: rdbuf_t;

	-- IP sigs.rdAGearIgr.cust --- INSERT

	---- rdB geared egress operation (rdBGearEgr)
	type stateRdBGearEgr_t is (
		stateRdBGearEgrInit,
		stateRdBGearEgrIdle,
		stateRdBGearEgrAddr,
		stateRdBGearEgrWaitFull,
		stateRdBGearEgrXfer
	);
	signal stateRdBGearEgr: stateRdBGearEgr_t;

	constant rdBWD: natural := 128;

	signal rdBAXI_rdata_oprt: std_logic_vector(rdBWD-1 downto 0);
	signal rdBAXI_rlast_oprt: std_logic;

	signal rdBReady: boolean;
	signal rdBA: std_logic_vector(17 downto 0);

	-- IP sigs.rdBGearEgr.cust --- INSERT

	---- rdB geared ingress operation (rdBGearIgr)
	type stateRdBGearIgr_t is (
		stateRdBGearIgrInit,
		stateRdBGearIgrIdle,
		stateRdBGearIgrAddr,
		stateRdBGearIgrXfer
	);
	signal stateRdBGearIgr: stateRdBGearIgr_t;

	signal reqRdB_sig: std_logic;

	signal rdBAXI_araddr_sig: std_logic_vector(17 downto 0);
	signal rdBAXI_arvalid_sig: std_logic;
	signal rdBAXI_rready_sig: std_logic;

	signal rdBFull: boolean;
	signal rdBBuf: rdbuf_t;

	-- IP sigs.rdBGearIgr.cust --- INSERT

	---- read access negotiation (read)
	type stateRead_t is (
		stateReadInit,
		stateReadIdle,
		stateReadLocked
	);
	signal stateRead: stateRead_t;

	constant NRd: natural := 2;

	signal ddrAXI_arlen_sig: std_logic_vector(7 downto 0);
	signal ddrAXI_arvalid_sig: std_logic;

	signal ddrAXI_rready_sig: std_logic;
	signal abRd: natural range 0 to NRd-1;
	signal ackRd: std_logic;

	signal ackRdA_sig: std_logic;
	signal ackRdB_sig: std_logic;

	type mutex_t is (mutexIdle, mutexA, mutexB);
	signal rdmutex: mutex_t;
	signal strbRdlock: std_logic;

	type rdid_t is array (0 to 31) of mutex_t;
	signal rdid: rdid_t;
	signal ixRdid: natural range 0 to 31;
	signal ixRdidEgr: natural range 0 to 31;

	signal rdAAXI_arready_sig: std_logic;
	signal rdAAXI_rdata_sig: std_logic_vector(511 downto 0);
	signal rdAAXI_rlast_sig: std_logic;
	signal rdAAXI_rresp_sig: std_logic_vector(1 downto 0);
	signal rdAAXI_rvalid_sig: std_logic;

	signal rdBAXI_arready_sig: std_logic;
	signal rdBAXI_rdata_sig: std_logic_vector(511 downto 0);
	signal rdBAXI_rlast_sig: std_logic;
	signal rdBAXI_rresp_sig: std_logic_vector(1 downto 0);
	signal rdBAXI_rvalid_sig: std_logic;

	-- IP sigs.read.cust --- INSERT

	---- accumulate statistics (stats)
	type stateStats_t is (
		stateStatsCollectA, stateStatsCollectB
	);
	signal stateStats: stateStats_t;

	signal NRdA: std_logic_vector(31 downto 0);
	signal NRdB: std_logic_vector(31 downto 0);
	signal NWrA: std_logic_vector(31 downto 0);
	signal NWrB: std_logic_vector(31 downto 0);

	-- IP sigs.stats.cust --- INSERT

	---- wrA geared egress operation (wrAGearEgr)
	type stateWrAGearEgr_t is (
		stateWrAGearEgrInit,
		stateWrAGearEgrIdle,
		stateWrAGearEgrXfer
	);
	signal stateWrAGearEgr: stateWrAGearEgr_t;

	constant wrAWD: natural := 128;
	signal reqWrA_sig: std_logic;

	signal wrAAXI_awaddr_sig: std_logic_vector(17 downto 0);
	signal wrAAXI_awvalid_sig: std_logic;
	signal wrAAXI_wdata_sig: std_logic_vector(511 downto 0);
	signal wrAAXI_wlast_sig: std_logic;
	signal wrAAXI_wvalid_sig: std_logic;

	signal wrADoneA: boolean;
	signal wrADoneB: boolean;

	-- IP sigs.wrAGearEgr.cust --- INSERT

	---- wrA geared ingress operation (wrAGearIgr)
	type stateWrAGearIgr_t is (
		stateWrAGearIgrInit,
		stateWrAGearIgrIdle,
		stateWrAGearIgrAddr,
		stateWrAGearIgrXfer
	);
	signal stateWrAGearIgr: stateWrAGearIgr_t;

	signal wrAFillBNotA: boolean;

	signal wrAFullA: boolean;
	signal wrAFullB: boolean;

	signal wrAAa: std_logic_vector(17 downto 0);
	type wrbuf_t is array (0 to NBeatWr-1) of std_logic_vector(wD-1 downto 0);
	signal wrAAbuf: wrbuf_t;

	signal wrABa: std_logic_vector(17 downto 0);
	signal wrABbuf: wrbuf_t;

	-- IP sigs.wrAGearIgr.cust --- INSERT

	---- wrB geared egress operation (wrBGearEgr)
	type stateWrBGearEgr_t is (
		stateWrBGearEgrInit,
		stateWrBGearEgrIdle,
		stateWrBGearEgrXfer
	);
	signal stateWrBGearEgr: stateWrBGearEgr_t;

	constant wrBWD: natural := 128;
	signal reqWrB_sig: std_logic;

	signal wrBAXI_awaddr_sig: std_logic_vector(17 downto 0);
	signal wrBAXI_awvalid_sig: std_logic;
	signal wrBAXI_wdata_sig: std_logic_vector(511 downto 0);
	signal wrBAXI_wlast_sig: std_logic;
	signal wrBAXI_wvalid_sig: std_logic;

	signal wrBDoneA: boolean;
	signal wrBDoneB: boolean;

	-- IP sigs.wrBGearEgr.cust --- INSERT

	---- wrB geared ingress operation (wrBGearIgr)
	type stateWrBGearIgr_t is (
		stateWrBGearIgrInit,
		stateWrBGearIgrIdle,
		stateWrBGearIgrAddr,
		stateWrBGearIgrXfer
	);
	signal stateWrBGearIgr: stateWrBGearIgr_t;

	signal wrBFillBNotA: boolean;

	signal wrBFullA: boolean;
	signal wrBFullB: boolean;

	signal wrBAa: std_logic_vector(17 downto 0);
	signal wrBAbuf: wrbuf_t;

	signal wrBBa: std_logic_vector(17 downto 0);
	signal wrBBbuf: wrbuf_t;

	-- IP sigs.wrBGearIgr.cust --- INSERT

	---- write access negotiation (write)
	type stateWrite_t is (
		stateWriteInit,
		stateWriteIdle,
		stateWriteLocked
	);
	signal stateWrite: stateWrite_t;

	constant NWr: natural := 2;
	constant wtrmax: natural := 16;

	signal ddrAXI_awlen_sig: std_logic_vector(7 downto 0);
	signal ddrAXI_awvalid_sig: std_logic;

	signal ddrAXI_wlast_sig: std_logic;
	signal ddrAXI_wvalid_sig: std_logic;

	signal ddrAXI_bready_sig: std_logic;
	signal wtr: natural range 0 to wtrmax;
	signal abWr: natural range 0 to NWr-1;
	signal ackWr: std_logic;

	signal ackWrA_sig: std_logic;
	signal ackWrB_sig: std_logic;

	signal wrmutex: mutex_t;
	signal strbWrlock: std_logic;

	signal wrAAXI_awready_sig: std_logic;
	signal wrAAXI_wready_sig: std_logic;

	signal wrBAXI_awready_sig: std_logic;
	signal wrBAXI_wready_sig: std_logic;

	-- IP sigs.write.cust --- INSERT

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

	signal strbRdlock_mclk: std_logic;
	signal strbRdlock_to_mclkm1: std_logic;
	signal strbRdlock_to_mclkm2: std_logic;
	signal strbWrlock_mclk: std_logic;
	signal strbWrlock_to_mclkm1: std_logic;
	signal strbWrlock_to_mclkm2: std_logic;

	-- IP sigs.memclkToMclkSample.cust --- INSERT

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

	signal strbRdlock_to_mclk: std_logic;
	signal strbWrlock_to_mclk: std_logic;

	-- IP sigs.memclkToMclkStretch.cust --- INSERT

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

begin

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

	------------------------------------------------------------------------
	-- implementation: rdA geared egress operation (rdAGearEgr)
	------------------------------------------------------------------------

	-- IP impl.rdAGearEgr.wiring --- BEGIN
	ackRdA <= '1' when (stateRdAGearEgr=stateRdAGearEgrAddr or stateRdAGearEgr=stateRdAGearEgrWaitFull or stateRdAGearEgr=stateRdAGearEgrXfer) else '0';

	rdAAXI_arready <= '1' when stateRdAGearEgr=stateRdAGearEgrAddr else '0';
	rdAAXI_rdata <= rdAAXI_rdata_oprt;
	rdAAXI_rlast <= rdAAXI_rlast_oprt;
	rdAAXI_rvalid <= '1' when stateRdAGearEgr=stateRdAGearEgrXfer else '0';
	-- IP impl.rdAGearEgr.wiring --- END

	-- IP impl.rdAGearEgr.wiring.cust --- LINE

	-- IP impl.rdAGearEgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.rdAGearEgr.vars --- BEGIN
		variable i: natural range 0 to NBeatRd-1;

		constant jmax: natural := wD/rdAWD-1;
		variable j: natural range 0 to jmax;
		-- IP impl.rdAGearEgr.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.rdAGearEgr.asyncrst --- BEGIN
			stateRdAGearEgr <= stateRdAGearEgrInit;
			rdAAXI_rdata_oprt <= (others => '0');
			rdAAXI_rlast_oprt <= '1';
			rdAReady <= false;
			rdAA <= (others => '0');

			i := 0;
			j := 0;
			-- IP impl.rdAGearEgr.asyncrst --- END
			-- IP impl.rdAGearEgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if stateRdAGearEgr=stateRdAGearEgrInit then
				-- IP impl.rdAGearEgr.syncrst --- BEGIN
				rdAAXI_rdata_oprt <= (others => '0');
				rdAAXI_rlast_oprt <= '1';
				rdAReady <= false;
				rdAA <= (others => '0');

				i := 0;
				j := 0;
				-- IP impl.rdAGearEgr.syncrst --- END
				-- IP impl.rdAGearEgr.syncrst.cust --- INSERT

				stateRdAGearEgr <= stateRdAGearEgrIdle;

			elsif stateRdAGearEgr=stateRdAGearEgrIdle then
				if reqRdA='1' and not rdAFull then
					stateRdAGearEgr <= stateRdAGearEgrAddr;
				end if;

			elsif stateRdAGearEgr=stateRdAGearEgrAddr then
				if rdAAXI_arvalid='1' then
					rdAA <= rdAAXI_araddr;
					rdAReady <= true;

					stateRdAGearEgr <= stateRdAGearEgrWaitFull;
				end if;

			elsif stateRdAGearEgr=stateRdAGearEgrWaitFull then
				if rdAFull then
					i := 0;
					j := 0;

					rdAAXI_rdata_oprt <= rdABuf(i)(rdAWD-1 downto 0);
					rdAAXI_rlast_oprt <= '0';

					stateRdAGearEgr <= stateRdAGearEgrXfer;
				end if;

			elsif stateRdAGearEgr=stateRdAGearEgrXfer then
				if rdAAXI_rready='1' then
					if j=jmax then
						j := 0;

						if i=NBeatRd-1 then
							rdAReady <= false;

							stateRdAGearEgr <= stateRdAGearEgrIdle;

						else
							i := i + 1;

							rdAAXI_rdata_oprt <= rdABuf(i)(rdAWD*(j+1)-1 downto rdAWD*j);

							stateRdAGearEgr <= stateRdAGearEgrXfer;
						end if;

					else
						j := j + 1;

						rdAAXI_rdata_oprt <= rdABuf(i)(rdAWD*(j+1)-1 downto rdAWD*j);

						if i=NBeatRd-1 and j=jmax then
							rdAAXI_rlast_oprt <= '1';
						end if;

						stateRdAGearEgr <= stateRdAGearEgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.rdAGearEgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: rdA geared ingress operation (rdAGearIgr)
	------------------------------------------------------------------------

	-- IP impl.rdAGearIgr.wiring --- BEGIN
	reqRdA_sig <= '1' when (stateRdAGearIgr=stateRdAGearIgrAddr or stateRdAGearIgr=stateRdAGearIgrXfer) else '0';

	rdAAXI_arvalid_sig <= '1' when stateRdAGearIgr=stateRdAGearIgrAddr else '0';
	rdAAXI_rready_sig <= '1' when stateRdAGearIgr=stateRdAGearIgrXfer else '0';
	-- IP impl.rdAGearIgr.wiring --- END

	-- IP impl.rdAGearIgr.wiring.cust --- LINE

	-- IP impl.rdAGearIgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.rdAGearIgr.vars --- BEGIN
		variable i: natural range 0 to NBeatRd-1;
		-- IP impl.rdAGearIgr.vars --- END

	begin
		if resetMemclk='1' then
			stateRdAGearIgr <= stateRdAGearIgrInit;
			rdAAXI_araddr_sig <= (others => '0');
			rdAFull <= false;
			for i in 0 to NBeatRd-1 loop
				rdABuf(i) <= (others => '0');
			end loop;
			-- IP impl.rdAGearIgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if not rdAReady and rdAFull then
				rdAFull <= false;
			end if;

			if stateRdAGearIgr=stateRdAGearIgrInit then
				rdAAXI_araddr_sig <= (others => '0');
				rdAFull <= false;
				for i in 0 to NBeatRd-1 loop
					rdABuf(i) <= (others => '0');
				end loop;
				-- IP impl.rdAGearIgr.syncrst.cust --- INSERT

				stateRdAGearIgr <= stateRdAGearIgrIdle;

			elsif stateRdAGearIgr=stateRdAGearIgrIdle then
				if rdAReady and not rdAFull then
					rdAAXI_araddr_sig <= rdAA;

					stateRdAGearIgr <= stateRdAGearIgrAddr;
				end if;

			elsif stateRdAGearIgr=stateRdAGearIgrAddr then
				if rdAAXI_arready_sig='1' then
					i := 0;

					stateRdAGearIgr <= stateRdAGearIgrXfer;
				end if;

			elsif stateRdAGearIgr=stateRdAGearIgrXfer then
				if rdAAXI_rvalid_sig='1' then
					rdABuf(i) <= rdAAXI_rdata_sig;

					if (i=NBeatRd-1 or rdAAXI_rlast_sig='1') then
						rdAFull <= true;

						stateRdAGearIgr <= stateRdAGearIgrIdle;

					else
						i := i + 1;

						stateRdAGearIgr <= stateRdAGearIgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.rdAGearIgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: rdB geared egress operation (rdBGearEgr)
	------------------------------------------------------------------------

	-- IP impl.rdBGearEgr.wiring --- BEGIN
	ackRdB <= '1' when (stateRdBGearEgr=stateRdBGearEgrAddr or stateRdBGearEgr=stateRdBGearEgrWaitFull or stateRdBGearEgr=stateRdBGearEgrXfer) else '0';

	rdBAXI_arready <= '1' when stateRdBGearEgr=stateRdBGearEgrAddr else '0';
	rdBAXI_rdata <= rdBAXI_rdata_oprt;
	rdBAXI_rlast <= rdBAXI_rlast_oprt;
	rdBAXI_rvalid <= '1' when stateRdBGearEgr=stateRdBGearEgrXfer else '0';
	-- IP impl.rdBGearEgr.wiring --- END

	-- IP impl.rdBGearEgr.wiring.cust --- LINE

	-- IP impl.rdBGearEgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.rdBGearEgr.vars --- BEGIN
		variable i: natural range 0 to NBeatRd-1;

		constant jmax: natural := wD/rdBWD-1;
		variable j: natural range 0 to jmax;
		-- IP impl.rdBGearEgr.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.rdBGearEgr.asyncrst --- BEGIN
			stateRdBGearEgr <= stateRdBGearEgrInit;
			rdBAXI_rdata_oprt <= (others => '0');
			rdBAXI_rlast_oprt <= '1';
			rdBReady <= false;
			rdBA <= (others => '0');

			i := 0;
			j := 0;
			-- IP impl.rdBGearEgr.asyncrst --- END
			-- IP impl.rdBGearEgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if stateRdBGearEgr=stateRdBGearEgrInit then
				-- IP impl.rdBGearEgr.syncrst --- BEGIN
				rdBAXI_rdata_oprt <= (others => '0');
				rdBAXI_rlast_oprt <= '1';
				rdBReady <= false;
				rdBA <= (others => '0');

				i := 0;
				j := 0;
				-- IP impl.rdBGearEgr.syncrst --- END
				-- IP impl.rdBGearEgr.syncrst.cust --- INSERT

				stateRdBGearEgr <= stateRdBGearEgrIdle;

			elsif stateRdBGearEgr=stateRdBGearEgrIdle then
				if reqRdB='1' and not rdBFull then
					stateRdBGearEgr <= stateRdBGearEgrAddr;
				end if;

			elsif stateRdBGearEgr=stateRdBGearEgrAddr then
				if rdBAXI_arvalid='1' then
					rdBA <= rdBAXI_araddr;
					rdBReady <= true;

					stateRdBGearEgr <= stateRdBGearEgrWaitFull;
				end if;

			elsif stateRdBGearEgr=stateRdBGearEgrWaitFull then
				if rdBFull then
					i := 0;
					j := 0;

					rdBAXI_rdata_oprt <= rdBBuf(i)(rdBWD-1 downto 0);
					rdBAXI_rlast_oprt <= '0';

					stateRdBGearEgr <= stateRdBGearEgrXfer;
				end if;

			elsif stateRdBGearEgr=stateRdBGearEgrXfer then
				if rdBAXI_rready='1' then
					if j=jmax then
						j := 0;

						if i=NBeatRd-1 then
							rdBReady <= false;

							stateRdBGearEgr <= stateRdBGearEgrIdle;

						else
							i := i + 1;

							rdBAXI_rdata_oprt <= rdBBuf(i)(rdBWD*(j+1)-1 downto rdBWD*j);

							stateRdBGearEgr <= stateRdBGearEgrXfer;
						end if;

					else
						j := j + 1;

						rdBAXI_rdata_oprt <= rdBBuf(i)(rdBWD*(j+1)-1 downto rdBWD*j);

						if i=NBeatRd-1 and j=jmax then
							rdBAXI_rlast_oprt <= '1';
						end if;

						stateRdBGearEgr <= stateRdBGearEgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.rdBGearEgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: rdB geared ingress operation (rdBGearIgr)
	------------------------------------------------------------------------

	-- IP impl.rdBGearIgr.wiring --- BEGIN
	reqRdB_sig <= '1' when (stateRdBGearIgr=stateRdBGearIgrAddr or stateRdBGearIgr=stateRdBGearIgrXfer) else '0';

	rdBAXI_arvalid_sig <= '1' when stateRdBGearIgr=stateRdBGearIgrAddr else '0';
	rdBAXI_rready_sig <= '1' when stateRdBGearIgr=stateRdBGearIgrXfer else '0';
	-- IP impl.rdBGearIgr.wiring --- END

	-- IP impl.rdBGearIgr.wiring.cust --- LINE

	-- IP impl.rdBGearIgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.rdBGearIgr.vars --- BEGIN
		variable i: natural range 0 to NBeatRd-1;
		-- IP impl.rdBGearIgr.vars --- END

	begin
		if resetMemclk='1' then
			stateRdBGearIgr <= stateRdBGearIgrInit;
			rdBAXI_araddr_sig <= (others => '0');
			rdBFull <= false;
			for i in 0 to NBeatRd-1 loop
				rdBBuf(i) <= (others => '0');
			end loop;
			-- IP impl.rdBGearIgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if not rdBReady and rdBFull then
				rdBFull <= false;
			end if;

			if stateRdBGearIgr=stateRdBGearIgrInit then
				rdBAXI_araddr_sig <= (others => '0');
				rdBFull <= false;
				for i in 0 to NBeatRd-1 loop
					rdBBuf(i) <= (others => '0');
				end loop;
				-- IP impl.rdBGearIgr.syncrst.cust --- INSERT

				stateRdBGearIgr <= stateRdBGearIgrIdle;

			elsif stateRdBGearIgr=stateRdBGearIgrIdle then
				if rdBReady and not rdBFull then
					rdBAXI_araddr_sig <= rdBA;

					stateRdBGearIgr <= stateRdBGearIgrAddr;
				end if;

			elsif stateRdBGearIgr=stateRdBGearIgrAddr then
				if rdBAXI_arready_sig='1' then
					i := 0;

					stateRdBGearIgr <= stateRdBGearIgrXfer;
				end if;

			elsif stateRdBGearIgr=stateRdBGearIgrXfer then
				if rdBAXI_rvalid_sig='1' then
					rdBBuf(i) <= rdBAXI_rdata_sig;

					if (i=NBeatRd-1 or rdBAXI_rlast_sig='1') then
						rdBFull <= true;

						stateRdBGearIgr <= stateRdBGearIgrIdle;

					else
						i := i + 1;

						stateRdBGearIgr <= stateRdBGearIgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.rdBGearIgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: read access negotiation (read)
	------------------------------------------------------------------------

	-- IP impl.read.wiring --- BEGIN
	ddrAXI_arid <= "000000";
	ddrAXI_arburst <= "01"; -- INCR burst type
	ddrAXI_arcache <= "0000"; -- device non-bufferable memory type
	ddrAXI_arlen_sig <= std_logic_vector(to_unsigned(NBeatRd - 1, 8));
	ddrAXI_arlen <= ddrAXI_arlen_sig;
	ddrAXI_arlock <= "0"; -- non-exclusive access
	ddrAXI_arprot <= "010"; -- unprivileged, non-secure data access
	ddrAXI_arqos <= "1101"; -- not participating in QoS scheme
	ddrAXI_arregion <= "0000"; -- region feature not used
	ddrAXI_arsize <= "110"; -- 512-bit wide transfers

	ackRd <= '1' when stateRead=stateReadLocked else '0';

	ackRdA_sig <= ackRd when rdmutex=mutexA else '0';
	ackRdB_sig <= ackRd when rdmutex=mutexB else '0';

	rdAAXI_arready_sig <= ddrAXI_arready when rdmutex=mutexA else '0';
	rdAAXI_rdata_sig <= ddrAXI_rdata;
	rdAAXI_rlast_sig <= ddrAXI_rlast when rdid(ixRdidEgr)=mutexA else '1';
	rdAAXI_rresp_sig <= ddrAXI_rresp;
	rdAAXI_rvalid_sig <= ddrAXI_rvalid when rdid(ixRdidEgr)=mutexA else '0';

	rdBAXI_arready_sig <= ddrAXI_arready when rdmutex=mutexB else '0';
	rdBAXI_rdata_sig <= ddrAXI_rdata;
	rdBAXI_rlast_sig <= ddrAXI_rlast when rdid(ixRdidEgr)=mutexB else '1';
	rdBAXI_rresp_sig <= ddrAXI_rresp;
	rdBAXI_rvalid_sig <= ddrAXI_rvalid when rdid(ixRdidEgr)=mutexB else '0';
	-- IP impl.read.wiring --- END

	ddrAXI_araddr <= "0000001" & rdAAXI_araddr_sig & "00000000" when rdmutex=mutexA
				else "0000001" & rdBAXI_araddr_sig & "00000000" when rdmutex=mutexB
				else (others => '0');

	ddrAXI_arvalid <= ddrAXI_arvalid_sig;
	ddrAXI_arvalid_sig <= rdAAXI_arvalid_sig when rdmutex=mutexA
				else rdBAXI_arvalid_sig when rdmutex=mutexB
				else '0';

	ddrAXI_rready <= ddrAXI_rready_sig;
	ddrAXI_rready_sig <= rdAAXI_rready_sig when rdid(ixRdidEgr)=mutexA
				else rdBAXI_rready_sig when rdid(ixRdidEgr)=mutexB
				else '0';

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

	begin
		if resetMemclk='1' then
			-- IP impl.read.asyncrst --- BEGIN
			stateRead <= stateReadInit;
			abRd <= 0;
			rdmutex <= mutexIdle;
			strbRdlock <= '0';
			rdid <= (others => mutexIdle);
			ixRdid <= 0;
			ixRdidEgr <= 0;

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

		elsif rising_edge(memclk) then
			if ddrAXI_rready_sig='1' and ddrAXI_rvalid='1' and ddrAXI_rlast='1' then
				rdid(ixRdidEgr) <= mutexIdle;

				if ixRdidEgr=31 then
					ixRdidEgr <= 0;
				else
					ixRdidEgr <= ixRdidEgr + 1;
				end if;
			end if;

			if stateRead=stateReadInit then
				-- IP impl.read.syncrst --- BEGIN
				abRd <= 0;
				rdmutex <= mutexIdle;
				strbRdlock <= '0';
				rdid <= (others => mutexIdle);
				ixRdid <= 0;
				ixRdidEgr <= 0;

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

				stateRead <= stateReadIdle;

			elsif stateRead=stateReadIdle then
				if (reqRdA_sig='1' and ((abRd=0 and reqRdB_sig='0') or abRd=1) and rdid(ixRdid)=mutexIdle) then
					abRd <= 0;
					rdmutex <= mutexA;

					strbRdlock <= '1';

					rdid(ixRdid) <= mutexA;

					stateRead <= stateReadLocked;

				elsif (reqRdB_sig='1' and ((abRd=1 and reqRdA_sig='0') or abRd=0) and rdid(ixRdid)=mutexIdle) then
					abRd <= 1;
					rdmutex <= mutexB;

					strbRdlock <= '1';

					rdid(ixRdid) <= mutexB;

					stateRead <= stateReadLocked;
				end if;

			elsif stateRead=stateReadLocked then
				strbRdlock <= '0';

				if (ddrAXI_arready='1' and ddrAXI_arvalid_sig='1') then
					rdmutex <= mutexIdle;

					if ixRdid=31 then
						ixRdid <= 0;
					else
						ixRdid <= ixRdid + 1;
					end if;

					stateRead <= stateReadIdle;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.read.rising --- END

	------------------------------------------------------------------------
	-- implementation: accumulate statistics (stats)
	------------------------------------------------------------------------

	-- IP impl.stats.wiring --- BEGIN
	getStatsNRdA <= NRdA;
	getStatsNRdB <= NRdB;
	getStatsNWrA <= NWrA;
	getStatsNWrB <= NWrB;
	-- IP impl.stats.wiring --- END

	-- IP impl.stats.wiring.cust --- LINE

	-- IP impl.stats.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.stats.vars --- BEGIN
		constant imax: natural := 10000; -- 1 s
		variable i: natural range 0 to imax;

		variable NRdA_collect: std_logic_vector(31 downto 0);
		variable NRdB_collect: std_logic_vector(31 downto 0);
		variable NWrA_collect: std_logic_vector(31 downto 0);
		variable NWrB_collect: std_logic_vector(31 downto 0);
		-- IP impl.stats.vars --- END

	begin
		if reset='1' then
			-- IP impl.stats.asyncrst --- BEGIN
			stateStats <= stateStatsCollectA;
			NRdA <= (others => '0');
			NRdB <= (others => '0');
			NWrA <= (others => '0');
			NWrB <= (others => '0');

			i := 0;
			NRdA_collect := (others => '0');
			NRdB_collect := (others => '0');
			NWrA_collect := (others => '0');
			NWrB_collect := (others => '0');
			-- IP impl.stats.asyncrst --- END
			-- IP impl.stats.asyncrst.cust --- INSERT

		elsif rising_edge(mclk) then
			if strbRdlock_mclk='1' then
				case rdmutex is
					when mutexA =>
						NRdA_collect := std_logic_vector(unsigned(NRdA_collect) + unsigned(ddrAXI_arlen_sig) + 1);
					when mutexB =>
						NRdB_collect := std_logic_vector(unsigned(NRdB_collect) + unsigned(ddrAXI_arlen_sig) + 1);
					when others =>
				end case;
			end if;

			if strbWrlock_mclk='1' then
				case wrmutex is
					when mutexA =>
						NWrA_collect := std_logic_vector(unsigned(NWrA_collect) + unsigned(ddrAXI_awlen_sig) + 1);
					when mutexB =>
						NWrB_collect := std_logic_vector(unsigned(NWrB_collect) + unsigned(ddrAXI_awlen_sig) + 1);
					when others =>
				end case;
			end if;

			if stateStats=stateStatsCollectA then
				if tkclk='1' then
					if i=imax then
						i := 0;

						NRdA <= NRdA_collect;
						NRdA_collect := (others => '0');

						NRdB <= NRdB_collect;
						NRdB_collect := (others => '0');

						NWrA <= NWrA_collect;
						NWrA_collect := (others => '0');

						NWrB <= NWrB_collect;
						NWrB_collect := (others => '0');
					end if;

					stateStats <= stateStatsCollectB;
				end if;

			elsif stateStats=stateStatsCollectB then
				if tkclk='0' then
					i := i + 1;

					stateStats <= stateStatsCollectA;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.stats.rising --- END

	------------------------------------------------------------------------
	-- implementation: wrA geared egress operation (wrAGearEgr)
	------------------------------------------------------------------------

	-- IP impl.wrAGearEgr.wiring --- BEGIN
	reqWrA_sig <= '1' when stateWrAGearEgr=stateWrAGearEgrXfer else '0';
	-- IP impl.wrAGearEgr.wiring --- END

	-- IP impl.wrAGearEgr.wiring.cust --- LINE

	-- IP impl.wrAGearEgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.wrAGearEgr.vars --- BEGIN
		variable i: natural range 0 to NBeatWr-1;

		variable awdone: boolean;
		variable wdone: boolean;
		-- IP impl.wrAGearEgr.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.wrAGearEgr.asyncrst --- BEGIN
			stateWrAGearEgr <= stateWrAGearEgrInit;
			wrAAXI_awaddr_sig <= (others => '0');
			wrAAXI_awvalid_sig <= '0';
			wrAAXI_wdata_sig <= (others => '0');
			wrAAXI_wlast_sig <= '1';
			wrAAXI_wvalid_sig <= '0';
			wrADoneA <= false;
			wrADoneB <= false;

			i := 0;
			awdone := false;
			wdone := false;
			-- IP impl.wrAGearEgr.asyncrst --- END
			-- IP impl.wrAGearEgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if wrAFillBNotA and not wrAFullA and wrADoneA then
				wrADoneA <= false;
			end if;

			if not wrAFillBNotA and not wrAFullB and wrADoneB then
				wrADoneB <= false;
			end if;

			if stateWrAGearEgr=stateWrAGearEgrInit then
				wrAAXI_awaddr_sig <= (others => '0');
				wrAAXI_awvalid_sig <= '0';
				wrAAXI_wdata_sig <= (others => '0');
				wrAAXI_wlast_sig <= '1';
				wrAAXI_wvalid_sig <= '0';

				i := 0;
				awdone := false;
				wdone := false;
				-- IP impl.wrAGearEgr.syncrst.cust --- INSERT

				stateWrAGearEgr <= stateWrAGearEgrIdle;

			elsif stateWrAGearEgr=stateWrAGearEgrIdle then
				if wrAFillBNotA and wrAFullA and not wrADoneA then
					wrAAXI_awaddr_sig <= wrAAa;
					wrAAXI_awvalid_sig <= '1';

					wrAAXI_wdata_sig <= wrAAbuf(0);
					wrAAXI_wlast_sig <= '0';
					wrAAXI_wvalid_sig <= '1';

					i := 0;

					awdone := false;
					wdone := false;

					stateWrAGearEgr <= stateWrAGearEgrXfer;

				elsif not wrAFillBNotA and wrAFullB and not wrADoneB then
					wrAAXI_awaddr_sig <= wrABa;
					wrAAXI_awvalid_sig <= '1';

					wrAAXI_wdata_sig <= wrABbuf(0);
					wrAAXI_wlast_sig <= '0';
					wrAAXI_wvalid_sig <= '1';

					i := 0;

					awdone := false;
					wdone := false;

					stateWrAGearEgr <= stateWrAGearEgrXfer;
				end if;

			elsif stateWrAGearEgr=stateWrAGearEgrXfer then
				if not awdone and wrAAXI_awready_sig='1' then
					wrAAXI_awvalid_sig <= '0';

					awdone := true;
				end if;

				if not wdone and wrAAXI_wready_sig='1' then
					if wrAAXI_wlast_sig='1' then
						wrAAXI_wvalid_sig <= '0';

						wdone := true;
					else
						i := i + 1;

						if wrAFillBNotA then
							wrAAXI_wdata_sig <= wrAAbuf(i);
						else
							wrAAXI_wdata_sig <= wrABbuf(i);
						end if;

						if i=NBeatWr-1 then
							wrAAXI_wlast_sig <= '1';
						end if;
					end if;
				end if;

				if awdone and wdone then
					if wrAFillBNotA then
						wrADoneA <= true;
					else
						wrADoneB <= true;
					end if;

					stateWrAGearEgr <= stateWrAGearEgrIdle;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.wrAGearEgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: wrA geared ingress operation (wrAGearIgr)
	------------------------------------------------------------------------

	-- IP impl.wrAGearIgr.wiring --- BEGIN
	ackWrA <= '1' when (stateWrAGearIgr=stateWrAGearIgrAddr or stateWrAGearIgr=stateWrAGearIgrXfer) else '0';

	wrAAXI_awready <= '1' when stateWrAGearIgr=stateWrAGearIgrAddr else '0';
	wrAAXI_wready <= '1' when stateWrAGearIgr=stateWrAGearIgrXfer else '0';
	-- IP impl.wrAGearIgr.wiring --- END

	-- IP impl.wrAGearIgr.wiring.cust --- LINE

	-- IP impl.wrAGearIgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.wrAGearIgr.vars --- BEGIN
		variable i: natural range 0 to NBeatWr-1;

		constant jmax: natural := wD/wrAWD-1;
		variable j: natural range 0 to jmax;
		-- IP impl.wrAGearIgr.vars --- END

	begin
		if resetMemclk='1' then
			stateWrAGearIgr <= stateWrAGearIgrInit;
			wrAFillBNotA <= false;
			wrAFullA <= false;
			wrAFullB <= false;
			wrAAa <= (others => '0');
			for i in 0 to NBeatWr-1 loop
				wrAAbuf(i) <= (others => '0');
			end loop;
			wrABa <= (others => '0');
			for i in 0 to NBeatWr-1 loop
				wrABbuf(i) <= (others => '0');
			end loop;
			-- IP impl.wrAGearIgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if not wrAFillBNotA and wrAFullB and wrADoneB then
				wrAFullB <= false;
			end if;

			if wrAFillBNotA and wrAFullA and wrADoneA then
				wrAFullA <= false;
			end if;

			if stateWrAGearIgr=stateWrAGearIgrInit then
				wrAFillBNotA <= false;
				wrAAa <= (others => '0');
				for i in 0 to NBeatWr-1 loop
					wrAAbuf(i) <= (others => '0');
				end loop;
				wrABa <= (others => '0');
				for i in 0 to NBeatWr-1 loop
					wrABbuf(i) <= (others => '0');
				end loop;
				-- IP impl.wrAGearIgr.syncrst.cust --- INSERT

				stateWrAGearIgr <= stateWrAGearIgrIdle;

			elsif stateWrAGearIgr=stateWrAGearIgrIdle then
				if reqWrA='1' and ((not wrAFillBNotA and not wrAFullA) or (wrAFillBNotA and not wrAFullB)) then
					stateWrAGearIgr <= stateWrAGearIgrAddr;
				end if;

			elsif stateWrAGearIgr=stateWrAGearIgrAddr then
				if wrAAXI_awvalid='1' then
					if not wrAFillBNotA then
						wrAAa <= wrAAXI_awaddr;
					else
						wrABa <= wrAAXI_awaddr;
					end if;

					i := 0;
					j := 0;

					stateWrAGearIgr <= stateWrAGearIgrXfer;
				end if;

			elsif stateWrAGearIgr=stateWrAGearIgrXfer then
				if wrAAXI_wvalid='1' then
					if not wrAFillBNotA then
						wrAAbuf(i)(wrAWD*(j+1)-1 downto wrAWD*j) <= wrAAXI_wdata;
					else
						wrABbuf(i)(wrAWD*(j+1)-1 downto wrAWD*j) <= wrAAXI_wdata;
					end if;

					if j=jmax then
						j := 0;

						if i=NBeatWr-1 then
							if not wrAFillBNotA then
								wrAFullA <= true;
							else
								wrAFullB <= true;
							end if;

							wrAFillBNotA <= not wrAFillBNotA;

							stateWrAGearIgr <= stateWrAGearIgrIdle;

						else
							i := i + 1;

							stateWrAGearIgr <= stateWrAGearIgrXfer;
						end if;

					else
						j := j + 1;

						stateWrAGearIgr <= stateWrAGearIgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.wrAGearIgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: wrB geared egress operation (wrBGearEgr)
	------------------------------------------------------------------------

	-- IP impl.wrBGearEgr.wiring --- BEGIN
	reqWrB_sig <= '1' when stateWrBGearEgr=stateWrBGearEgrXfer else '0';
	-- IP impl.wrBGearEgr.wiring --- END

	-- IP impl.wrBGearEgr.wiring.cust --- LINE

	-- IP impl.wrBGearEgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.wrBGearEgr.vars --- BEGIN
		variable i: natural range 0 to NBeatWr-1;

		variable awdone: boolean;
		variable wdone: boolean;
		-- IP impl.wrBGearEgr.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.wrBGearEgr.asyncrst --- BEGIN
			stateWrBGearEgr <= stateWrBGearEgrInit;
			wrBAXI_awaddr_sig <= (others => '0');
			wrBAXI_awvalid_sig <= '0';
			wrBAXI_wdata_sig <= (others => '0');
			wrBAXI_wlast_sig <= '1';
			wrBAXI_wvalid_sig <= '0';
			wrBDoneA <= false;
			wrBDoneB <= false;

			i := 0;
			awdone := false;
			wdone := false;
			-- IP impl.wrBGearEgr.asyncrst --- END
			-- IP impl.wrBGearEgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if wrBFillBNotA and not wrBFullA and wrBDoneA then
				wrBDoneA <= false;
			end if;

			if not wrBFillBNotA and not wrBFullB and wrBDoneB then
				wrBDoneB <= false;
			end if;

			if stateWrBGearEgr=stateWrBGearEgrInit then
				wrBAXI_awaddr_sig <= (others => '0');
				wrBAXI_awvalid_sig <= '0';
				wrBAXI_wdata_sig <= (others => '0');
				wrBAXI_wlast_sig <= '1';
				wrBAXI_wvalid_sig <= '0';

				i := 0;
				awdone := false;
				wdone := false;
				-- IP impl.wrBGearEgr.syncrst.cust --- INSERT

				stateWrBGearEgr <= stateWrBGearEgrIdle;

			elsif stateWrBGearEgr=stateWrBGearEgrIdle then
				if wrBFillBNotA and wrBFullA and not wrBDoneA then
					wrBAXI_awaddr_sig <= wrBAa;
					wrBAXI_awvalid_sig <= '1';

					wrBAXI_wdata_sig <= wrBAbuf(0);
					wrBAXI_wlast_sig <= '0';
					wrBAXI_wvalid_sig <= '1';

					i := 0;

					awdone := false;
					wdone := false;

					stateWrBGearEgr <= stateWrBGearEgrXfer;

				elsif not wrBFillBNotA and wrBFullB and not wrBDoneB then
					wrBAXI_awaddr_sig <= wrBBa;
					wrBAXI_awvalid_sig <= '1';

					wrBAXI_wdata_sig <= wrBBbuf(0);
					wrBAXI_wlast_sig <= '0';
					wrBAXI_wvalid_sig <= '1';

					i := 0;

					awdone := false;
					wdone := false;

					stateWrBGearEgr <= stateWrBGearEgrXfer;
				end if;

			elsif stateWrBGearEgr=stateWrBGearEgrXfer then
				if not awdone and wrBAXI_awready_sig='1' then
					wrBAXI_awvalid_sig <= '0';

					awdone := true;
				end if;

				if not wdone and wrBAXI_wready_sig='1' then
					if wrBAXI_wlast_sig='1' then
						wrBAXI_wvalid_sig <= '0';

						wdone := true;
					else
						i := i + 1;

						if wrBFillBNotA then
							wrBAXI_wdata_sig <= wrBAbuf(i);
						else
							wrBAXI_wdata_sig <= wrBBbuf(i);
						end if;

						if i=NBeatWr-1 then
							wrBAXI_wlast_sig <= '1';
						end if;
					end if;
				end if;

				if awdone and wdone then
					if wrBFillBNotA then
						wrBDoneA <= true;
					else
						wrBDoneB <= true;
					end if;

					stateWrBGearEgr <= stateWrBGearEgrIdle;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.wrBGearEgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: wrB geared ingress operation (wrBGearIgr)
	------------------------------------------------------------------------

	-- IP impl.wrBGearIgr.wiring --- BEGIN
	ackWrB <= '1' when (stateWrBGearIgr=stateWrBGearIgrAddr or stateWrBGearIgr=stateWrBGearIgrXfer) else '0';

	wrBAXI_awready <= '1' when stateWrBGearIgr=stateWrBGearIgrAddr else '0';
	wrBAXI_wready <= '1' when stateWrBGearIgr=stateWrBGearIgrXfer else '0';
	-- IP impl.wrBGearIgr.wiring --- END

	-- IP impl.wrBGearIgr.wiring.cust --- LINE

	-- IP impl.wrBGearIgr.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.wrBGearIgr.vars --- BEGIN
		variable i: natural range 0 to NBeatWr-1;

		constant jmax: natural := wD/wrBWD-1;
		variable j: natural range 0 to jmax;
		-- IP impl.wrBGearIgr.vars --- END

	begin
		if resetMemclk='1' then
			stateWrBGearIgr <= stateWrBGearIgrInit;
			wrBFillBNotA <= false;
			wrBFullA <= false;
			wrBFullB <= false;
			wrBAa <= (others => '0');
			for i in 0 to NBeatWr-1 loop
				wrBAbuf(i) <= (others => '0');
			end loop;
			wrBBa <= (others => '0');
			for i in 0 to NBeatWr-1 loop
				wrBBbuf(i) <= (others => '0');
			end loop;
			-- IP impl.wrBGearIgr.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if not wrBFillBNotA and wrBFullB and wrBDoneB then
				wrBFullB <= false;
			end if;

			if wrBFillBNotA and wrBFullA and wrBDoneA then
				wrBFullA <= false;
			end if;

			if stateWrBGearIgr=stateWrBGearIgrInit then
				wrBFillBNotA <= false;
				wrBAa <= (others => '0');
				for i in 0 to NBeatWr-1 loop
					wrBAbuf(i) <= (others => '0');
				end loop;
				wrBBa <= (others => '0');
				for i in 0 to NBeatWr-1 loop
					wrBBbuf(i) <= (others => '0');
				end loop;
				-- IP impl.wrBGearIgr.syncrst.cust --- INSERT

				stateWrBGearIgr <= stateWrBGearIgrIdle;

			elsif stateWrBGearIgr=stateWrBGearIgrIdle then
				if reqWrB='1' and ((not wrBFillBNotA and not wrBFullA) or (wrBFillBNotA and not wrBFullB)) then
					stateWrBGearIgr <= stateWrBGearIgrAddr;
				end if;

			elsif stateWrBGearIgr=stateWrBGearIgrAddr then
				if wrBAXI_awvalid='1' then
					if not wrBFillBNotA then
						wrBAa <= wrBAXI_awaddr;
					else
						wrBBa <= wrBAXI_awaddr;
					end if;

					i := 0;
					j := 0;

					stateWrBGearIgr <= stateWrBGearIgrXfer;
				end if;

			elsif stateWrBGearIgr=stateWrBGearIgrXfer then
				if wrBAXI_wvalid='1' then
					if not wrBFillBNotA then
						wrBAbuf(i)(wrBWD*(j+1)-1 downto wrBWD*j) <= wrBAXI_wdata;
					else
						wrBBbuf(i)(wrBWD*(j+1)-1 downto wrBWD*j) <= wrBAXI_wdata;
					end if;

					if j=jmax then
						j := 0;

						if i=NBeatWr-1 then
							if not wrBFillBNotA then
								wrBFullA <= true;
							else
								wrBFullB <= true;
							end if;

							wrBFillBNotA <= not wrBFillBNotA;

							stateWrBGearIgr <= stateWrBGearIgrIdle;

						else
							i := i + 1;

							stateWrBGearIgr <= stateWrBGearIgrXfer;
						end if;

					else
						j := j + 1;

						stateWrBGearIgr <= stateWrBGearIgrXfer;
					end if;
				end if;
			end if;
		end if;
	end process;
	-- IP impl.wrBGearIgr.rising --- END

	------------------------------------------------------------------------
	-- implementation: write access negotiation (write)
	------------------------------------------------------------------------

	-- IP impl.write.wiring --- BEGIN
	ddrAXI_awid <= "000000";
	ddrAXI_awburst <= "01"; -- INCR burst type
	ddrAXI_awcache <= "0000"; -- device non-bufferable memory type
	ddrAXI_awlen_sig <= std_logic_vector(to_unsigned(NBeatWr - 1, 8));
	ddrAXI_awlen <= ddrAXI_awlen_sig;
	ddrAXI_awlock <= "0"; -- non-exclusive access
	ddrAXI_awprot <= "010"; -- unprivileged, non-secure data access
	ddrAXI_awqos <= "1101"; -- not participating in QoS scheme
	ddrAXI_awregion <= "0000"; -- region feature not used
	ddrAXI_awsize <= "110"; -- 512-bit wide transfers

	ddrAXI_wstrb <= "1111111111111111111111111111111111111111111111111111111111111111"; -- no sparse tranfsers

	ddrAXI_bready <= ddrAXI_bready_sig;
	ackWr <= '1' when stateWrite=stateWriteLocked else '0';

	ackWrA_sig <= ackWr when wrmutex=mutexA else '0';
	ackWrB_sig <= ackWr when wrmutex=mutexB else '0';

	wrAAXI_awready_sig <= ddrAXI_awready when wrmutex=mutexA else '0';
	wrAAXI_wready_sig <= ddrAXI_wready when wrmutex=mutexA else '0';

	wrBAXI_awready_sig <= ddrAXI_awready when wrmutex=mutexB else '0';
	wrBAXI_wready_sig <= ddrAXI_wready when wrmutex=mutexB else '0';
	-- IP impl.write.wiring --- END

	ddrAXI_awaddr <= "0000001" & wrAAXI_awaddr_sig & "00000000" when wrmutex=mutexA
				else "0000001" & wrBAXI_awaddr_sig & "00000000" when wrmutex=mutexB
				else (others => '0');

	ddrAXI_awvalid <= ddrAXI_awvalid_sig;
	ddrAXI_awvalid_sig <= wrAAXI_awvalid_sig when wrmutex=mutexA
				else wrBAXI_awvalid_sig when wrmutex=mutexB
				else '0';

	ddrAXI_wdata <= wrAAXI_wdata_sig when wrmutex=mutexA
				else wrBAXI_wdata_sig when wrmutex=mutexB
				else (others => '0');

	ddrAXI_wlast <= ddrAXI_wlast_sig;
	ddrAXI_wlast_sig <= wrAAXI_wlast_sig when wrmutex=mutexA
				else wrBAXI_wlast_sig when wrmutex=mutexB
				else '1';

	ddrAXI_wvalid <= ddrAXI_wvalid_sig;
	ddrAXI_wvalid_sig <= wrAAXI_wvalid_sig when wrmutex=mutexA
				else wrBAXI_wvalid_sig when wrmutex=mutexB
				else '0';

	-- IP impl.write.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.write.vars --- BEGIN
		variable inc: boolean;
		variable dec: boolean;

		variable awdone: boolean;
		variable wdone: boolean;
		-- IP impl.write.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.write.asyncrst --- BEGIN
			stateWrite <= stateWriteInit;
			ddrAXI_bready_sig <= '0';
			wtr <= 0;
			abWr <= 0;
			wrmutex <= mutexIdle;
			strbWrlock <= '0';

			inc := false;
			dec := false;
			awdone := false;
			wdone := false;
			-- IP impl.write.asyncrst --- END
			-- IP impl.write.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			inc := false;
			if ddrAXI_bready_sig='1' and ddrAXI_bvalid='1' then
				dec := true;
			else
				dec := false;
			end if;

			if stateWrite=stateWriteInit then
				-- IP impl.write.syncrst --- BEGIN
				ddrAXI_bready_sig <= '0';
				wtr <= 0;
				abWr <= 0;
				wrmutex <= mutexIdle;
				strbWrlock <= '0';

				inc := false;
				dec := false;
				awdone := false;
				wdone := false;
				-- IP impl.write.syncrst --- END
				-- IP impl.write.syncrst.cust --- INSERT

				stateWrite <= stateWriteIdle;

			elsif stateWrite=stateWriteIdle then
				if wtr/=wtrmax then
					if (reqWrA_sig='1' and ((abWr=0 and reqWrB_sig='0') or abWr=1)) then
						abWr <= 0;
						wrmutex <= mutexA;

						strbWrlock <= '1';

						inc := true;

						awdone := false;
						wdone := false;

						stateWrite <= stateWriteLocked;

					elsif (reqWrB_sig='1' and ((abWr=1 and reqWrA_sig='0') or abWr=0)) then
						abWr <= 1;
						wrmutex <= mutexB;

						strbWrlock <= '1';

						inc := true;

						awdone := false;
						wdone := false;

						stateWrite <= stateWriteLocked;
					end if;
				end if;

			elsif stateWrite=stateWriteLocked then
				strbWrlock <= '0';

				if not awdone and ddrAXI_awready='1' and ddrAXI_awvalid_sig='1' then
					awdone := true;
				end if;

				if not wdone and ddrAXI_wready='1' and ddrAXI_wvalid_sig='1' and ddrAXI_wlast_sig='1' then
					wdone := true;
				end if;

				if awdone and wdone then
					wrmutex <= mutexIdle;

					stateWrite <= stateWriteIdle;
				end if;
			end if;

			if inc and not dec and wtr/=wtrmax then
				ddrAXI_bready_sig <= '1';
				wtr <= wtr + 1;

			elsif not inc and dec and wtr/=0 then
				if wtr=1 then
					ddrAXI_bready_sig <= '0';
				end if;

				wtr <= wtr - 1;
			end if;

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

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

	-- IP impl.memclkToMclkSample.wiring --- BEGIN
	-- IP impl.memclkToMclkSample.wiring --- END

	-- IP impl.memclkToMclkSample.wiring.cust --- LINE

	-- IP impl.memclkToMclkSample.rising --- BEGIN
	process (reset, mclk)
		-- IP impl.memclkToMclkSample.vars --- BEGIN
		variable strbRdlock_wait: boolean;
		variable strbWrlock_wait: boolean;
		-- IP impl.memclkToMclkSample.vars --- END

	begin
		if reset='1' then
			-- IP impl.memclkToMclkSample.asyncrst --- BEGIN
			strbRdlock_mclk <= '0';
			strbRdlock_to_mclkm1 <= '0';
			strbRdlock_to_mclkm2 <= '0';
			strbWrlock_mclk <= '0';
			strbWrlock_to_mclkm1 <= '0';
			strbWrlock_to_mclkm2 <= '0';

			strbRdlock_wait := false;
			strbWrlock_wait := false;
			-- IP impl.memclkToMclkSample.asyncrst --- END
			-- IP impl.memclkToMclkSample.asyncrst.cust --- INSERT

		elsif rising_edge(mclk) then
			if strbRdlock_mclk='1' then
				strbRdlock_mclk <= '0';
			elsif strbRdlock_to_mclkm1='1' and strbRdlock_to_mclkm2='1' and not strbRdlock_wait then
				strbRdlock_mclk <= '1';
				strbRdlock_wait := true;
			end if;
			if strbRdlock_to_mclkm1='0' and strbRdlock_to_mclkm2='0' and strbRdlock_wait then
				strbRdlock_wait := false;
			end if;
			strbRdlock_to_mclkm1 <= strbRdlock_to_mclk;
			strbRdlock_to_mclkm2 <= strbRdlock_to_mclkm1;

			if strbWrlock_mclk='1' then
				strbWrlock_mclk <= '0';
			elsif strbWrlock_to_mclkm1='1' and strbWrlock_to_mclkm2='1' and not strbWrlock_wait then
				strbWrlock_mclk <= '1';
				strbWrlock_wait := true;
			end if;
			if strbWrlock_to_mclkm1='0' and strbWrlock_to_mclkm2='0' and strbWrlock_wait then
				strbWrlock_wait := false;
			end if;
			strbWrlock_to_mclkm1 <= strbWrlock_to_mclk;
			strbWrlock_to_mclkm2 <= strbWrlock_to_mclkm1;

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

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

	-- IP impl.memclkToMclkStretch.wiring --- BEGIN
	-- IP impl.memclkToMclkStretch.wiring --- END

	-- IP impl.memclkToMclkStretch.wiring.cust --- LINE

	-- IP impl.memclkToMclkStretch.rising --- BEGIN
	process (resetMemclk, memclk)
		-- IP impl.memclkToMclkStretch.vars --- BEGIN
		constant imax: natural := 10;

		variable strbRdlock_i: natural range 0 to imax;
		variable strbWrlock_i: natural range 0 to imax;
		-- IP impl.memclkToMclkStretch.vars --- END

	begin
		if resetMemclk='1' then
			-- IP impl.memclkToMclkStretch.asyncrst --- BEGIN
			strbRdlock_to_mclk <= '0';
			strbWrlock_to_mclk <= '0';

			strbRdlock_i := 0;
			strbWrlock_i := 0;
			-- IP impl.memclkToMclkStretch.asyncrst --- END
			-- IP impl.memclkToMclkStretch.asyncrst.cust --- INSERT

		elsif rising_edge(memclk) then
			if strbRdlock='1' then
				strbRdlock_to_mclk <= '1';
				strbRdlock_i := 0;
			elsif strbRdlock_i=imax then
				strbRdlock_to_mclk <= '0';
			else
				strbRdlock_i := strbRdlock_i + 1;
			end if;

			if strbWrlock='1' then
				strbWrlock_to_mclk <= '1';
				strbWrlock_i := 0;
			elsif strbWrlock_i=imax then
				strbWrlock_to_mclk <= '0';
			else
				strbWrlock_i := strbWrlock_i + 1;
			end if;

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

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

	

end Rtl;
