0

I’m using Vivado to auto generate an AXI Full Master template. Within the template it gives a state-machine which is shown:

IDLE => WRITE => READ => IDLE.

And the template of AXI Full Master ports are:

				
INIT_AXI_TXN : in Std_logic;  -- Initiate AXI transactions
TXN_DONE     : out Std_logic; -- Asserts when transaction is complete
ERROR        : out Std_logic; -- Asserts when ERROR is detected

M_AXI_ACLK    : in Std_logic;
M_AXI_ARESETN : in Std_logic;

M_AXI_AWID    : out Std_logic_vector(C_M_AXI_ID_WIDTH - 1 downto 0);     -- Master Interface Write Address ID
M_AXI_AWADDR  : out Std_logic_vector(C_M_AXI_ADDR_WIDTH - 1 downto 0);   -- Master Interface Write Address
M_AXI_AWLEN   : out Std_logic_vector(7 downto 0);                        -- Burst length. The burst length gives the exact number of transfers in a burst
M_AXI_AWSIZE  : out Std_logic_vector(2 downto 0);                        -- Burst size. This signal indicates the size of each transfer in the burst
M_AXI_AWBURST : out Std_logic_vector(1 downto 0);                        -- always "00"
M_AXI_AWLOCK  : out Std_logic;                                           -- ignore
M_AXI_AWCACHE : out Std_logic_vector(3 downto 0);                        -- ignore
M_AXI_AWPROT  : out Std_logic_vector(2 downto 0);                        -- ignore
M_AXI_AWQOS   : out Std_logic_vector(3 downto 0);                        -- ignore
M_AXI_AWUSER  : out Std_logic_vector(C_M_AXI_AWUSER_WIDTH - 1 downto 0); -- ignore
M_AXI_AWVALID : out Std_logic;
M_AXI_AWREADY : in Std_logic;

M_AXI_WDATA  : out Std_logic_vector(C_M_AXI_DATA_WIDTH - 1 downto 0);   -- required
M_AXI_WSTRB  : out Std_logic_vector(C_M_AXI_DATA_WIDTH/8 - 1 downto 0); -- ignore
M_AXI_WLAST  : out Std_logic;                                           -- required
M_AXI_WUSER  : out Std_logic_vector(C_M_AXI_WUSER_WIDTH - 1 downto 0);  -- ignore
M_AXI_WVALID : out Std_logic;                                           -- required
M_AXI_WREADY : in Std_logic;                                            -- required

M_AXI_BID    : in Std_logic_vector(C_M_AXI_ID_WIDTH - 1 downto 0);
M_AXI_BRESP  : in Std_logic_vector(1 downto 0);
M_AXI_BUSER  : in Std_logic_vector(C_M_AXI_BUSER_WIDTH - 1 downto 0);
M_AXI_BVALID : in Std_logic;
M_AXI_BREADY : out Std_logic;

M_AXI_ARID    : out Std_logic_vector(C_M_AXI_ID_WIDTH - 1 downto 0);
M_AXI_ARADDR  : out Std_logic_vector(C_M_AXI_ADDR_WIDTH - 1 downto 0);
M_AXI_ARLEN   : out Std_logic_vector(7 downto 0);
M_AXI_ARSIZE  : out Std_logic_vector(2 downto 0);
M_AXI_ARBURST : out Std_logic_vector(1 downto 0);
M_AXI_ARLOCK  : out Std_logic;
M_AXI_ARCACHE : out Std_logic_vector(3 downto 0);
M_AXI_ARPROT  : out Std_logic_vector(2 downto 0);
M_AXI_ARQOS   : out Std_logic_vector(3 downto 0);
M_AXI_ARUSER  : out Std_logic_vector(C_M_AXI_ARUSER_WIDTH - 1 downto 0);
M_AXI_ARVALID : out Std_logic;
M_AXI_ARREADY : in Std_logic;

M_AXI_RID    : in Std_logic_vector(C_M_AXI_ID_WIDTH - 1 downto 0);
M_AXI_RDATA  : in Std_logic_vector(C_M_AXI_DATA_WIDTH - 1 downto 0);
M_AXI_RRESP  : in Std_logic_vector(1 downto 0);
M_AXI_RLAST  : in Std_logic;
M_AXI_RUSER  : in Std_logic_vector(C_M_AXI_RUSER_WIDTH - 1 downto 0);
M_AXI_RVALID : in Std_logic;
M_AXI_RREADY : out Std_logic;

1.) However, my implementation requires high performance of data transfer, where the write and read of data must occur concurrently. So, I wonder that I can implement my own AXI Full protocol with the AXI Full interface. Moreover, my custom AXI Full protocol can also communicate with the other IPs that are provided by Vivado. Is it possible to implement my custom AXI Full protocol?

2.) If so, is there a rule that I must follow? And is there an example that can be shown, because I search through the Xilinx manual guide and I can't find some useful information that I need.

3.) I read from the Xilinx reference guide, and it says that the master always initiates a transaction with the slave. However, my application is the slave would finish its calculation and tells the master to read the data from it. I would like to implement this with the S_AXI_RVALID (at the slave port), whenever the result is ready the S_AXI_RVALID would always be '1', then the master can read the data from the slave (The Address Read would be abandoned because there is only one place to store the result). Would this violate the AXI rule? Or I should add another port between master and slave, where this port is the channel for the slave to initiate the "READ" of data?