Jump to content

Handling Synchronisation Between FPGA and Host without deterministic host loops


AlexA

Recommended Posts

Ok, I couldn't figure out the best way to synthesise my problem down for a title but that will have to do. I'm trying to send information around between the target FPGA and a windows host machine. The problem is that, because the information coming from the FPGA is from a single-cycle timed loop, and the windows host code is slow and not deterministic, I can't rely on polling a "data ready" type indicator to begin the transfer without latching said indicator. If I latch it, I don't know how to unlatch it so it's not a one off event.

Does anyone have any good advice for this sort of problem?

Link to comment

There shouldn't be a problem using a front panel control. The FPGA sets the control to TRUE when data is available. The Windows side sees the TRUE, reads data (for example, from a numeric control), then sets the same data ready control to FALSE. When the FPGA sees that the data ready control is FALSE, it loads a new value into the numeric control and sets the data ready control to TRUE. This works fine, I've used this technique repeatedly (for example, to load a sequence of values from the host into an FPGA memory block). Perhaps the key piece you're missing is that "control" and "indicator" are essentially identical in terms of FPGA interaction - either side (Windows/FPGA) can set and read either one - and a local variable is acceptable (and, as far as I know, reasonably efficient) on the FPGA.

Link to comment

Yeah, DMA doesn't really work at the throughputs I'm talking about either. I'm streaming images out from the FPGA at least 52MBs/s, you can't build a DMA FIFO big enough to handle that sort of throughput due to the differences between the speeds of write in FPGA and read in windows, whatever size you build is going to fill up. Because of the non-determinism you can't reliably hit a certain number of elements in the FIFO on every read call, which makes handling the data a bitch in the host code. My skin crawls at the idea of trying to rely on a-priori knowledge about the different data rates to get the read quantities right given how variable windows is.

The best I've come up with is to use the onboard DRAM to handle high-speed writes then read it out at a later point at a much more sedate rate, hence the hand shaking.

Edited by AlexA
Link to comment

For streaming data, I'm with neil. You want to do this using a DMA FIFO because you can handle large numbers of elements at a time very quickly (much faster than with handshaking). Unless your data rate is horribly variable, between the Timeout and Number Elements you should be able to read consistent blocks on the Windows side. Note, also, that are two different sizes for the FIFO - one on the FPGA, the other on the host. The host can have a much larger buffer than the FPGA.

If for some reason it's necessary you can still use the on-board memory to store samples as they are aquired, then transfer them to the DMA FIFO in a separate loop.

Link to comment

How exactly does the different buffer size thing work? If I'm writing data into the DMA FIFO in the FPGA and it's got x elements, but those elements fill up before I can get a read command off, how does having a bigger buffer on the host side help? I would love to use DMA, but in my experience I can't balance the read commands accurately. Either I call for too many elements and get a "read could not be processed in the specified time out" or I don't call for enough and the buffer over runs, I start losing data.

Link to comment

When you write to the DMA FIFO on the FPGA, you're writing to the FPGA's memory. When you read from the DMA FIFO in Windows, you're reading from the host machine's RAM. Behind the scenes the DMA engine waits until the FPGA memory fills to a certain point, then quietly moves all that data into host memory, with no involvement from the host CPU nor the FPGA. Because the host can have a larger buffer than the FPGA, many of these transfers can occur between calls to read the FIFO on the host. You use the Configure method of an FPGA Invoke Node to set the FIFO depth on the host.

If you're trying to read from the FIFO too fast and the read is timing out, there's no particular downside to either waiting longer, or ignoring the timeout and restarting the read.

Link to comment

Interesting, I was having a lot of problems with DMA write time outs and buffer over-runs, you're saying a lot of it could be solved by simply making my host buffer larger? What proportion of the DMA FIFO fills up before the engine writes the data to ram? Is there anyway to control this?

Link to comment

Without seeing your code, yes, my best guess is that with a large enough buffer you can get this to work reliably at high transfer rates. I haven't seen any information about the details of the DMA engine and I don't know of any way to control it; you'll just have to trust or test that it works. You could try posting on the NI forum and see if someone with knowledge of the internals can give you an exact answer.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.