VerilogA學習 - VCO demo 合集
代碼片來源於The Designer’s Guide網站(https://designers-guide.org),主要包括了1. 輸出爲正弦波、不含jitter 2. 輸出爲方波,不含jitter 3. 輸出爲方波,jitter類型是 white accumulating jitter 4. 差分正交VCO,輸出爲方波,jitter類型是 white accumulating jitter
另外,該網站還有許多其他的VerilogA代碼demo可以參考,安利一波~
具體代碼如下,很好用~
// Voltage controlled oscillators
//
// Version 2, 2 April 2019
//
// Ken Kundert
//
// Downloaded from The Designer's Guide (www.designers-guide.org).
// Post any questions to www.designers-guide.org/Forum
`include "disciplines.vams"
`include "constants.vams"
//
// Voltage controlled oscillator
// output is sinusoidal with no jitter
//
module vco0 (out, in);
input in; voltage in; // input terminal
output out; voltage out; // output terminal
parameter real vmin=0; // input voltage that corresponds to minimum output frequency
parameter real vmax=vmin+1 from (vmin:inf); // input voltage that corresponds to maximum output frequency
parameter real fmin=1 from (0:inf); // minimum output frequency
parameter real fmax=2*fmin from (fmin:inf); // maximum output frequency
parameter real va=1; // amplitude
real freq, phase;
integer n;
analog begin
// compute the freq from the input voltage
freq = (V(in) - vmin)*(fmax - fmin) / (vmax - vmin) + fmin;
// bound the frequency (this is optional)
if (freq > fmax) freq = fmax;
if (freq < fmin) freq = fmin;
// bound the time step to assure no cycles are skipped
$bound_step(0.2/freq);
// phase is the integral of the freq modulo 2 pi
phase = 2*`M_PI*idtmod(freq, 0.0, 1.0, -0.5);
V(out) <+ va*sin(phase);
end
endmodule
//
// Voltage controlled oscillator
// output is square wave with no jitter
//
module vco1 (out, in);
input in; voltage in; // input terminal
output out; voltage out; // output terminal
parameter real vmin=0; // input voltage that corresponds to minimum output frequency
parameter real vmax=vmin+1 from (vmin:inf); // input voltage that corresponds to maximum output frequency
parameter real fmin=1 from (0:inf); // minimum output frequency
parameter real fmax=2*fmin from (fmin:inf); // maximum output frequency
parameter real vl=-1; // high output voltage
parameter real vh=1; // low output voltage
parameter real tt=0.01/fmax from (0:inf); // output transition time
parameter real ttol=1u/fmax from (0:0.1/fmax); // time tolerance
real freq, phase;
integer n;
analog begin
// compute the freq from the input voltage
freq = (V(in) - vmin)*(fmax - fmin) / (vmax - vmin) + fmin;
// bound the frequency (this is optional)
if (freq > fmax) freq = fmax;
if (freq < fmin) freq = fmin;
// bound the time step to assure no cycles are skipped
$bound_step(0.6/freq);
// phase is the integral of the freq modulo 2 pi
phase = 2*`M_PI*idtmod(freq, 0.0, 1.0, -0.5);
// identify the point where switching occurs
@(cross(phase + `M_PI/2, +1, ttol) or cross(phase - `M_PI/2, +1, ttol))
n = (phase >= -`M_PI/2) && (phase < `M_PI/2);
// generate the output
V(out) <+ transition(n ? vh : vl, 0, tt);
end
endmodule
//
// Voltage controlled oscillator
// output is square wave with white accumulating jitter
//
module vco2 (out, in);
input in; voltage in; // input terminal
output out; voltage out; // output terminal
parameter real vmin=0; // input voltage that corresponds to minimum output frequency
parameter real vmax=vmin+1 from (vmin:inf); // input voltage that corresponds to maximum output frequency
parameter real fmin=1 from (0:inf); // minimum output frequency
parameter real fmax=2*fmin from (fmin:inf); // maximum output frequency
parameter real vl=-1; // high output voltage
parameter real vh=1; // low output voltage
parameter real tt=0.01/fmax from (0:inf); // output transition time
parameter real ttol=1u/fmax from (0:0.1/fmax); // time tolerance
parameter real jitter=0 from [0:0.25/fmax); // period jitter (produces white accumulating jitter)
real freq, phase, dT;
integer n, seed;
analog begin
@(initial_step) seed = -561;
// compute the freq from the input voltage
freq = (V(in) - vmin)*(fmax - fmin) / (vmax - vmin) + fmin;
// bound the frequency (this is optional)
if (freq > fmax) freq = fmax;
if (freq < fmin) freq = fmin;
// add the phase noise
freq = freq/(1 + dT*freq);
// bound the time step to assure no cycles are skipped
$bound_step(0.6/freq);
// phase is the integral of the freq modulo 2 pi
phase = 2*`M_PI*idtmod(freq, 0.0, 1.0, -0.5);
// update jitter twice per period
// `M_SQRT2=sqrt(K), K=2 jitter updates/period
@(cross(phase + `M_PI/2, +1, ttol) or cross(phase - `M_PI/2, +1, ttol)) begin
dT = `M_SQRT2*jitter*$rdist_normal(seed,0, 1);
n = (phase >= -`M_PI/2) && (phase < `M_PI/2);
end
// generate the output
V(out) <+ transition(n ? vh : vl, 0, tt);
end
endmodule
//
// Differential quadrature voltage controlled oscillator
// output is square wave with white accumulating jitter
//
module quadVco (PIout,NIout, PQout,NQout, Pin,Nin);
input Pin, Nin; voltage Pin, Nin; // input terminals
output PIout, NIout; voltage PIout, NIout; // output terminals
output PQout, NQout; voltage PQout, NQout; // output terminals
parameter real vmin=0; // input voltage that corresponds to minimum output frequency
parameter real vmax=vmin+1 from (vmin:inf); // input voltage that corresponds to maximum output frequency
parameter real fmin=1 from (0:inf); // minimum output frequency
parameter real fmax=2*fmin from (fmin:inf); // maximum output frequency
parameter real vl=-1; // high output voltage
parameter real vh=1; // low output voltage
parameter real tt=0.01/fmax from (0:inf); // output transition time
parameter real ttol=1u/fmax from (0:0.1/fmax); // time tolerance
parameter real jitter=0 from [0:0.25/fmax); // period jitter (produces white accumulating jitter)
real freq, phase, dT;
integer i, q, seed;
analog begin
@(initial_step) seed = 133;
// compute the freq from the input voltage
freq = (V(Pin,Nin) - vmin) * (fmax - fmin) / (vmax - vmin) + fmin;
// bound the frequency (this is optional)
if (freq > fmax) freq = fmax;
if (freq < fmin) freq = fmin;
// add the phase noise
freq = freq/(1 + dT*freq);
// bound the time step to assure no cycles are skipped
$bound_step(0.6/freq);
// phase is the integral of the freq modulo 2 pi
phase = 2*`M_PI*idtmod(freq, 0.0, 1.0, -0.5);
// update jitter where phase crosses p/2
// 2=sqrt(K), K=4 jitter updates per period
@(cross(phase - 3*`M_PI/4, +1, ttol) or cross(phase - `M_PI/4, +1, ttol) or
cross(phase + `M_PI/4, +1, ttol) or cross(phase + 3*`M_PI/4, +1, ttol)) begin
dT = 2*jitter*$rdist_normal(seed,0,1);
i = (phase >= -3*`M_PI/4) && (phase < `M_PI/4);
q = (phase >= -`M_PI/4) && (phase < 3*`M_PI/4);
end
// generate the I and Q outputs
V(PIout) <+ transition(i ? vh : vl, 0, tt);
V(NIout) <+ transition(i ? vl : vh, 0, tt);
V(PQout) <+ transition(q ? vh : vl, 0, tt);
V(NQout) <+ transition(q ? vl : vh, 0, tt);
end
endmodule