I need your help in understanding how to simulate a timing recovery algorithm. I have already read a lot of literature and posted here the question but I have still doubts how it works.

Let me briefly explain my simulation:

  • Create a test signal:
  • BPSK, 1000 symbol with 16 samples
  • Raised cosine filter
  • Compute an amplitude and phase of each sample (CORDIC)
  • Create N ( = 1000 / (32*16)) blocks: 32 x 16
  • For each “sample” - vector (32 x 1) compute a sample with max amplitude and fix its index. Result: array 32 x N, which contains max amplitude samples (sample, called the on-time sample) and second one contains indexes.
  • Selects sample from the time-index one greater than that of the on-time sample is the late sample, and the sample from the time-index one less than that of the on-time sample is the early sample.
  • Compute an error (= late sample - early sample)
  • Depends on the error I shift one sample before or after

My questions are:

  • And after that I don’t know what my next step is?

  • What should I do with the computed error?

  • If I know the sample with max amplitude, do I need the time recovery algorithm at the receiver side?

  • How can I compensate the phase offset in this way?

  • Guys, does anyone have an example of simulation in Matlab or in C?


I would recommend the Gardner Timing Error Detector vs the CORDIC for determining timing error for use in a timing recovery loop. (The CORDIC is an algorithm of choice when we desire to trade iteration for computation of accurate phase, but the computations required for the Gardner are so minimal that this point is mute). The Gardner works with only two samples per symbol and up to very large carrier offsets up to a quarter of the symbol rate). Any given single sample from the Gardner will not be necessarily accurate (has self noise) but for use in a timing recovery loop (which provides the average over several samples) will converge to low phase error, so do not be discouraged in the accuracy of any one given sample from the Gardner or any other timing error detector for this purpose in a tracking loop.

The OP also mentions making use of the largest sample, but with observation of an eye pattern of raised cosine pulse shaped waveforms with tighter bandwidths (see Eye pattern construction and interpretation) it is clear that the largest sample is NOT at the ideal sampling location. Also I would advise on ensuring both carrier offset and timing offset is being addressed as these are two separate and independent offsets that need to be corrected in independently operating receivers.

The links below provide the implementation details of the Gardner Loop for determining the timing error from the samples with the sampling rate decimated to two samples per symbol. The error is accumulated in a loop filter (for a simple first order loop, just accumulate the error samples and multiply by the loop gain as needed for stability (due to parasitic delays it will be unstable if the gain is too high) and to adjust the loop bandwidth. A typical rule of thumb for the loop bandwidth is to use a small fraction of the symbol rate (such as 1/20th or less).

The accumulated error (which should converge to zero) controls a variable delay element: this element has nominal delay when the accumulated error is zero, and can shift the waveform forward and reverse by small incremental delays based on the accumulated error being positive or negative (in such a way to drive the error to zero). This is a simple first order delay lock loop with one integrator element (the accumulator). Depending on design requirements (dynamics and tracking requirements), this can be expanded into a 2nd order loop with an additional accumulator and direct control path (forming a Proportional-Integral Loop Filter), but this complexity won't be necessary for an initial demonstration. It would be simplest without getting into control loop theory and modelling to set up a simple demonstration with a waveform that has a static timing error and start with a very small multiplier in the accumulator (meaning multiply the error from the timing error detector by 0.01 for example and then add that result to the accumulated result) such that convergence is very slow. Then increase that multiplier to observe the increase in convergence rate. At the lower convergence rate (narrower loop BW) the self noise from the detector as well as other noise sources in the signal itself are significantly filtered, so ultimately there is a trade between desired dynamics (how fast we want to track) and noise that gets added.

To implement the variable delay element used for delay correction, interpolators are often used and polyphase filters are great for this since with that you don't actually have to increase the sampling rate. Farrow filters are another option (see https://www.dsprelated.com/showarticle/22.php). For more details on the polyphase interpolator for variable delay, see:

Emulating a Variable Delay

Fractional Delay using Polyphase Filter

How to implement Polyphase filter?

Please also see the following posts with further details of this:

Fractional spaced equalizer + timing (clock) recovery

Gardner Timing Recovery for Repeated Symbols

Isn't Gardner's algorithm and Early-Late gate the same thing?

Symbol timing synchronization using a high sampling rate

Recovering signal for psk (this last link provides an example of a carrier recovery loop but does not show timing recovery, but shows a similar loop structure of two accumulators as a PI Loop, here the second accumulator is part of the NCO).

For AGC: Role of Power Metric and LPF in AGC(Automatic Gain Controller)

  • $\begingroup$ anyway it is not clear how I can use the results of the Cordic in time recovery algorithm $\endgroup$ – Ali23 Mar 5 at 14:24
  • 2
    $\begingroup$ @Ali23 my point is to not use the CORDIC; I don't yet see how the CORDIC would be a better choice or even the right choice for this application for timing error. In any event phase error is used to determine Carrier Recovery not timing offset. (the phase of the IQ signal is the carrier phase, not a sampling offset). But even for carrier recovery (which is also important) I would use a cross product multiplier as the phase detector rather than the CORDIC, unless for some reason I didn't have the two real multipliers needed to compute the $I_1Q_2 - I_2Q_1$ result. $\endgroup$ – Dan Boschen Mar 5 at 15:43

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.