Phase-locked Loop

In this example, a Phase-locked loop is described. The PLL comprises three blocks each of which is implemented with a single Verilog-A module. The three modules are then interconnected using the hierarchical structures feature of Verilog-A

Hierarchical structures provide a means of interconnecting Verilog-A modules or SIMetrix primitives within a Verilog-A module. This makes it possible to construct higher level modules to implement a subsystem or even a complete circuit.

In this topic:

Top-level Module

module pll(vin_rf, vlocal_osc, phase_detect_in, vout);

electrical vin_rf, vlocal_osc, vout_ph_det, vout, phase_detect_in;

parameter real FILTER_BANDWIDTH=130.0;
parameter real VCO_GAIN=1K;
parameter real VC_CENTRE_FREQ=2.45K;

phase_detector #(.GAIN(2))
pd (phase_detect_in, vin_rf, vout_ph_det);

vco #(.AMPLITUDE(1),.CENTRE_FREQ(VC_CENTRE_FREQ), .VCO_GAIN(VCO_GAIN) )
osc (vout, vlocal_osc);

lpf_1storder #(.BANDWIDTH(FILTER_BANDWIDTH) )
lpf (vout_ph_det, vout);

endmodule
The above instantiates three sub-modules, that is the phase detector, VCO and low-pass filter. For example in:
phase_detector #(.GAIN(2))
pd (phase_detect_in, vin_rf, vout_ph_det);

phase_detector specifies the module name.

pd is the name of the instance and is arbitary but must be unique.

The arguments to #( ) are the parameter values. So .GAIN(2) sets the GAIN parameter to 2.

phase_detect_in, vin_rf, vout_ph_det define the connections to the module.

Sub-module Definitions

// Simple first order filter
module lpf_1storder(vin, vout);

electrical vout, vin;

parameter real BANDWIDTH = 300.0;

localparam r = 1k ;
localparam c= 1.0/(2.0*'M_PI*r*BANDWIDTH);

analog begin
V(vout, vin) <+ r*I(vout, vin);
I(vout) <+ ddt(c*V(vout));
end

endmodule



// Ideal VCO
module vco(vin, vout);

electrical vin, vout;

parameter real AMPLITUDE = 1.0;
parameter real CENTRE_FREQ = 2.5k;
parameter real VCO_GAIN = 1K;

real phase;
real inst_freq;

analog begin

inst_freq = CENTRE_FREQ + VCO_GAIN * V(vin);
phase = 2.0 * 'M_PI *  idtmod( inst_freq, 0.0, 1.0);

V(vout) <+ AMPLITUDE * sin ( phase);

$bound_step (0.04 / inst_freq);
end
endmodule


// Phase detector - using multiplier
module phase_detector(vlocal_osc, vin_rf, vif);

electrical vlocal_osc, vin_rf, vif;
parameter real GAIN = 2.0;


analog begin
V(vif) <+ GAIN*V(vlocal_osc)*V(vin_rf);
end

endmodule

Hierarchical Structures

Hierarchical structures are a Verilog concept that allow interconnection of modules at different levels of hierarchy. This is essentially the same function as the netlist but defined within a Verilog-A module.

In this phase-locked loop example, all modules and the top level module interconnecting them are in the same file. However this isn't necessary and it is possible to have each Verilog-A module in its own file. In this case a .LOAD statement must be included in the netlist to load all Verilog-A module accessed in the instance statements.