The Designer's Guide Community Forum https://designers-guide.org/forum/YaBB.pl Simulators >> Timing Simulators >> How to measure frequency in Ultrasim? https://designers-guide.org/forum/YaBB.pl?num=1159294073 Message started by ccd on Sep 26th, 2006, 11:07am

 Title: How to measure frequency in Ultrasim? Post by ccd on Sep 26th, 2006, 11:07am Hello,Does anyone know how to measure frequency of a PLL clock in Ultrasim? I created a verilogA model to do this, but I keep getting a spike in freq every so often and I know that's not real because the clock period doesn't change as abruptly as the freq spike indicates.  For debugging purpose, I dumped two columns of data: time and frequency, and it seems the frequency spike occurs when time doesn' advance with time resolution to fs. This makes sense because my frequency is calculated as 1/period, so if time doesn't advance, period gets small. Here is my verilogA model:`include "discipline.h"`include"constants.h"`define PI      3.14159265358979323846264338327950288419716939937511                                                                                                                                                                                          nature Frequency        abstol = 1m;        access = FF;        units = "Hz";endnaturemodule freq_meter(vp,vn,fout);electrical vp, vn;freq_current fout;parameter integer log_to_file = 1;                                                                                                                                                                                             integer out_file;                                                                                                                                                                                             real tlast_cross;                                                                                                                                                                                             real fout_val;                                                                                                                                                                                             analog begin                                                                                                                                                                                                @ ( initial_step ) begin         if (log_to_file ) begin             out_file = \$fopen( "%C:r.dat" );             \$fstrobe(out_file,"# Generated by Spectre from module `%M'");      @ ( cross (V(vp,vn),1,10p,20m) ) begin             fout_val = 1/(\$abstime-tlast_cross);             tlast_cross = \$abstime;      end                                                                                                                                                                                                if (log_to_file) begin         \$fstrobe(out_file, "%-.18f\t%-.18f", \$abstime, fout_val);      end                                                                                                                                                                                                FF(fout) <+ fout_val;   endendmodule                                                                                                                                                                                                   end      endExcerpt from my output file showing frequency jump when time doesn't advance.                                                                                                                                                                                          time in second                        frequency in hertz0.000034319178918823    80861192.9871529042720794680.000034319179282800    80861192.9871529042720794680.000034319179282800    170571276.6019054353237152100.000034319188537857    170571276.6019054353237152100.000034319197792913    170571276.601905435323715210        potential Frequency;        flow Current;enddiscipline

 Title: Re: How to measure frequency in Ultrasim? Post by Ken Kundert on Sep 26th, 2006, 4:52pm You compute fout_val within the @initial_step block, meaning that it is only computed at the beginning of the interval. This is probably not what you wanted to do, but it does explain why the frequency you output is largely constant.Why Ultrasim reruns the @initial_step block at that one point I cannot say, perhaps it is having convergence problems and it restarts there. Whatever the reason, it is incorrect and should be reported to Cadence as a bug.-Ken

 Title: Re: How to measure frequency in Ultrasim? Post by ccd on Sep 27th, 2006, 8:49am Sorry, the verilogA code I posted got messed up when I copied and pasted it.  Here's what it's supposed to look:module freq_meter(vp,vn,fout);electrical vp, vn;freq_current fout;parameter integer log_to_file = 1;                                                                                                                                                                                                   integer out_file;                                                                                                                                                                                                   real tlast_cross;                                                                                                                                                                                                   real fout_val;                                                                                                                                                                                                   analog begin                                                                                                                                                                                                      @ ( initial_step ) begin         if (log_to_file ) begin             out_file = \$fopen( "%C:r.dat" );             \$fstrobe(out_file,"# Generated by Spectre from module `%M'");         end      end                                                                                                                                                                                                      @ ( cross (V(vp,vn),1,10p) ) begin             fout_val = 1/(\$abstime-tlast_cross);             tlast_cross = \$abstime;      end                                                                                                                                                                                                      if (log_to_file) begin         \$fstrobe(out_file, "%-.18f\t%-.18f", \$abstime, fout_val);      end                                                                                                                                                                                                      FF(fout) <+ fout_val;   endendmodule

 Title: Re: How to measure frequency in Ultrasim? Post by Ken Kundert on Sep 27th, 2006, 10:46pm First an aside. You can get more accurate results if you use the last_crossing() function. See the "Period Measurement" model on http://www.designers-guide.org/VerilogAMS/ for an example.You print your results outside the @cross function, so you are printing the period every timestep whereas the value is only changing at the crossings. This is why the frequency only changes every once and a while. And what you call a spike is really just a step change, right? So it seems like in the end your question is why do you get some timesteps where the time does not seem to advance. Is that correct? There could be several explanations:1. it could be that the simulator is running the same time point twice, once where it does not evaluate the contents of the @cross block, and one where it does. It might do this to better resolve any discontinuities cause by the @cross.2. it could be advancing time, but by a very small amount. This is unlikely given the number of digits that you printed.3. there could be a bug in the program.My money is on 1.-Ken

 Title: Re: How to measure frequency in Ultrasim? Post by ccd on Sep 27th, 2006, 11:10pm Hi Ken,Thank you for your detailed explanation.  Yes, it seems the spikes occur when time doesn't advance, even at fs resolution. So, I believe you're right on 1. A couple of things I did before I got your response were #1 set the simulator to more conservative mode to improve accuracy and  #2 compute freq only when time advances.  I'm not sure which one actually helped. But, these two things I did seem to help eliminating these freq spikes.  From reading your post I would like to know why last_crossing() is more accurate than cross().  I haven't had a chance to read the doc you suggested yet, maybe the answer to my question is there.  :)Again, I appreciate your help.Regards,ccd

 Title: Re: How to measure frequency in Ultrasim? Post by Ken Kundert on Sep 28th, 2006, 1:23am With the tolerances you specified, cross will get within 10ps of the threshold crossing, but it is guaranteed to fire not at the threshold crossing, but just beyond the threshold crossing. So the accuracy of your model is 10ps. When you use last crossing, the crossing is still resolved within 10ps, but in addition, last_crossing estimates from their where actual crossing occurs using interpolation, so is accuracy is an order of magnitude higher.-Ken