A Voltage Controlled Oscillator

Verilog-A may be used to create signal sources. Here we show how to make a voltage controlled oscillator.

'include "disciplines.vams"
'include "constants.vams"

module vco(in, out) ;

parameter real  amplitude = 1.0,
centre_frequency = 1K,
gain = 1K ;

parameter integer steps_per_cycle=20 ;

localparam real omegac = 2.0 * 'M_PI * centre_frequency,
omega_gain = 2.0 * 'M_PI * gain ;

electrical in, out ;

begin : main

real vin, instantaneousFreq ;

vin = V(in) ;
V(out) <+ amplitude*sin(idt(vin*omega_gain+omegac,0.0)) ;

// Use $bound_step system task to limit time step
// This is to ensure that sine wave is rendered with
// adequate detail.
instantaneousFreq = centre_frequency + gain * vin ;
$bound_step (1.0 / instantaneousFreq / steps_per_cycle) ;

This can be found in Examples/Manual/Vco

This model uses the idt analog operator to integrate frequency to obtain phase. The frequency is calculated from omegac which is the constant term and vin*omega_gain which the voltage controlled term.

A problem with sinusoidal signals is that in order to obtain adequate resolution, the time step must be limited to a controlled fraction of the cycle time. In the above the parameter steps_per_cycle is used to define a minimum number of steps per cycle. This is implemented using the $bound_step system task. This tells the simulator the maximum time step it can use for the next time point. It can use a smaller step if needed but must not use a larger step.

The above can suffer a problem if left to run for a very large number of cycles. The return value from the idt operator increases continuously and eventually the size of this value will impact on the calculation precision available leading to inaccuracy. The problem can be resolved using the idtmod operator. However, this language feature has not yet been implemented in the SIMetrix Verilog-A. We expect to offer this in a later release.