5
$\begingroup$

I have a Virtex 6 FPGA running at 200MHz with ADC/DACs on it. I have been converting a WiFi signal (2462MHz) down to a more reasonable IF of 25MHz, sampling, running the signal through taps, tweaking them, and mixing back up. This all works fine.

My issue is that since I am mixing down and sampling at a lower rate, I cannot implement RF level multipath by adjusting the delay in the taps for phase changes, instead I had to adjust it at the IF level instead. This works OK, but it means that timing is off (things like TDOA or stuff with TOF measurements could care about that). It seems like the best way around this (and probably the right way) is to implement a fractional delay filter (FDF), but I am not sure the best way to do it.

It seems like I need to come up with the coefficients for the taps, but I cannot seem to glean that out of the whitepapers I've read on FDF. Any ideas?

$\endgroup$
  • $\begingroup$ The "Interpolation in Digital Modems" papers by Gardner are a good reference for polynomial-interpolation-based fractional delay lines. They are quite amenable to hardware implementation using a Farrow structure. $\endgroup$ – Jason R May 30 '13 at 19:52
8
$\begingroup$

I usually do this by creating a low pass filter that entirely passes through the signal that I want to delay. I create the LPF "manually" by creating a windowed sinc function. Something along the lines of-

filt = sinc(-80:.8:80);
filt = filt .* hamming(length(filt)).';

This gets you a filter that passes about 80% of the nyquist region (the 80% is set by the .8 increment in the sinc indexing). To get a fractional delay you simply include the fractional delay in the calculation of your filter. Adding a constant to the sinc indexing delays the filter by $\frac{constant}{increment}$ samples. For instance, in the case of the filter above, adding 0.1 would create a fractional delay of $\frac{0.1}{0.8}$ samples, or $0.125$ samples.

filt = sinc((-80:.8:80) + .1);
filt = filt .* hamming(length(filt)).';

This works because filtering is a linear operation and delaying the filter is equivalent to convolving your original LPF with a fractionally delayed delta function. Since linearity implies that the associative property holds, convolving your signal with the delayed LPF is equivalent to convolving your signal with a fractionally delayed delta function and then filtering it with the "undelayed" LPF.

Note: When creating the "undelayed" LPF you must make sure that the indices are symmetric. The easiest way to do that is to make sure the start and end points are integer multiples of your indexing increment. That is why I used +/- 80 for an increment of 0.8.

$\endgroup$
  • $\begingroup$ This sounds very reasonable. So this would give the coefficients for 201 taps, right? I guess I am confused as to how you chose .8 and +/-80 though. I understand the relationship between the two, but how did you come up with them for your example (trying to visualize what I would want for my scenario)? $\endgroup$ – toozie21 May 31 '13 at 15:37
  • $\begingroup$ I'm a doofus, I see what you were doing now. 200 taps * 0.125 samples, is 25 samples, which is my IF in this case. The .8 is set by choosing to allow 80% of the signal through, and then the .1 is chosen to get the 25MHz IF. That right? So if I wanted to have .0625 samples and still allow 80% through, I would need since((-80:.8:80)+0.05), right? Does this mean that since my sample rate is 200MHz, I can't get by with less than 200 taps (thinking ahead to implementing on the FPGA)? $\endgroup$ – toozie21 May 31 '13 at 16:40
  • $\begingroup$ The number of taps is somewhat arbitrary. With more taps you get "better" cutoff performance, but since you aren't really trying to filter out anything that doesn't really matter much, so yes, I'm sure that you could get away with fewer taps. And yes, adding 0.05 would get you a delay of .0625 samples. $\endgroup$ – Jim Clay May 31 '13 at 17:04
  • $\begingroup$ OK, thanks. I guess as I stare at it, the one thing I don't quit get is how it is implemented. Your above steps are done once to come up with the tap coefficients, right? Then how would I use that to come up with the value of the incoming signal say 1/4 of the way between samples? $\endgroup$ – toozie21 Jun 3 '13 at 17:54
  • $\begingroup$ Come up with filter coefficients that delay by 1/4 sample, and then filter the signal with that filter. $\endgroup$ – Jim Clay Jun 3 '13 at 19:09
1
$\begingroup$

The paper:

P.J. Kootsookos and R.C. Williamson, “FIR Approximation of Fractional Sample Delay Systems,” IEEE Transactions on Circuits and Systems II: Analog and Digital Signal Processing, vol. 43(3), March 1996, pp. 269-271.

might be of interest. It shows that three distinct approaches to fractional sample delay FIR filter design are all essentially equivalent. A preprint is available here.

$\endgroup$
1
$\begingroup$

As mentioned, the farrow implementation is good for HW & FPGAs. If you don't have access to the IEEE paper, there is a block diagram available here:

http://www.dsptemplates.com/doc/classSPUC_1_1farrow.html

Also, spuc code at sourceforge.net should have a c++ implementation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.