2
$\begingroup$

I have an incoming digitally sampled sine wave pulse, so my FPGA has the ADC level from an I and Q channel. I want to be able to shift the phase by some arbitrary amount.

  • What's the most efficient way to do this?

The most obvious way to shift phase would be just to multiply by $e^{i\phi}$, but that would be slow and wasteful. I've also seen someone recommend using an allpass filter with some phase shift.

  • Is there any other options I should be considering? Or is the allpass filter the best way to do this?
$\endgroup$
  • $\begingroup$ Would a variable delay line be close enough? $\endgroup$ – user14819 Jul 3 '16 at 0:32
  • $\begingroup$ for example see: music.mcgill.ca/~gary/618/week1/delayline.html $\endgroup$ – user14819 Jul 3 '16 at 0:49
  • $\begingroup$ Be careful- do you really want a phase shift or a delay? A phase shift is dispersive if your signal has any bandwidth since the delay will vary with frequency. A variable delay all pass filter may be what you really need. $\endgroup$ – Dan Boschen Apr 29 '17 at 16:07
1
$\begingroup$

The allpass you're describing is a multiplication with multiple numbers. Hence, if you want to shift your phase, the only mathematically viable and easiest way is indeed a multiplication with $e^{i\phi}$.

I don't see why that would be overly slow – in a modern FPGA, you'd probably utilize DSP slices to do the (real-valued) two multiplications and additions that make up a complex $\cdot$ complex multiplication.

Now, if you need to increment your phase, so you need to *calculate the value of $e^{i\phi}$ first, then there might be room for optimization. In fact, digital tuning happens in FPGAs, in the DSP chains of software defined radio devices like the Ettus USRP series.

There, a pretty standard CORDIC algorithm was employed to approximate a complex sinusoid $e^{i2\pi f}$ of arbitrary relative frequency $f$. Have a look at the USRP X3xx's GPL-licensed RX DSP DDC chain:

cordic_z24 #(.bitwidth(cwidth))
  cordic(.clock(clk), .reset(rst), .enable(run),
     .xi(to_cordic_i),. yi(to_cordic_q), .zi(phase[31:32-zwidth]),
    .xo(i_cordic),.yo(q_cordic),.zo() );

The cordic_z24 is really just a multi-stage CORDIC implementation with pre-computed atan coefficients.

It runs at complex 64MS/s even on 2005 Spartan FPGAs, and doesn't really blink much of an eye about 200MS/s on modern Kintex7 FPGAs.

It avoids explicit multiplication alltogether.

$\endgroup$
0
$\begingroup$

I agree with most of what Marcus has said. A complex multiplication in a modern FPGA isn't too slow or inefficient if the FPGA is designed for DSP applications (and hence has DSP slices available). On the other hand, if you don't have a readily available multiply-add solution, the CORDIC algorithm as Marcus suggests is a typical way to accomplish your goal. A CORDIC block, operating in a fully pipelined implementation, will have much more latency than the complex multiplier solution, but it will require less FPGA fabric in the case that you do not have dedicated DSP slices to use. Do you require the phase to be adjusted in real-time? Both of the previous solutions can do that. Also, a tunable allpass filter could accomplish that, but keep in mind that it will require more memory and a number of multiply-add operations. So, in the end, it probably won't be much more efficient or faster than the single complex multiplication approach. One allpass filter that might be acceptable (if the sinusoid frequency is relatively slow) and would certainly be simpler would be a variable delay. If you needed a phase shift at a finer granularity than a single sample, then you could achieve this through a fractional interpolation filter. For example, look at the Farrow Structure. You would need to weigh the cost of this structure against the CORDIC and the complex multiply approaches. This is easy to do in a project where you are dealing with constraints, but it is difficult to do in a general context without more detail being provided.

$\endgroup$
  • $\begingroup$ Would CORDIC rotate the in-phase and quadrature (IQ) signal or just calculate $e^{i\phi}$, in case you would still need to complex multiply the IQ signal with that? $\endgroup$ – Olli Niemitalo Mar 30 '17 at 7:58
  • 1
    $\begingroup$ The CORDIC name encompasses a set of algorithms based on rotations that are done by multiplying by powers of 2 and adding. These rotations can be applied on their own to generate $e^{i\phi}$ for applications that don't require a multiplication. Typically, though, they are applied to the I/Q stream to perform the rotations (to a specified degree of accuracy) avoiding the need for the complex multiplication. $\endgroup$ – hops Mar 30 '17 at 15:51

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.