Jump to content

Diving in


Recommended Posts

Hello all,

I am studying computer engineering, but I have a strong leaning towards the hardware side. I have played around with FPGAs a little in community college, and I'm diving into a more in depth course now.

Great timing too, as I am planning to use an FPGA for a (very simple) software defined radio.

For any other new users scrolling through here, my analog discovery 2 has been an invaluable tool as a portable starter scope. I'm sure I'll accumulate more gear in the future, but for now it's more than capable for what I need.

Link to comment
Share on other sites


a little bit of warning: "Genuine" SDR on FPGA is a difficulty level far beyond "enthusiast" range. When FPGA implementation comes in, you should have a clear understanding of the algorithm side. It's the wrong technology to learn SDR. Until then, use Matlab / Octave / Scilab / Python / whatever to prototype ideas.

Even if I run out of CPU horsepower and start writing optimized C code / throw in SSE intrinsics / convert to GPU-code / use grid computing / ..., it is still much more straightforward to work with than FPGA. One simple reason is that I can just write everything out in 32 bit floats, no need to touch fixed point math. Or take the slow compile cycle and lack of accessibility for internal signals. Those are actually the very same reasons why I've grown so fond of Octave over the years.


Link to comment
Share on other sites


I fully recognize that SDR is quite a deep topic, and the emphasis for this project is "very simple" lol. The FPGA will be primarily an interface between the ADC and computer, we are only receiving signals (other team is transmitting) and we are keeping it under ~5Mhz carrier which should eliminate the need for a mixer or some of the tricky analog front end. It's a very basic introduction to SDR, but more than enough to keep me busy for a bit. Matlab has been a wonderful resource for figuring things out in the earlier stages, and I'm sure it'll continue to help as my team figures out what we're doing wrong.

Link to comment
Share on other sites

Looks like you found the UART discussion in the other thread, I think I see where this is heading :)

Using the FPGA for an downconverter frontend from a direct sampling ADC is relatively straightforward: quadrature NCO, multiply the signal with sine / cosine, lowpass filter both products and send to PC as I and Q.
Note, there are fairly decent ADCs on the modern FPGAs (Artix, Spartan 7) that are capable of sampling I and Q channels in synchronized mode. Mixers are cheap - If I had to hack up something quickly, I might think about using the FPGA to generate downconverter LO signals (possibly in quadrature) for external Minicircuits ring diode mixers. Just thinking aloud...  (this is creative ham radio hacking, not something I'd expect to see in a self-respecting product implementation)


Link to comment
Share on other sites

I ran the CMOD a7 test you wrote, and got 1568ms. Great first usb test, though compiling in C# was new for me. Always the little things that trip ya up! One of the things that I don't get about creating a LO, it seems like it's very desirable to have a pure sin wave, and I'm not familiar with any good method for building a wide range high frequency generator. I have a bit of a desire to go above the project description and tack on something to allow me to look at ~100Mhz FM band, or 88.5 to satisfy my NPR needs, but the only 'good' thing I've found for LO generators are  VCO colpitts oscilators, and to make a wide range with those looks to be a bit of work. If there's an FPGA trick for making a LO I'd love to know

Link to comment
Share on other sites


There are many FPGA tricks for making LO's, depending upon the quality of what you are looking for.

  • You can use just the high bit of the phase to be your sinewave output.  Works great for low logic, poor for a quality sine wave since you get a square wave with this method instead. Even still, a one-bit sine wave also works great for building simple PLL's.
  • You can use a table lookup.  Depending on the quality you need, though, the table size can grow rapidly and exponentially.
  • You can use a CORDIC.  This will not only create the sine wave for your LO, but you can use the algorithm to apply the LO as well.  Requires no multiplies.  However, a fully pipelined implementation for a large number of bits can get quite costly.
  • You can also apply some sort of interpolation to your table lookup.  Just two multiplies, and some 128-element tables, and you can get just about all the sine wave accuracy you need.

Your choice.  Decide what you need for your problem, then go for it.  You can find a core generator that will generate any of the above algorithms to your specifications here.  Don't forget to avoid both radians and degrees, and don't get tripped up by the complexity of building an NCO (it's not hard at all--once you can generate the sine wave).


Link to comment
Share on other sites

>> it seems like it's very desirable to have a pure sin wave,

Welcome to the world of radio engineering :)
Very quick answer: Many modern receivers (e.g. take your cellphone) use a digital divider for LO generation that outputs a square LO signal.
It actually gives higher mixer gain (which is good for noise) since the "switches" in the mixer conduct 100 % of the time and improves balance issues.
The downside is, you get strong spurious responses at n times the LO frequency, which should be suppressed by filtering at the antenna side, before the mixer.

But this is one problem from a very long list that you can probably ignore for a while.

Generating a square LO is straightforward - simply use the clocking wizard to instantiate an MMCM/PLL. The chip does include LC oscillators (of which Colpitts is a textbook example) and they are digitally programmable. They can also provide 90 degree phase shifted outputs from a built-in divider.

BTW, if you downconvert the ADC signal in software: You need a _decimating_ lowpass filter. Either that, or the number of MAC operations skyrockets (calculating samples that are mostly discarded).

Link to comment
Share on other sites

... a slightly longer answer, if anybody is interested (analog mixing with square wave LO):

One way is to look at the Fourier series of the square wave  as a sum of sines at frequencies f, 3f, 5f, 7f, ... and to a lesser extent 2f, 4f, 6f from implementation imperfections. Then think of the mixer as linear multiplier, and use superposition (the distributive property of multiplication) for a*(b3+b5+b7+...) = a*b3+a*b5+a*b7+...
Hint, if anybody wants to formally go through the math, it gets much less messy with cos(x) = (exp(ix)+exp(-ix))/2 aka DeMoivre.

So you really get multiple frequency translations instead of one. What remains to be done is to manage the input signal energy at those frequencies I don't want, with a filter or narrow-band antenna.

In the digital world, you'd always use a sine wave.

Link to comment
Share on other sites

Don't forget coupling capacitors - single-ended RF signals are +/- around GND

Frequency accuracy is only as good as the reference, which will be badly (by RF standards) temperature dependent. Good enough for FM radio but any coherent demodulation will give you a hard time. A common reference clock between transmitter and receiver makes it easier

Channel grid is another possible problem. Cascading PLLs on the FPGA can improve resolution to hit a single frequency.

If you have $20 left in the budget, one of those into a clock-capable input of the FPGA gives a much better timebase, both in terms of phase noise / jitter and frequency resolution (note the voltage option letter).


This part is just off the top of my head (from the "official" Xilinx FMC card).


Link to comment
Share on other sites


This topic is now archived and is closed to further replies.

  • Create New...