I have created a channel model in GNU Radio (a modified version of the default GNU Radio Channel Block). Its performance under AWGN (without timing, phase or frequency offsets) aligns properly with theory (for BPSK). I'm currently evaluating the effect of carrier frequency offset on BER by means of the flowgraph below. The block "debug_bpsk_phase_recovery" is a modified version of the default GNU Radio Costas loop (provides a way of configuring the loop damping factor). The curves below were obtained by running the simulation with loop bandwidths $B_{n} = 0.1$ and 0.05 and two different data rates (250k and 500k). The frequency offset is $0.01R_{s}$.
Out of curiosity, I'm trying to find out how much frequency offset the Costas loop can handle. To my understanding, the maximum frequency offset is related to the PLL pull-in range. From theory, the PLL pull-in range is $\left( 2\pi\sqrt(2)\times \zeta\right)\times B_{n}$ (where $\zeta$ is damping factor (which I set to 1.0 for critical damping (some texts use $\sqrt(2)/2$). This evaluates to $0.88\times R_{s}$ and $0.44\times R_{s}$ for $B_{n} = 0.1$ and 0.05 respectively ($R_{s}$ is symbol rate).
However, as seen in the table below (SNR = 6dB), the loop fails to handle offsets above $0.04R_{s}$ (Bn = 0.1) and $0.03R_{s}$ (Bn = 0.05), which is much much less than theory. Any ideas of why is this happening?
As I understand (from the Mengali book), course carrier frequency (like FLL block in GNU Radio) can reduce offsets to within 10% of the symbol rate. I therefore tried to include the FLL block. This didnt help at all. As a matter of fact, the FLL introduced BER degradation even for small frequency offsets (~0.01) that the Costas loop was able handle on its own. Why does the FLL show this behavior?
The book also suggested the use of fine carrier recovery (tracking?) (clock-aided, decision-directed) before phase recovery. Any suggestion on algorithms that I could use for this are welcome.
Thanks in Advance, M.