[ << Controlling FPGA Registers | ^ Top ^ | Digital Up Converter >> ]

Digital Down Converter Questions

  • In the FPGA DDC, are I and Q samples being generated from complex samples? The adc_interface module just seems to multiplex the same complex sample to 2 lines?

The ADC interface module takes care of demuxing the received signal into I and Q signals. Then every pair of IQ is routed to a DDC.

  • What is the purpose of multiplexer in the FPGA receive path?

The MUX is like a router or a circuit switcher. It determines which ADC (or constant zero) is connected to each DDC input. There are 4 DDCs. Each has two inputs. We can control the MUX using usrp.set_mux() method in Python.

The Mux value is calculated by:

     3                   2                   1
   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
  +-------+-------+-------+-------+-------+-------+-------+-------+
  |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
  +-------+-------+-------+-------+-------+-------+-------+-------+

Each 4-bit I field is either ADC 0,1,2,3 Each 4-bit Q field is either ADC 0,1,2,3 or 0xf (input is const zero) All FPGA DDC Q's must be 0xf or none of them may be 0xf. We tell each input DDC input (I0, Q0, I1 ... I3, Q3) which ADC is connected to it by using 4 bits (0, 1, 2, 3 or 0xf). So a 32-bit integer would be enough for all 8 inputs to know which ADC is connected. Of course an integer in hexadecimal system will be more convenient if we want to use the set_mux() method. For most real sampling applications, the Q input of each DDC is constant zero. So quite often we don't need to modify the standard configuration of the FPGA. Actually it is anticipated that the majority of USRP users will never need to use anything other than the standard FPGA configuration.

  • I want to insert a filter FIR pass band after the output of ADC and before the input of DDC. What's the sampling frequency for this filter FIR? Is correct to insert this filter?

The sample rate of the ADC is 64Msps. The samples then go through the CORDIC to generate complex pairs, then through a CIC with minimum decimation of 4, and then through a halfband 2:1 decimating filter. The lack of hardware multipliers inside the FPGA requires you to run a relatively simple filter unless you are running at "low" sample rates which allow you to serialize the data going through one or two multipliers and accumulate the output.

  • How the FPGA halfband filter implemented, and why we cannot decimate by less than 8 in standard FPGA configuration?

It has 31 taps. The current implementation of the halfband filter in the FPGA requires 8 clocks to process the 31 taps. See the comments about timing in fpga/sdr_lib/hb/halfband_decim.v.

This works fine with decimation 8 or higher. To run at decimation 4, you'll need to use a build of the FPGA that does not contain the halfband filter, or you'll need to re-implement the halfband, such that it uses two multipliers instead of one. In addition to the standard 2 Rx (with halfband) 2 Tx build, the *current* code contains an FPGA image with 4 RX paths (without the halfband) and with 0 transmit paths. It's not installed by default.

  • ADC samples at 64MHz, and passes through both I and Q channels over the 24-bit RX bus. Internal to the FPGA, the CIC automatically decimates by a value of at least 4. The halfband decimating FIR filter internal to the FPGA decimates by a fixed value of 2. This gives a minimum decimation rate of 8, leaving 8Msps going over the USB of the USRP. Is this correct?

Yes. Note that some FPGA builds don't contain the half-band. With 16-bit I & Q decim = 8 -> 8MS/sec -> 32MB/sec. With 8-bit I & Q decim = 4 -> 16MS/sec -> 32MB/sec

  • Is there any other way to decrease the sample rate beside the USRP decim_rate?

The decim_rate sets how much decimation is done in the FPGA. You can of course perform additional decimation in software. You'd probably want to use gr.fir_filter_ccf for that job. The first argument is the decimation rate. Note: To use 4 channels, you must use the std_4rx_0tx.rbf FPGA image. If you use the std_4rx_0tx.rbf image, the decimation rate must be <= 128. If you need more decimation, you must do it in software.

  • Are odd decimation numbers ok? Can I use a decimation of 125?

With the std_4rx_0tx.rbf image, I believe odd numbers will work. They will not work with std_2rxhb_2tx.rbf

  • I wonder how to calculate the frequency resolution of the USRP CORDIC algorithm?

This paper is really good for understanding the CORDIC: CORDIC Algorithm

It is specifically written to look at FPGA implementations, which is nice. As I understand it, the USRP uses the CORDIC as described in section 3.1 of that paper. A phase accumulator is used to spin the angle around, and the modulated sin/cos or xi is the output on xo and yo after 12 iterations of the algorithm. The value of zo should be zero, and any error leftover should be represented on that output. The resolution should really be how slowly you can spin the zi component while maintaining accuracy out of the CORDIC. It may be that with 12 iterations and 16-bit inputs 0.01 Hz is possible, whereas more iterations or larger inputs might get better resolution, but I suspect you're really past the point of diminishing returns at that point.

The "phase generator" part of the CORDIC block works by incrementing a 32-bit phase register by a fixed amount per clock cycle. The full size of the register represents 2*PI() of phase, or one cycle of the waveform. The user programmed phase increment per clock cycle then represents frequency.

In the receive chain of the FPGA, the phase generator is clocked at 64 MHz. Thus, the minimum delta-frequency (a one bit change in the phase increment register) is 64 MHz / pow(2, 32) = 0.0149 Hz.

Thus, for DC, the phase increment value is zero, for 0.0149 Hz, it is 1, for 0.0298 Hz, it is 2, all the way up to 32 MHz, where it is pow(2, 31). You can also tune negative frequencies, where -1 creates -0.0149Hz, etc.

The CORDIC block then uses the resulting "sawtooth" phase value to rotate the incoming signal by that amount, resulting in complex frequency conversion. The FPGA CORDIC deals with phase and not frequency, so there is no concept of frequency resolution for it. The one being used in the USRP has 14 bits of PHASE resolution. Frequency resolution is controlled by the NCO, or phase accumulator. In our case it has 32 bits of resolution. 64 MHz/232 is your frequency resolution in Hz.

  • If we want a decimation of 64, what is the response of the CIC filter (decimation by 32), HBF (decimation by 2) and the cascaded CIC+HBF (total decimation 64) in the DDC?

For decimation 32, the response of the CIC (4 stages) frequency response from 0 to 2MHz is shown below:

http://img505.imageshack.us/img505/7776/usrpcicdecimation32jq8.jpg
The HBF frequency response is shown below (normalized frequency):

http://img180.imageshack.us/img180/8118/HBF.jpg


The cascaded response (CIC + HBF) is shown below (normalized frequency): http://img180.imageshack.us/img180/488/CICHBF.jpg

[ << Controlling FPGA Registers | ^ Top ^ | Digital Up Converter >> ]