How correctly control the Non-Sequential Strobe of axi4?

  • I used to connect a 64-bit source to a 32-bit destination on the AXI4 bus with almost the same  burst length of AXI.  in the environment.

However, here, I want to test it with multiple transactions. The master is 64 bits and the slave is 32 bits.

While randomly generating all possible combinations of AWSIZE, AWLEN, and WSTRB for testing, a transmission error was encountered.

Master:

  • awaddr[35:0] = 0x642_0860
  • awburst[1:0] = 0x1
  • awlen[7:0] = 0x3
  • awsize[2:0] = 0x1
  • wdata[63:0] = 0xefa9_d2c9_2f96_d822
  • wstrb[7:0] =  0x3 0x30 0xc0 0x0c

Slave:

  • awaddr[35:0] = 0x642_0860
  • awburst[1:0] = 0x1
  • awlen[7:0] = 0x3
  • awsize[2:0] = 0x1
  • wdata[31:0] = 0xd822  0x0  0xefa9_0000  0x0
  • wstrb[3:0]0x3     0x0   0xc          0x0

As you can see, the slave's wdata[31:0] does not correctly receive the data from the master. Specifically, the master's wdata[47:40] and wdata[39:32] are not correctly received by the slave.

I’m confused because it works when the master's wstrb[7:0] = 0xf0 or 0x0f, but when I choose different wstrb values, the slave can't receive the data. Is there a restriction rule for wstrb, or did I misunderstand? Could you guide me, please?

[update]

Through several experiments, I found that when a 64-bit Master sends data to a 32-bit slave bus, the data must always be sent in 32-bit chunks. Since the Master is 64-bit, the wstrb can be either 8'hf or 8'hf0.

If I send the 64-bit data with wstrb = 'hf0 first and then wstrb = 'hf, the slave does not receive the data correctly. However, if I send the 64-bit data with wstrb = 'hf first and then wstrb = 'hf0, the slave receives the data correctly.

I originally thought that when splitting 64-bit data into two 32-bit parts to send to the slave, as long as I match the 32-bit boundaries with any wstrb combination, it should work without issues. However, from my experiments, it seems that when sending the data, the wstrb must first send the lower 32-bit part and then the upper 32-bit part. Is this the correct behavior? Does the lower 32 bits always need to be sent before the upper 32 bits?

Can’t I first send wstrb = 8'h1001_1010 and then send wstrb = 8'h0110_0101? I'm quite confused and would like some help understanding this.

4214.Bus Issue-1.PDF

Parents
  • I think possibly the issue you are facing is a more basic one in that you are not following the rules for WSTRB and which bits can be asserted. See section A4.2.1  for a description of how the WSTRB signal, and importantly, section A4.2.2 for examples of how WSTRB can be used in "Narrow transfers" such as you are performing here.

    For any write transaction the AWADDR, AWBURST, AWLEN and AWSIZE signals define which byte lanes can be used for each transfer. AWSIZE tells you the maximum number of WSTRB bits that can be asserted for each transfer, and AWADDR tells you which AWSIZE width (and AWSIZE aligned) part of the data bus can be used for the first transfer. AWBURST then tells you how the AWSIZE width range of WSTRB bits might change for each of the AWLEN transfers in the transaction.

    So if we look at your example, the 64-bit manager is signalling a transaction starting at AWADDR=0x642_0860, and AWSIZE=0x1 (16-bit). AWLEN=0x3 (4 transfers) and AWBURST=0x1 (INCR).

    The first transfer starts at a 64-bit aligned address, so active data bus bits are WDATA[15:0] and the byte lanes that could be used are WSTRB[1:0] for the 16-bit transfer. So WSTRB[7:0] could indicate 0x03, 0x02, 0x01 or 0x00 (any combination that only uses the byte lanes described by AWADDR and AWSIZE).

    As this is an INCR burst, the next transfer uses WDATA[31:16] and WSTRB[3:2], so WSTRB can be 0x0C, 0x08, 0x04 or 0x00.

    The 3rd transfer in the transaction can use WDATA[47:32] and WSTRB[5:4], so WSTRB can be 0x30, 0x20, 0x10 or 0x00.

    And the final transfer would use WDATA[63:48] and WSTRB[7:6], so possible WSTRB values of 0xC0, 0x80, 0x40 or 0x00.

    You can only ever use WSTRB bits that are covered by the AWADDR/AWSIZE/AWBURST controls, and any other WSTRB bits must be 0 as they are not addressed by this transfer.

    So the WSTRB bit patterns you show in your example of 0x03, 0x30, 0xC0 and 0x0C are only actually legal for the first transfer, and it looks like the 64-32 bit conversion logic you have is attempting to route the relevant half of the WSTRB[7:0] bus onto WSTRB[3:0], hence seeing 0x03 for the first transfer, 0x0 for the second (because WSTRB[3:0] was 0x0 on the 64-bit side), 0xC for the third (because that is what was on WSTRB[7:4]) and 0x0 (again because that was what was on WSTRB[7:4] for the 4th transfer).

    Throughout your description of what you have been trying, the WSTRB values are mostly illegally trying to use bits not covered by the AWADDR/AWSIZE/AWBURST controls (with AWSIZE=0x1 you can only have a max of 2 bits per transfer), so please check your AXI manager implementation to see why it is generating illegal WSTRB values.

    Looking at your very last line in your question, if you wanted to drive WSTRB to 8'b1001_1010 or 8'b0110_0101, this would need AWSIZE to indicate a 64-bit transfer (as you are trying to use all 8 byte lanes - or at least byte lanes within the 64-bit aligned range of byte lanes).

Reply
  • I think possibly the issue you are facing is a more basic one in that you are not following the rules for WSTRB and which bits can be asserted. See section A4.2.1  for a description of how the WSTRB signal, and importantly, section A4.2.2 for examples of how WSTRB can be used in "Narrow transfers" such as you are performing here.

    For any write transaction the AWADDR, AWBURST, AWLEN and AWSIZE signals define which byte lanes can be used for each transfer. AWSIZE tells you the maximum number of WSTRB bits that can be asserted for each transfer, and AWADDR tells you which AWSIZE width (and AWSIZE aligned) part of the data bus can be used for the first transfer. AWBURST then tells you how the AWSIZE width range of WSTRB bits might change for each of the AWLEN transfers in the transaction.

    So if we look at your example, the 64-bit manager is signalling a transaction starting at AWADDR=0x642_0860, and AWSIZE=0x1 (16-bit). AWLEN=0x3 (4 transfers) and AWBURST=0x1 (INCR).

    The first transfer starts at a 64-bit aligned address, so active data bus bits are WDATA[15:0] and the byte lanes that could be used are WSTRB[1:0] for the 16-bit transfer. So WSTRB[7:0] could indicate 0x03, 0x02, 0x01 or 0x00 (any combination that only uses the byte lanes described by AWADDR and AWSIZE).

    As this is an INCR burst, the next transfer uses WDATA[31:16] and WSTRB[3:2], so WSTRB can be 0x0C, 0x08, 0x04 or 0x00.

    The 3rd transfer in the transaction can use WDATA[47:32] and WSTRB[5:4], so WSTRB can be 0x30, 0x20, 0x10 or 0x00.

    And the final transfer would use WDATA[63:48] and WSTRB[7:6], so possible WSTRB values of 0xC0, 0x80, 0x40 or 0x00.

    You can only ever use WSTRB bits that are covered by the AWADDR/AWSIZE/AWBURST controls, and any other WSTRB bits must be 0 as they are not addressed by this transfer.

    So the WSTRB bit patterns you show in your example of 0x03, 0x30, 0xC0 and 0x0C are only actually legal for the first transfer, and it looks like the 64-32 bit conversion logic you have is attempting to route the relevant half of the WSTRB[7:0] bus onto WSTRB[3:0], hence seeing 0x03 for the first transfer, 0x0 for the second (because WSTRB[3:0] was 0x0 on the 64-bit side), 0xC for the third (because that is what was on WSTRB[7:4]) and 0x0 (again because that was what was on WSTRB[7:4] for the 4th transfer).

    Throughout your description of what you have been trying, the WSTRB values are mostly illegally trying to use bits not covered by the AWADDR/AWSIZE/AWBURST controls (with AWSIZE=0x1 you can only have a max of 2 bits per transfer), so please check your AXI manager implementation to see why it is generating illegal WSTRB values.

    Looking at your very last line in your question, if you wanted to drive WSTRB to 8'b1001_1010 or 8'b0110_0101, this would need AWSIZE to indicate a 64-bit transfer (as you are trying to use all 8 byte lanes - or at least byte lanes within the 64-bit aligned range of byte lanes).

Children