So if you are sure you are way over sampled even at the reduced sample rate where you perform your delay then that should not be an issue.
It is possible to write some of the waveform into DRAM and then grab DMA it up to the host. The DRAM clock is slower than 200MHz. I don't know exactly what it is on the USRP. That doens't mean you can't read and write to the DRAM in the 200MHz loop, it just means it would not be available for writing on every clock. That is not an issue because the DRAM is 256 bits wide. If you are just capturing 1 channel (32 bits) you only have to write data every 8 clocks so you will be at about a 25MHz access rate. I've included a screen shot of the one of the DRAM code blocks I used to provide an example of how it can work.
Let me know if there are questions or issues.
What's the purpose of the host-target fifo? My data is coming from the FPGA I/O node that interfaces to the ADC.
You are right, both should be target-to-host. One assigned to the DRAM collecting input data and the other assigned to the DRAM collecting output data. You could reduce this to 1 FIFO and share but you would have to add some control logic to be able to share it. I would recommend just adding 2.
How do I cram an 8 element array into a dma fifo in one clock cycle of a single cycle timed loop? I can't wrap the dma write in a for loop. I can break the array up and write each element with it's own write (successively and after turning off arbitration) but that wont compile. I can put the DRAM to DMA write in it's own while loop but the compiler wont allow handshaking in a while loop.
In the DMA configuration on the Interfaces page you set the number of elements to write to 8 (see image below). You will still need to use the hand shaking (ready for input, etc.)
Took me a while to get it working but here it is capturing data right off the ADC. The source is an agilent E8257D signal generator with a 2 msec pulse width 5 msec PRI pulse modulation. The 10 MHz references are tied together. The VI doesn't free run. Collection is triggered by the user. This is what's on the fpga. . This is what's on the host. Here is the data from the first iteration. There is some corruption. Odd that the corruption doesn't go to zero or the max value (1) but it doesn't look that bad. But after a few iterations it starts to look like this It looks ok for 30 msec or so and then things get much worse. And they stay that way from then on. What would do this and, assuming all this goes on to the DAC, why wouldn't I see it on the spectrum and network analyzer?
Sorry this debug has been such a challenge. Perhaps once you get the DRAM working you can skip all your filtering and use it directly.
Looking at your code I see two small issues and then I see something that looks weird to me so I don't know how it is affecting what you are seeing. First off for the two small things:
I didn't see you monitoring drops on the host, we are running at such a low rate I don't see that is likely but once you have the logic corrected it would be good to verify.
So I need some help understanding the collect and reset. I assume in your loop on the host those are set to TRUE. On the FPGA are you using latching controls? Without it don't see how it would ever set reset and collect back to FALSE. Not that the code for latching on the FPGA doesn't work, I'd be concerned about the timing of everything. Would need to make sure the code comes out of reset before collect. To simplify I would remove the latching on both those controls on the FPGA (assuming that is the case) and in the host just write constants in this order:
You should be able to do them in the same property node.
Looking at the data is it hard to tell but are all the bad values similar or exact. For instance what you have shown on your second graph for I, there are a lot of bad values around 0.2, are this all the same value or close to the same value? As for you question about why you are not seeing this on the spectrum analyzer connected to the output => while we have not found the root cause of this issue yet, this appears to be isolated to the use of the DRAM and not a true indication of the real IQ values.
Can you also share you code for the edge triggered count down?
The reset and collect buttons mechanical actions are "switch until released" on the host and "switch when pressed" on the fpga. Nothing is latched. I try to make everything edge triggered. I switched I & Q and the drops counter and gate as you said, and I now monitor drops. There are a lot of drops. In the hundreds per collection. The bad values usually fluctuate in amplitude. Here is the edge triggered count down.
So obviously we are using too much of the DRAM bandwidth although I will need to dig deeper to actually find out why. One way to make things better easily is to wait to do the DRAM read/DMA until the capture to DRAM is complete. This would cut the required bandwidth in half. I've attached a VI snippet below of a quick mock up. I did not have time to compile and test it so I can't guarantee that it is not without errors. It should serve as an example. Since it is a snippet you should be able to download the PNG then drop the PNG directly on a VI and have the code (I wrote this in LabVIEW 2018 because it was what I had readily available).