CDR_BangBangPLLCDR_LoopFilter : A digital loop filter for bang-bang PLL-based CDR
A digital loop filter for a band-bang PLL-based CDR processes the digital timing error information provided by the bang-bang phase detector and updates the digital code fed to the digitally-controlled oscillator.
This digital loop filter model describes a digital controller with a proportional gain and an integral gain, set by the parameters Kp
and Ki
, respectively. That is, the output out
is computed as a sum of the current net input (up
–dn
) scaled by the proportional gain Kp
and the accumulated sum of all the past net inputs scaled by the integral gain Ki
, as expressed in the below equation:
out[n+Nd] = Kp*(up[n]-dn[n]) + Ki*sum_(j=1...n)(up[j]-dn[j])
The parameter Nd
defines the delay of the loop filter in clock cycles and the parameter init_value
sets the initial value of the internal accumulator, determining the initial value of the loop filter output.
Note that this model describes only the most basic functionality of the digital loop filter and is suitable only for behavioral simulations. A more practical implementation may include timing synchronization, decimation, and ways to reduce effective latency of the loop filter. Furthermore, it is desirable to model such a digital controller in synthesizable Verilog, so that it can be synthesized into gate-level netlists once its functionality is verified.
module CDR_BangBangPLLCDR_LoopFilter #( parameter init_value = 14'b10000000000000, // initial output value parameter Kp = 256, // proportional gain parameter Ki = 1, // integral gain parameter Nd = 4 // loop filter delay )( output reg [13:0] out, // output signal input bit clk, // triggering clock input bit up, // up signal from pd/pfd input bit dn // down signal from pd/pfd ); // variables reg [13:0] out_d [Nd-1:0]; reg [13:0] acc; reg [13:0] out_p; int i; // initialize out initial begin for (i=0; i<Nd; i++) begin out_d[i] = init_value; end acc = init_value; end always @(posedge clk) begin acc = acc + Ki*(up - dn); end always @(acc or up or dn) begin out_p = Kp*(up - dn) + acc; end assign out = out_d[Nd-1]; always @(posedge clk) begin for (i=Nd-1; i>0; i--) out_d[i] = out_d[i-1]; out_d[0] = out_p; end endmodule
Input/Output Terminals
Name | I/O | Type | Description |
out[13:0] | output | reg | output signal |
clk | input | bit | triggering clock |
up | input | bit | up signal from pd/pfd |
dn | input | bit | down signal from pd/pfd |
Parameters
Name | Type | Default | Description |
init_value | integer | 14’b10000000000000 | initial output value |
Kp | integer | 256 | proportional gain |
Ki | integer | 1 | integral gain |
Nd | integer | 4 | loop filter delay |