There are few publications on the internet regarding analog PLL design. Digital PLL design articles are mostly from hardware perspective. Very little comprehensive material is available on "software" DPLL design. Here are some links:
Unfortunately, in many cases, whole parts of derivation are omitted and the PLL structure assumption are undocumented. Often only the closed-loop response is shown/analyzed without providing formulas for just the loop filter.
Here I'll try to do more thorough analysis of second- and third-order digital "software" PLL from the ground up. Including discretization and full formulas + plots. In all cases bilinear transform is used to for discretization:
In PLL (typically)
The following continuous-time structure is assumed:
There are no gain/proportional coefficients included, as a software phase detector can output the phase directly. Transfer function of the open-loop system is:
Closed-loop system is therefore described by:
We can identify the denominator with the standard form:
Using the bilinear transform we can discretize the closed-loop transfer function:
From this we can compute the discrete filter coefficients:
Similarly we can obtain the discrete approximation for just the loop filter:
and the filter coefficients:
Example:
samplerate = 1000 #Hz
loop_bandwidth = 50 #Hz
omega_n=2*math.pi*loop_bandwidth/samplerate # 0.31415
zeta = 1/math.sqrt(2) # 0.707
tau_1 = 1 / (omega_n * omega_n) # 10.1321
tau_2 = 2 * zeta / omega_n # 4.5016
Closed-loop discrete filter coefficients:
b = [0.19795842428558091, 0.039579165327638284, -0.15837925895794264]
a = [1.0, -1.5645039861011998, 0.6436623167564764]
Discrete loop filter coefficients:
b = [0.49363631582128226, -0.39494027181038893]
a = [1.0, -1.0]
And the final analysis results (
The loop structure is the same as before. The only difference is second-order loop filter:
Open-loop transfer function is:
Closed-loop system is therefore described by:
We can find formulas for the poles of the system (zeros of the denominator). There is one purely real pole:
and a conjugate pair of poles:
where:
Finding the design parameters
0.0 | 1.0 | 1.0 |
0.4 | 1.8 | 1.8 |
0.5 | 2 | 2 |
0.707 ( |
2.414213 | 2.414213 |
0.8 | 2.6 | 2.6 |
0.9 | 2.8 | 2.8 |
So it looks that for
Another design parameter selection scheme, offering better closed-loop response in some cases (the real pole is closer to zero), might be:
- Set
$b$ to$2.9999$ - Choose
$c$ from below table for desired$zeta$ - Multiply the desired
$\omega_{n}$ by$\alpha$
0.0 | 0.3333 | 0.5774 |
0.1 | 0.6865 | 0.589 |
0.2 | 1.0269 | 0.602 |
0.3 | 1.3533 | 0.6166 |
0.4 | 1.6643 | 0.6333 |
0.5 | 1.9581 | 0.6527 |
0.6 | 2.2322 | 0.6759 |
0.7 | 2.4831 | 0.7048 |
0.8 | 2.7053 | 0.7431 |
0.9 | 3.1927 | 1.3711 |
Now we know roughly how choose design parameters, so next step is discretization. Here is the discretized transfer function:
and the filter coefficients:
where:
Next the discrete approximation for just the loop filter:
and the loop filter coefficients:
Example:
samplerate = 1000 #Hz
loop_bandwidth = 50 #Hz
omega_n=2*math.pi*loop_bandwidth/samplerate # 0.31415
zeta = 1/math.sqrt(2) # 0.707
b = 1 + 2 * zeta # 2.4142
c = b
Here is a pole-zero map in s-plane:
Closed-loop discrete filter coefficients:
b = [0.30683977743424357, -0.21351282207666347, -0.2960936186119176, 0.2242589808989895]
a = [1.0, -2.2929934897739326, 1.7833870490853516, -0.4689012416667669]
Discrete loop filter coefficients:
b = [0.8853357923467264, -1.501391980009482, 0.6470624643430553]
a = [1.0, -2.0, 1.0]
Here is a pole-zero map in z-plane:
Simulations show that values chosen for
Here are also results for
Zooming into the PLL simulation output shows that 3rd-order PLL can track frequency changes - there is no lag in presence of constant input frequency change - and the lock is achieved sooner: