UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Visitor andrew.bean
Visitor
8,659 Views
Registered: ‎06-18-2015

Stall an AXI slave during a read transaction

Jump to solution

Hi,

 

Hopefully somebody will be able to give me a few pointers to solve my issue, I've been fighting with it for a few days but can't seem to get it working.

 

I'm trying to write a simple AXI4 Slave (full AXI not lite) which will respond to read requests from the GP Masters of a Zynq Core.  I have the following simple state machine which supports read transactions, including incremental bursts.  the RDATA output is set in code not included below, triggered by the mem_read signal.

 

 

always@(posedge ACLK, negedge ARESETN)
begin 

if(ARESETN == 1'b0 ) begin ARREADY <= 1'b0; RVALID <= 1'b0; RRESP <= 2'b00; RLAST <= 1'b0; RID <= 3'b000; AXI_RC_BUSY <= 1'b0; axi_fsm_read_state <= Read_Idle_0; w_tr_length <= 4'b0000; mem_raddr <= 31'h00000000; end else begin case (axi_fsm_read_state)
Read_Idle_0: begin RVALID <= 1'b0; RLAST <= 1'b0; r_tr_length <= 4'b0000; if ( (ARVALID == 1'b1) && (ARBURST == 2'b01) && ((ARSIZE == 3'b000) || (ARSIZE == 3'b001) || (ARSIZE == 3'b010) || (ARSIZE == 3'b011))) begin ARREADY <= 1'b1; AXI_RC_BUSY <= 1'b1; ARSIZE_INT <= ARSIZE; ARBURST_INT <= ARBURST; ARLEN_INT <= ARLEN; RID <= ARID; mem_raddr <= ARADDR; mem_read <= 1'b1; axi_fsm_read_state <= Read_0; end else begin axi_fsm_read_state <= Read_Idle_0; end end Read_0: begin mem_read <= 1'b0; RVALID <= 1'b1; if (r_tr_length == ARLEN_INT) begin axi_fsm_read_state <= Read_2; RLAST <= 1'b1; end else begin axi_fsm_read_state <= Read_1; RLAST <= 1'b0; end end
Read_1: begin if (RREADY == 1'b1) begin axi_fsm_read_state <= Read_0; RVALID <= 1'b0; mem_read <= 1'b1; r_tr_length <= r_tr_length+1'b1; case(ARSIZE_INT[1:0]) 2'b00: begin mem_raddr <= mem_raddr + 16'h1; end 2'b01: begin mem_raddr <= mem_raddr + 16'h2; end 2'b10: begin mem_raddr <= mem_raddr + 16'h4; end 2'b11: begin mem_raddr <= mem_raddr + 16'h8; end default : mem_raddr <= mem_raddr; endcase end end
Read_2: begin if (RREADY == 1'b1) begin RVALID <= 1'b0; ARREADY <= 1'b1; RLAST <= 1'b0; RID <= 3'b000; axi_fsm_read_state <= Read_Idle_0; end end endcase end

 

The code as included seems to work as is.  Now I want to be able to temporarily stall the slave and delay the completion of the read transaction for a few cycles introducing a delay.  For now I'm looking at just artificially stalling the slave for a few cycles but this will be replaced with implementation logic which may take a couple of cycles to run.  Looking at the AXI specs, and timing diagrams it appears that there are at least two points where the master should wait for the slave's signals before continuing:

 

  1. Once the master has provided a valid read address (ARADDR = address and ARVALID high) the master must hold these signals until the slave acknowledges the address by raising the ARREADY signal (though ARREADY can be high before the master initiates a transaction)
  2. Once the read address has been accepted, the slave keeps the RVALID signal low until the read data is ready on RDATA at which point the slave asserts RVALID and the master is able to read the data.

In the above code there is no stall for 1) as the ARREADY signal is high before the read transaction is initiated and there is no stall for 2) as RVALID is asserted in the cycle immediately following the valid address being provided.  When I try to insert a delay in either of these points (asserting ARREADY after an address request, or inserting a additional fsm state between Read_Idle0 and Read_0 the transaction appears not to complete and my control code on the ARM core hangs in the Xil_In32 command which initiates the read transaction, even if I stall for just a single cycle.

 

My question is, have I interpreted the spec and timing diagrams correctly to allow me to do this?  is there a better way to insert a delay in the slave responding to a read request?  And can anyone give me any pointers on how to implement it?

 

Thanks in advance for your comments, if anything needs clarifying, let me know.

 

Andrew

 

 

 

Tags (5)
0 Kudos
1 Solution

Accepted Solutions
Visitor andrew.bean
Visitor
16,124 Views
Registered: ‎06-18-2015

Re: Stall an AXI slave during a read transaction

Jump to solution

Hi bwiec,

 

Thanks for your message.  I think i've got it working now.  After much investigation I realised that the AXI stuff was working but I'd made a mistake in implementing my extra states in the state machine - note too self: when adding additional states to an fsm, always ensure ALL state variables have sufficient bit-widths!...

 

Thanks again

 

Andrew

0 Kudos
2 Replies
Xilinx Employee
Xilinx Employee
8,627 Views
Registered: ‎08-02-2011

Re: Stall an AXI slave during a read transaction

Jump to solution
Hi Andrew,

Your interpretation is fine. The slave can stall either the address or data cycles by deasserting arready/rvalid for as long as you want.

Can you post an updated snippet of code showing the inserted delay cycle?

Have you probed the interface with an ILA to see what's happening? If so, can you post a screenshot of it (showing all AXI signals going to the slave).
www.xilinx.com
0 Kudos
Visitor andrew.bean
Visitor
16,125 Views
Registered: ‎06-18-2015

Re: Stall an AXI slave during a read transaction

Jump to solution

Hi bwiec,

 

Thanks for your message.  I think i've got it working now.  After much investigation I realised that the AXI stuff was working but I'd made a mistake in implementing my extra states in the state machine - note too self: when adding additional states to an fsm, always ensure ALL state variables have sufficient bit-widths!...

 

Thanks again

 

Andrew

0 Kudos