04-02-2019 02:01 PM
I have a legacy design with simple fifo interface and I want to write/read data to/from it using axi4-full interface. My plan is to convert the read and write fifo interfaces into axi-s and put axi-s to axi4-full converter IP but I am still not sure which IP would be right one.
Initially I looked into AXI mm2s mapper, but it wasn't convenient because it puts the control info (address, etc) on the axi-s bus. Then, I looked into axi stream FIFO IP, but it does not seem to utilize 4KB boundary - the data write address on the axi4 side has only one address, but the software expects to see 4KB address space. Then, I looked at axi data mover, but it takes the command from axi-s side, not axi4 port.
I'm looking for a simple protocol converter which converts axi4 data to axis stream when the host writes a chunk of data to the assigned memory space. The interface needs to convert axi-s data to axi4-full and start the transaction by putting the data from the address 0 when the host requests a read on axi4-full.
Is there any IP which does it? If not, any recommendation?
I thought about designing axi4-full to axi-s converter to meet my purpose, but I was not sure how to handle the burst size, if it changes a burst after burst (and it is possible, i think). My data bus width is 256bit wide and don't want to design for all possible cases...
Thanks for your help.
04-08-2019 12:47 PM
Xilinx doesn't have an IP that does exactly what you want. Converting AXI-Stream into AXI Memory Mapped protocol is actually not a very simple thing to do. There are two that you should consider, though, as you work through your design.
The first is the AXI Stream Data FIFO. It is configurable such that you can have a full AXI slave port on the FIFO to write data to/read data from. There is also an AXI Lite interface to configure the details of the transfers to/from the stream interfaces.
The second IP to consider is AXI DMA. This is the Datamover IP with a register interface wrapped around it.
04-08-2019 03:24 PM - edited 04-08-2019 03:25 PM
You can pretty much wire the axis interfaces directly to the wdata and rdata channels. Then you just need to worry about decoding the address requests from AWADDR/ARADDR. And dont forget BRESP when the write is completed.
All Channels in AXI (4 and Streaming) have exactly the same behaviour - data is transfered when valid and ready are high.
I assume you're talking about being a slave device? therefore you'll know the burst length and address from the master. While technically, no burst should cross a 4k boundary, in reality, you're free to work how you want (for example, the Xilinx Interconnect will happily take a single burst larger than 4k - its even in the example testbench!). But it's up to the master to ensure that doesnt happen, not the slave.
04-08-2019 03:31 PM - edited 04-08-2019 03:49 PM
The AXI-MM to AXI-S is a complicated beast, much more so than it needs to be. It's very hard to use in a simple fall-though mode.
Instead, I wrote my own function to do exactly that: bridge AXI-MM to AXI-S. It's a couple of dozen lines of RTL in all. I bolt on AXI-S FIFOs and width converters to make the complete bridge to the rest of my logic.
This function is simple enough that I feel it could (and should) be a converter that Xilinx offers as part of their stream IP.
I can't share my code, but here's the general approach:
1. Understand that AXI-S is a subset of AXI-MM with the same VALID/READY handshake rules, so the R and W channels connect to Stream ports practically one-to-one.
2. You're not using AW or AR buses so you can tie AWREADY and ARREADY high (I hold them off with a 'pending' flop to prevent the host from enqueuing more than one address at a time.) Optionally you can use some of the AW address to send along TUSER or TDEST to memory-map multiple stream payloads on the same bus. This makes DMA very convenient.
3. Since you're dealing with full AXI-MM, you need to handle block transfers. Writes are easy, they're terminated by WLAST so you don't need to keep track (use this to trigger sending BRESP, too.) Reads you will need to count off the beats and terminate with RLAST when the count is exhausted, at which time you send RRESP.
4. I added a read timer to issue SLVERR if the read-to-empty condition occurs. This will generate an exception in the DMA block so you will have notification of underrun. I suppose you could do the same for overrun, or allow backpressure to regulate the writing rate.