Hello Ken,
thanks for a reply.
I'm making a simple model with a voltage pulse input and a voltage pulse with jitter output (an oscillator with jitter).
The input frequency in this case is predetermined, and it could be given as a parameter probably, but for some other reasons I chose not to have it as a parameter but to calculate it continuously throughout the simulation.
Here's the model:
Code:`include "constants.vams"
`include "disciplines.vams"
`timescale 1ps/1fs
module ClkWithJitter (out, in );
input wreal in;
output wreal out;
wire clkin_d;
reg clkout_d;
parameter real Vhi = 1.2;
parameter real Vlo = 0;
parameter real jitter = 0; // 1-sigma standard deviation period jitter value
// must be input in [ps] in reference to the `timescale / dscale updated accordingly
real Vth, random, period, dpj;
real tr1, tr2;
parameter integer dscale = 1e12; // the jitter value scale
parameter integer seednum = 10;
integer seed;
initial begin
seed = seednum;
Vth = (Vhi + Vlo)/2.0;
period = 0.001;
dpj = 0.0;
tr1 = 0;
tr2 = 0;
clkout_d = 1;
end //initial
assign clkin_d = in > Vth;
always begin
@(posedge clkin_d) tr1 = $realtime; $display("tr1 = %.3f", tr1);
@(negedge clkin_d) tr2 = $realtime; $display("tr2 = %.3f", tr2);
period = 2*(tr2 - tr1); $display("period = %.3f", period);
random = ($dist_normal(seed, 0, jitter*dscale) + 0.0)/(dscale/jitter);
dpj = random;
end //always
always begin
#((period+dpj)/2) clkout_d = ~clkout_d;
end
assign out = (period < 1) ? in : clkout_d ? Vhi : Vlo; // the first halfperiod is copied "as is" to the output
// this way correct pariod calculation is ensured
// and the first halfperiod can always be taken as a reference halfperiod
endmodule
It's not ideal in quite a few points actually.
I am using Virtuoso and AMS Designer. My testbench is a schematic view. For example, when I instantiate my model in the testbench I can't input "2ps" for jitter, but just a number. I remember being able to do that couple of years ago, so I don't know why I can't do that now, but anyway I got around it at this point...
So, in this example I am generating a random number with $dist_normal() function and sometimes the simulator complains I can't pass it a real parameter but only integers, and sometimes it doesn't complain and continue even though I have jitter defined as a real parameter.
I realized at some point when I exclude an xrun additional argument -disable_sem2009 (which is for compiling SystemVerilog and not VerilogAMS, it works ok...(systemVerilog part of this story is yet another story for itself...))
The other part that is not ideal is the whole "period" implementation I would say.
Since I am making a continuous always block with "period" as a delay parameter, then "period" has to be defined as something other than zero, and at this point it's a value that I know it won't interfere with the specification.
As well as the final assignment with that "if period < 1" line, it's because I assumed (not too rightfully) that the real calculated period will most probably always be bigger than 1ns.