06-21-2015 11:12 PM
I am finding my way with MIG for Spartan 6 and want to ask for advice.
I need to make some large read from memory device, which does not fit to read FIFO in one transfer. So I want to submit multiple read commands until whole data would get processed. My plan was to monitor cmd_empty flag of command FIFO. When it gets empty, send command for subsequent transfer. I expected, that commands get queued until previous command gets finished. I saw the reference in UG388, that empty flag mean no command queues, but there might be command in flight.
I'd like to ask for clarification. If I submit several commands back-to-back, would they be processed in sequence? May I think, that deasserted cmd_empty flag means 1+ command pending? May I treat cmd_empty asserted as "no pending command, but there is no more than one command in flight"?
Would appreciate general consideration on read throttling as well.
Thanks in advance.
06-22-2015 06:55 AM
If you are reading the data from the FIFO slower than MIG is writing it, you need to be sure you don't schedule another read command until there will be room for the new data. My experience with the S6 read interface is that it is much easier to just assert read-enable all the time and use the empty flag as a data valid (inverted) indicator. Then add a fabric-based FIFO on the output side of this to deal with your data flow requirements. Otherwise you'll find that you may need to wait not only until there are no commands in queue but also that the read data FIFO is empty before issuing the next read command. Another point is that there is a significant lag in the data count output of the MIG FIFO, enough to make it generally useless for flow control. A BRAM-based FIFO is much-better behaved, and you can also make it much deeper than a maximum read burst, allowing you to stream reads without overflowing.
06-22-2015 06:36 PM
Thank you for advice.
User logic seems to read slower, than MIG supplies data. Not accounting refresh cycles I could estimate, that x16 memory part running at 400MHz could supply 16bit*2edges*400MHz=12800Mibps. User logic is PCIe, it is running at 62.5MHz and consuming 32 bit at a time, so sink rate is 2000Mibps. So there is pretty good margin.
Meanwhile I have tried another approach. The minimum request size from user logic is 64B. I have configured MIG to have 64-bit interface. Then, with 64 words FIFO, one minimum request 64B/64b=8words will fill just small part of FIFO, namely 1/8. As larger transfer sizes are multiples of 64, I break them in sub-commands of 64B and send multiple commands. As a throttle I have tried to monitor cmd_empty and two MSbs of rd_count. This way I do issue new read subcommand when command FIFO is empty and data FIFO is less than half full.
The following graph is command schedule versus transmit time:
I think this graph is telling me that MIG has excessive throughput comparing to data consuming rate. Perhaps, I could reduce all interfaces to 32 bit, save some logic but still meet performance goal.
Ant next graph is rd_count vs time: