cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
m083040047
Visitor
Visitor
613 Views
Registered: ‎10-29-2019

AXi4 burst bvalid assert before aw transmission complete

Jump to solution

i create axi4 burst and write data to ddr in xilinx zcu102 board and i got some problem in AW transmission.

the B channel is assert before AW transmission complete

my AWlen is 55 and my burst wvaild ,wready and wlast in the correct way

but i dont know how to deal with is

i got wrong value in my ddr when i take it to compare

can someone help me? 

m083040047_0-1618217084904.png

 

0 Kudos
1 Solution

Accepted Solutions
dgisselq
Scholar
Scholar
401 Views
Registered: ‎05-21-2015

@m083040047 ,

Thank you!  Now we're getting somewhere.

Before I start commenting on your logic, let me first point out that Xilinx's AXI-lite (and AXI full) slave template has been broken for years.  It's known to cause designs to hang for certain usage patterns and configurations of the interconnect.  You've also copied their bugs into your myip_1_0_S00_AXI.v design.

	always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_arready <= 1'b0;
	      axi_araddr  <= 32'b0;
	    end 
	  else
	    begin    
	      if (~axi_arready && S_AXI_ARVALID)
	        begin
	          // indicates that the slave has acceped the valid read address
	          axi_arready <= 1'b1;
	          // Read address latching
	          axi_araddr  <= S_AXI_ARADDR;
	        end
	      else
	        begin
	          axi_arready <= 1'b0;
	        end
	    end 
	end       

This logic yields to some ugly AXI bugs like the one shown below where a read packet is dropped, so that you never get the acknowledgement associated with it.

axi-read-fault.png

If this ever happens, your design will hang.

Now, on to your AXI master.  The following is from a quick desk check alone, and without firing up the formal tools:

  1. Your AxVALID logic, for both AWVALID and ARVALID, doesn't wait on AxREADY before clearing.  This is a clear fault.
        always@(posedge M_AXI_ACLK)begin
            if(rst)
                en_axi_awvalid <= 1'b0;
            else
                en_axi_awvalid <= (en_axi_awvalid) ? 1'b0 : ((CWRITE_state==WRITE_DATA) && (en_axi_wcount < 1) && M_AXI_AWREADY==1);
        end
    ​
  2. Both en_axi_rcount and en_axi_wcount are similarly broken, since they check for en_axi_axvalid without also checking for M_AXI_AxREADY.
        always@(posedge M_AXI_ACLK)begin
            if(CWRITE_state==IDLE)
                en_axi_wcount <= 0;
            else if(en_axi_awvalid == 1'b1)
                en_axi_wcount <= en_axi_wcount + 1;
            else 
                en_axi_wcount <= en_axi_wcount;
        end​
  3. Looking over your Next_state and even NWRITE_state, checks for xLAST whether RLAST or WLAST should always be accompanied by a check for xREADY && xVALID.
                WRITE_DATA  :   begin
                    if(M_AXI_WLAST)                         NWRITE_state = IDLE;
                    else                                    NWRITE_state = WRITE_DATA;
                end​
  4. p_count looks like its advancing based on VALID without also checking for the associated READY signal.  Your counter will therefore get off cut if the bus ever stalls so that VALID is true but not READY.
  5. This looks like it applies to other signals as well, such as sram_addr, Write_count, write_valid_count, as well as your pre*ADDR signals.
    always @(posedge M_AXI_ACLK) begin
        write_valid_count <= (rst) ? 0 : (M_AXI_WVALID) ? write_valid_count+1 : write_valid_count;
    end​
  6. I would recommend setting "default_nettype" to none, lest some of your (mis)spellings, such as current_wirte_sram_width, get spelled correctly somewhere within your design.  (I'm assuming that was supposed to be current_write_sram_width ...)  Remember, the default Verilog behavior on coming across an undeclared identifier (i.e. a misspelled one) is to declare it on the spot.  This can lead to all kinds of problems later on.

Many of those bugs individually can explain why BVALID would show up before you are expecting it.  Which one is the actual problem is hard to say at this point.  I'd recommend fixing all of them.

Dan

View solution in original post

11 Replies
dgisselq
Scholar
Scholar
598 Views
Registered: ‎05-21-2015

@m083040047 ,

Just checking ... if your AWLEN = 55, how many WVALIDs are you sending?

Dan

m083040047
Visitor
Visitor
592 Views
Registered: ‎10-29-2019

Hi @dgisselq  

     There will be Aw_len + 1 cycle , write 56 data, each data 64 bits.

     Before i try aw_len = 55 , i had successfully on zedboard and aw_len = 15.

thanks you

0 Kudos
dgisselq
Scholar
Scholar
588 Views
Registered: ‎05-21-2015

@m083040047 ,

Have you guaranteed that your burst will not cross a 4kB boundary?  Also, have you defined the read interface signals?  'x values on the read half can impact the write half in Xilinx's interconnect.

Dan

m083040047
Visitor
Visitor
547 Views
Registered: ‎10-29-2019

@dgisselq 

I didn't cross 4KB boundary.

Could you please explain more what  read interface signals is? 

And "read half" & "write half" , Is that mean when i set Aw_len = 55 , 

between the time that wvalid is high, I can't do AR/R Channel ?

But i had already create this master ip and rvalid and wvalid high in same time and doing successfully actually.

If i misunderstand, please explain more to me, thanks you!!

0 Kudos
dgisselq
Scholar
Scholar
523 Views
Registered: ‎05-21-2015

@m083040047 ,

I'm asking because someone else on the forum recently had a problem where they left the read channel signals as x (undefined).  This broke the write signaling.  If your read channel signals are 1 or 0 (ARVALID, RREADY, etc), then this shouldn't be your problem.

Another problem someone else just had on the forum was a design that responded to WLAST without also checking WVALID.  Admittedly, this was a slave bug, but it's something to remember.  Another problem that's quite common, which I haven't seen today, is acting on something other than xVALID && xREADY, or similarly not acting on xVALID && xREADY when it is present.

Beyond this, however, I'd have to see your logic to know what's wrong with it.

Dan

m083040047
Visitor
Visitor
502 Views
Registered: ‎10-29-2019

Glad for your answer, I have repeatedly confirmed whether there are xVALID, xREADY problems,

there may be no errors in this direction at present In addition, my understanding of axi and bvalid

is whether there is any write data And the trigger will occur after the last write of the data is over

(as shown in the figure below). But bvalid pulled up early, I'm not sure if I made a mistake in his

behavior or settings.

m083040047_5-1618238472248.png

0 Kudos
dgisselq
Scholar
Scholar
488 Views
Registered: ‎05-21-2015

@m083040047 ,

I have yet to find a Xilinx IP core that will raise BVALID early.  I've been looking.  I've found a lot of other errors around, but never that one.  Intel's AXI3 slave demo does have a bug where it might raise BVALID early.  But ... if we assume the slave you are interacting with responds to AXI properly, then I'd recommend you check your logic instead.

I do think your understanding of AXI is correct.  Just to recap, ...

  • For every AWVALID && AWREADY, there should be (AWLEN+1) clock cycles of WVALID && WREADY's.
  • AWSIZE may be no larger than $clog2(C_M_AXI_DATA_WIDTH/8)
  • The last of these WVALID's should also have WLAST raised.
  • It is a protocol error to raise BVALID prior to or even concurrent with WVALID && WREADY && WLAST.

I've seen several AXI slave implementations.  Some implementations count WVALID && WREADY and ignore WLAST.  Some implementations ignore the WVALID count and just look for WLAST.  Other implementations (such as both Xilinx's and Intel's broken AXI demo slaves) will pay attention to WLAST even when WVALID isn't set.  Indeed, Intel's broken demo might generate BVALID prior to the end of the burst.  (Xilinx's broken demo will just hang.)

This is why I wanted to see your logic.  A quick formal check can often help you focus your efforts within your master module, or inform you that the bug is somewhere else in your design.  From what you've given so far, however, there's not enough information to draw any conclusions.

Dan

m083040047
Visitor
Visitor
425 Views
Registered: ‎10-29-2019

Thank you very much for your response again, I have placed my code on github, CNN is my master, and I use a slave (myip_v1_0_S00_AXI) to receive cpu messages, and a wrapper (myip_v1_0.v).
The signals of aw and w are line 360-line 370
The counter for calculating (aw_len+1) cycles is Write_count (+4 is due to some design needs, it can be used as write_count to count to (aw_len+1)*4 and I will trigger wlast.-line 559
About the signal setting of aw chennel-line 703 ~ line 711
// (AW) Channel
assign M_AXI_AWID = {C_M_AXI_ID_WIDTH{1'b0}}; //Unused
assign M_AXI_AWSIZE = 3'd3; //clogb2((C_M_AXI_DATA_WIDTH/8)-1);
assign M_AXI_AWBURST = 2'd1; //INCR Mode
assign M_AXI_AWCACHE = 4'd0; //???
assign M_AXI_AWPROT = 3'd0; //???
assign M_AXI_AWLOCK = 1'd0; //No need to lock bus
assign M_AXI_AWQOS = 4'd0; //Let QoS be default
assign M_AXI_AWUSER = {C_M_AXI_AWUSER_WIDTH{1'b0}}; //Unused

https://github.com/polachen0526/AXI?fbclid=IwAR3PG2X16biWXEWFmkkbiErwiMsSUS1qRchwaYAy1mJsGLHU5tH4KR9sAPI

Please correct me if I have any logical problems. Thank you

0 Kudos
dgisselq
Scholar
Scholar
402 Views
Registered: ‎05-21-2015

@m083040047 ,

Thank you!  Now we're getting somewhere.

Before I start commenting on your logic, let me first point out that Xilinx's AXI-lite (and AXI full) slave template has been broken for years.  It's known to cause designs to hang for certain usage patterns and configurations of the interconnect.  You've also copied their bugs into your myip_1_0_S00_AXI.v design.

	always @( posedge S_AXI_ACLK )
	begin
	  if ( S_AXI_ARESETN == 1'b0 )
	    begin
	      axi_arready <= 1'b0;
	      axi_araddr  <= 32'b0;
	    end 
	  else
	    begin    
	      if (~axi_arready && S_AXI_ARVALID)
	        begin
	          // indicates that the slave has acceped the valid read address
	          axi_arready <= 1'b1;
	          // Read address latching
	          axi_araddr  <= S_AXI_ARADDR;
	        end
	      else
	        begin
	          axi_arready <= 1'b0;
	        end
	    end 
	end       

This logic yields to some ugly AXI bugs like the one shown below where a read packet is dropped, so that you never get the acknowledgement associated with it.

axi-read-fault.png

If this ever happens, your design will hang.

Now, on to your AXI master.  The following is from a quick desk check alone, and without firing up the formal tools:

  1. Your AxVALID logic, for both AWVALID and ARVALID, doesn't wait on AxREADY before clearing.  This is a clear fault.
        always@(posedge M_AXI_ACLK)begin
            if(rst)
                en_axi_awvalid <= 1'b0;
            else
                en_axi_awvalid <= (en_axi_awvalid) ? 1'b0 : ((CWRITE_state==WRITE_DATA) && (en_axi_wcount < 1) && M_AXI_AWREADY==1);
        end
    ​
  2. Both en_axi_rcount and en_axi_wcount are similarly broken, since they check for en_axi_axvalid without also checking for M_AXI_AxREADY.
        always@(posedge M_AXI_ACLK)begin
            if(CWRITE_state==IDLE)
                en_axi_wcount <= 0;
            else if(en_axi_awvalid == 1'b1)
                en_axi_wcount <= en_axi_wcount + 1;
            else 
                en_axi_wcount <= en_axi_wcount;
        end​
  3. Looking over your Next_state and even NWRITE_state, checks for xLAST whether RLAST or WLAST should always be accompanied by a check for xREADY && xVALID.
                WRITE_DATA  :   begin
                    if(M_AXI_WLAST)                         NWRITE_state = IDLE;
                    else                                    NWRITE_state = WRITE_DATA;
                end​
  4. p_count looks like its advancing based on VALID without also checking for the associated READY signal.  Your counter will therefore get off cut if the bus ever stalls so that VALID is true but not READY.
  5. This looks like it applies to other signals as well, such as sram_addr, Write_count, write_valid_count, as well as your pre*ADDR signals.
    always @(posedge M_AXI_ACLK) begin
        write_valid_count <= (rst) ? 0 : (M_AXI_WVALID) ? write_valid_count+1 : write_valid_count;
    end​
  6. I would recommend setting "default_nettype" to none, lest some of your (mis)spellings, such as current_wirte_sram_width, get spelled correctly somewhere within your design.  (I'm assuming that was supposed to be current_write_sram_width ...)  Remember, the default Verilog behavior on coming across an undeclared identifier (i.e. a misspelled one) is to declare it on the spot.  This can lead to all kinds of problems later on.

Many of those bugs individually can explain why BVALID would show up before you are expecting it.  Which one is the actual problem is hard to say at this point.  I'd recommend fixing all of them.

Dan

View solution in original post

m083040047
Visitor
Visitor
334 Views
Registered: ‎10-29-2019

@dgisselq 

I will correct these errors and then try to see if there is any error in bvalid. Thank you very much for taking the time to help me debug. I will respond to you and my completed results in about a few days.

0 Kudos
m083040047
Visitor
Visitor
224 Views
Registered: ‎10-29-2019

Hi Dan

After fix those problems, BVALID has trigger correctly,

Every signals including "AR/R/AW/W Channel" are work same as before, maybe there has some 

combination logic error won't print on "ILA Debug" because signal less then 1 clock cycle.

Thanks your help

0 Kudos