USRP Software Radio

Showing results for 
Search instead for 
Did you mean: 

Trying to make a simple but long narrowband delay line from a usrp-2944R

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.


Basic instructions:

  • Create a typedef that is a fixed size array of 8 U32's.
  • At the project level create two DRAM blocks using that typedef as the data type.  Both will point to the same (only) DRAM bank on the USRP.  Both should use half the space (16777216 elements).
  • At the project level create two DMA FIFO's (one host-to-target and one target-to-host).  Data type is U32.  On the interfaces page, set the number of elements to read/write to 8.
  • Write code similar to the attachment.  You will need to make some tweaks.  Namely when you specify capture from the host capture exactly 16777216*8 elements and then disable write.  Once write is complete then start the request=>retrieve process.  You will cripple the DRAM's bandwidth if it is hoping around from location to location.  Much more efficient to do the write in a block, then do the upload.  Just note the image below does not follow that rule as I was doing something quick and it was in an 80MHz loop.


Let me know if there are questions or issues.



Systems Engineering - National Instruments
0 Kudos
Message 21 of 30

What's the purpose of the host-target fifo? My data is coming from the FPGA I/O node that interfaces to the ADC.

0 Kudos
Message 22 of 30

Also, DMA FIFO's don't allow custom controls.

0 Kudos
Message 23 of 30

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.

Systems Engineering - National Instruments
0 Kudos
Message 24 of 30

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.

0 Kudos
Message 25 of 30

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.)


DMA Config.PNG

Systems Engineering - National Instruments
0 Kudos
Message 26 of 30

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?

0 Kudos
Message 27 of 30



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:

  • When combining I and Q into a single U32, always make I the LSbs and not Q.  All Xilinx and NI provided IP assumes that.  If you look at your 'U32 to' on the host you will see this.
  • On your drops calculation it should be AND instead of OR.  The logic is: "if on the previous clock the node was NOT ready AND on this clock we are supplying new data, that data will be dropped".

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:

  1. Collect = FALSE (just to be sure)
  2. Reset = TRUE
  3. Reset = FALSE
  4. Collect = TRUE
  5. Collect = FALSE

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?

Systems Engineering - National Instruments
0 Kudos
Message 28 of 30

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.

0 Kudos
Message 29 of 30

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). 

Systems Engineering - National Instruments
0 Kudos
Message 30 of 30