Start > GNU Radio > Halfband interpolator stages for FPGA transmit chain of USRP1

Halfband interpolator stages for FPGA transmit chain of USRP1


Author Dominik Auras
Type Merge of existing code of USRP2 into USRP1
State Done
Key features
  • Less distortion because of better interpolation
  • No prefiltering to reduce CIC interpolator effects required anymore
  • Shares code with USRP2, may benefit from advances in USRP2 development
  • CIC interpolators completely bypassed at highest rate
  • One transmit chain with 2 cascaded 31-tap halfband interpolator stages, followed by CIC interpolator stage
  • One receive chain with halfband decimator
Changelog 2008-04-27: Add prebuilt FPGA bitstream
2008-03-31: initial setup


See USRP and GNU Radio

Please note: All I have done was to merge the existing halfband interpolator code from the USRP2 sources into the USRP1 code base. Except for a few necessary adjustment, there was no change to USRP2 code.

See hb_interp.diff and txhb.patch for the changes. They are documented, too, in ChangeLog in the complete archive.

Now with prebuilt FPGA bitstream.

Description of FPGA transmit chain

In the new transmit chain, there are 2 halfband interpolator stages in front of the CIC interpolator stage. They are copies of hb_interp.v from USRP2, which implements a 31-tap halfband interpolator. The input and output precision is 18 bit, the accumulator width 24 bit. The 16 bit input to the transmit chain is multiplied with 4 to extend to 18 bit. The 18 bit output is rounded to give 16 bit results. The gain of the cascaded interpolators is approximately 4, which is compensated for by the final rounding. If the FPGA interpolator rate equals 4x, then the CIC interpolators are bypassed.

The strobe generator has been moved into the tx chain, as is in USRP2, because we need a faster strobe. The strobe signal is output to the tx buffer. Hence, the interpolator_strobe output and the corresponding generator are removed from master control module. So there cannot be two transmit chains.
Some of the useful features the Xilinx FPGA of the USRP2 provides have to be built with logic cells for the Altera FPGA of USRP1. Because we have no embedded multipliers, the 18 bit multipliers are fitted in logic cells. The model for the addressable shift register is directly implemented in logic, too.

Resource usage is about 96% if one transmit and one receive chain are enabled, each of them with halfband filters. Accordingly there is no space left on FPGA for another chain. Timing constraints are met, of course.

The available bitstream has been built from sources with Altera Quartus 8.1 WebEdition. Place it in /usr/local/share/usrp/rev4 and specify fpga_filename="..." as constructor argument of your usrp sink. You can also place the RBF in a local project directory and give the full path as constructor argument.
I have tested the bitstream on several USRP1s. They work fine, however, there is no warranty etc. at all. GPL applies.

I have a Matlab simulation code that precisely models the whole USRP transmit chain, from the C++ usrp sink to the output of FPGA to the AD chip. Using this bitaccurate model, I have correctly precomputed the output of the chain for several standard test inputs (e.g. sine wave, dirac, rect) and verified that the Icarus verilog simulation is generating exactly identical sample values. Hence, the TX chain is to be considered verified.

Note: Too high an amplitude will significantly decrease your SNR. Good values depend on your setup, but should be in the range of 1000-10000. I have good experience with RMS amplitude of 4000.


This work is licensed under the terms of the GPL. A copy is included in the module archive.

I am not the author of the usrp code. See files AUTHORS and ChangeLog for more info. My changes are documented in the ChangeLog and in the diff-files. The new files have been copied from USRP2 code base.

The complete archive contains all relevant files from GNU Radio project related to usrp (that is the subdirectory usrp from the subversion server). The diff-archive contains only the patch file and the diff file of the changed verilog module hb_interp. Last changed revision of original directory was r8086. Existing RBF files (FPGA bitstreams) have been excluded (better get a current copy of that).


Complete Archive (RBF not included) TAR-Archive 2009-03-31 577kb
Diff-Archive TAR-Archive 2009-03-31 18kb
FPGA bitstream TAR-Archive of RBF 2009-04-27 170kb