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; end endmodule end end Excerpt from my output file showing frequency jump when time doesn't advance. time in second frequency in hertz 0.000034319178918823 80861192.987152904272079468 0.000034319179282800 80861192.987152904272079468 0.000034319179282800 170571276.601905435323715210 0.000034319188537857 170571276.601905435323715210 0.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; end endmodule |
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 |
The Designer's Guide Community Forum » Powered by YaBB 2.2.2! YaBB © 2000-2008. All Rights Reserved. |