Home
  • Products
  • Solutions
  • Support
  • Company

This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  • Products
  • Solutions
  • Support
  • Company
Community Custom IC Design ADE Assembler: automatic ADC gain error extraction

Stats

  • Locked Locked
  • Replies 11
  • Subscribers 127
  • Views 7817
  • Members are here 0
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

ADE Assembler: automatic ADC gain error extraction

NewScreenName
NewScreenName over 1 year ago

Hi all,

I am simulating a Nyquist ADC by giving a slow varying input ramp, collecting the sampled output code (and reconstructed by a verilogA model) and then plotting it versus the input signal (waveVsWave calculator function), hence getting the transfer characteristics of the ADC.

Now I would like to remove the offset and gain error, in order to take the difference between this corrected output and input, to observe the DNL.

Is there any built-in function to do that in the calculator or simple ocean script?

For the offset subtraction would be quite trivial, just subtract to the output its value at Vin=0.

But to find the gain error correction factor "gec" such that Vout*gec is the output characterstics without gain error, the proper Vin points must be chosen such that Vin(end) is the Vin corresponding to the last output code step + LSB/2 and Vin(start) corresponding to the first output code step -LSB/2.

To better explain, see example plot of an output characteristics of the ADC: the gec would be ideally calculated by [Vin(M4)-Vin(M5)]/[Vout(M4)-Vout(M5)] with reference to the markers M4,M5,M6,M7, such that Vin(M4)-Vin(M6)=LSB/2 and Vin(M4)-Vin(M7)=-LSB/2.

M5 and M4 are on the minimum and maximum ADC output code respectively, therefore the quantization error is diverging on their outer sides

Therefore finding a way to automatically extract the location of these M4 and M5 points is what I am looking for, without having to manually export data to matlab or any other program to do it manually for each corner/design parameter.

Note that depending on the corner the ADC gain error could be different, and therefore when I am sweeping a fixed range for the input voltage, in principle it is not possible to just use INTERCEPT/SLOPE functions of excel for example, because the regions where quantization noise diverges would start from different input voltages, but those functions would try to minimize the error thorugh all the input range. So such a method would require also to extract beforehand the region of the characteristics where quantization noise is within 0.5*LSB.

Any suggestion, or idea for different approaches, in case similar automatic functions are not available, would be highly appreciated.

virtuoso version ICADVM20.1

Thank you

Best regards

  • Cancel
Parents
  • ShawnLogan
    ShawnLogan over 1 year ago

    Dear NewScreenName,

    NewScreenName said:
    But to find the gain error correction factor "gec" such that Vout*gec is the output characterstics without gain error, the proper Vin points must be chosen such that Vin(end) is the Vin corresponding to the last output code step + LSB/2 and Vin(start) corresponding to the first output code step -LSB/2.

    I have an alternate approach that you might want to consider in order to compute the gain error between the output values of your A/D and the input samples.

    First of all, from my understanding of your computation of the gain error, you are not using the entire output and input characteristics to determine the gain error - you are only using the endpoints. Is that really what you want? For example, if your ADC has some non-linearity, then the average gain error you are computing will not correspond to the gain error at each output code. Would it not be better to use the entire set of output digital words to compute the average gain error? Alternately, might you not be more interested in computing the integral non-lineairity (INL)?

    In any case, to answer your question, suppose instead of plotting the output and input values against one another and attempting to locate the respective values for your "endpoint" gain calculation, suppose you consider two calculations - one using the input samples of the ramp at the time when you apply the sample pulse (i.e., your ADC clock) and the second the set of corresponding ADC output digital words converted back to an analog voltage by your verilog-A model. Hence, you have your input samples vs time (N samples) and the output samples versus time (N samples)

    The algorithm follows:

    1. Set the x-axis of your input samples and output samples to either time or the step number (1,,,N).

    2. Compute the best line fit to each data characteristic separately to form the sets of slopes and intercepts of (slope_in,intercept_in) and (slope_out,intercept_out).

    3. Compute the average gain error as (slope_out)/(slope_in).

    Figure 1 details an example computation for a 4 bit ADC and shows how the gain error the algorithm produces normalizes the output (ADC outputs) to the range of the input sample. I included the Microsoft Excel workbook with the example should you want to experiment with a set of values from your simulation.

    To automate this in Cadence, you may use the function written by Mr. Andrew Beckett abBestFit() or simply his function abBestFitCoeffs().  The later can be used to find the slopes of your two data sets. The function is available by searching the Forums, or a version is in the Forum post discussing a similar question to yours at:

    https://community.cadence.com/cadence_technology_forums/f/mixed-signal-design/38553/straight-line-best-fit-using-viva-calculator/1355129#1355129

    I hope I understood your need and this alternative simplifies your problem.

    Shawn

    Figure 1

    gain_error_computation_example_newscreenname_102523.xlsx

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • NewScreenName
    NewScreenName over 1 year ago in reply to ShawnLogan

    Dear ShawnLogan,

    Thank you very much for your reply, which has been definitely useful so far, and sorry for coming back so late, I missed the notification about having a reply on the forum! Some further points:

    ShawnLogan said:
    First of all, from my understanding of your computation of the gain error, you are not using the entire output and input characteristics to determine the gain error - you are only using the endpoints. Is that really what you want? For example, if your ADC has some non-linearity, then the average gain error you are computing will not correspond to the gain error at each output code. Would it not be better to use the entire set of output digital words to compute the average gain error? Alternately, might you not be more interested in computing the integral non-lineairity (INL)?

    As you say indeed, I should use the whole set of outputs, but I just showed a portion to avoid waiting the end of the simulation before I could write my post here.

    ShawnLogan said:
    Alternately, might you not be more interested in computing the integral non-lineairity (INL)?

    This is exactly what I aim to compute. As far as I know the way to do that is subtracting the offset and apply the gain error correction. After that the maximum absolute difference between my input and output will be my INL, isn't it?

    Am I missing some faster/simpler way to do this? As far as I know there is no built-in function in the calculator to do this (hence why I asked for an automated way to find the coefficients, from which I could build the set of output with offset and gain correction, from there it's trivial to build the corrected set of output and subtract it to the input to obtain INL).

    ShawnLogan said:
    The algorithm follows:

    This procedure does indeed what I wanted to do, my goal was though, to actually automate the process (suppose I have several corners and/or design points, it might get time consuming and tedious to repeat this for each of them, maybe multiple times, keeping everything in cadence would allow me to get a ready-made result at the end of each simulation)

    ShawnLogan said:
    To automate this in Cadence, you may use the function written by Mr. Andrew Beckett abBestFit() or simply his function abBestFitCoeffs()

    This is exactly something I was looking for, unfortunately only abBestFit() seems to work fine, while abBestFitCoeffs() on the same waveform (output data set) returns error:

    However I suppose this question should be addressed in the original post where this function is discussed, in the meantime I can extract those coefficients by looking at the intercept and slope of the waveform returned by abBestFit().

    What would be missing is a way to automatically detect when the output stops being saturated at x1 (about 600ns in my example picture below) and starts again being saturated at x2, such that I could properly apply the fit as abBestFit(clip(output x1 x2)). Is there any built-in function or way to extract x1 and x2?

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 1 year ago in reply to NewScreenName
    NewScreenName said:

    This is exactly something I was looking for, unfortunately only abBestFit() seems to work fine, while abBestFitCoeffs() on the same waveform (output data set) returns error:

    However I suppose this question should be addressed in the original post where this function is discussed, in the meantime I can extract those coefficients by looking at the intercept and slope of the waveform returned by abBestFit().

    Something strange was going on with the forum post yesterday - the fact that you had posts in moderation was preventing me from replying (I had our IT look into it). The reason for going into moderation was (probably) having several quoted sections - it triggers the "repeated text" check for spam (sorry!).

    Anyway, your expression here is wrong - you can't take the best fit coefficients of the result of abBestFit - it should be directly using abBestFitCoeffs(sample(...)) not abBestFitCoeffs(abBestFit(sample(...))) . That said, this function is not designed to handle family data, so it may not be very useful in ADE - it returns a list of the coefficients for a single waveform only.

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 1 year ago in reply to NewScreenName
    NewScreenName said:

    This is exactly something I was looking for, unfortunately only abBestFit() seems to work fine, while abBestFitCoeffs() on the same waveform (output data set) returns error:

    However I suppose this question should be addressed in the original post where this function is discussed, in the meantime I can extract those coefficients by looking at the intercept and slope of the waveform returned by abBestFit().

    Something strange was going on with the forum post yesterday - the fact that you had posts in moderation was preventing me from replying (I had our IT look into it). The reason for going into moderation was (probably) having several quoted sections - it triggers the "repeated text" check for spam (sorry!).

    Anyway, your expression here is wrong - you can't take the best fit coefficients of the result of abBestFit - it should be directly using abBestFitCoeffs(sample(...)) not abBestFitCoeffs(abBestFit(sample(...))) . That said, this function is not designed to handle family data, so it may not be very useful in ADE - it returns a list of the coefficients for a single waveform only.

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
Children
  • NewScreenName
    NewScreenName over 1 year ago in reply to Andrew Beckett

    Thank you for following up my question.

    I have tried to incorporate abBestFit() in an ocean script to get it calculate the slope and offset with teh following code:

    digout = clip(output x1 x2 ?interpolate nil )

    Vin= clip(input x1 x2 ?interpolate nil )

    uncorrected_Output_Characteristics = waveVsWave(?x Vin?y digout)

    fit_Output_Characteristics = abBestFit(uncorrected_Output_Characteristics)

    ADC_gain = value(deriv(fit_Output_Characteristics ) 0)

    ADC_offset = value(fit_Output_Characteristics 0)

    where x1 and x2 are such that they ensure to remove saturated areas from the waveform being fitted.

    I get the error in the exprOutputs log: *Error* eval: undefined function - abBestFit despite having made sure to load the script before running the simulation (and the script does work if I use the same command abBestFit(uncorrected_Output_Characteristics ) from the calculator instead  (uncorrected_Output_Characteristics  is an output of the ocean script).

    Am I missing some steps to allow ocean script to access abBestFit() a part from doing load("path/abBestFit.ils") from CIW before I run the simulation?

    Andrew Beckett said:
    That said, this function is not designed to handle family data, so it may not be very useful in ADE - it returns a list of the coefficients for a single waveform only.

    Regarding this, once I use it the way I do, so defined in an ocean script, doesn't each simulation point run the function on a single waveform (rather than a family of waveforms)? Or should I still expect issues when used this way?

    Otherwise any better method to automate this sort of measurement? Getting this fitting line working on the simulation output would be the only obstacle actually

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • ShawnLogan
    ShawnLogan over 1 year ago in reply to NewScreenName

    Dear NewScreenName,

    NewScreenName said:
    Am I missing some steps to allow ocean script to access abBestFit() a part from doing load("path/abBestFit.ils") from CIW before I run the simulation?

    At the beginning of all my ocean scripts, I load the functions I need for the script. As an example, the initial lines for a script looks like this:

    load("/home/smlogan/ocean_files/integrate.il")
    load("/home/smlogan/ocean_files/rise_fall.il")
    load("/home/smlogan/ocean_files/delay.il")
    load("/home/smlogan/ocean_files/setup.il")
    load("/home/smlogan/ocean_files/hold.il")

    ....

    Hence, in your case, include the line:

    load("path/abBestFit.ils")

    in your ocean script.

    NewScreenName said:
    Regarding this, once I use it the way I do, so defined in an ocean script, doesn't each simulation point run the function on a single waveform (rather than a family of waveforms)? Or should I still expect issues when used this way?

    I am not sure how you are invoking your ocean script - is it a standalone script or did you add an ocean output expression to an ADE output? As Andrew mentioned, if when you call the script it accesses the main ADE output directory of /psf and not the individual Interactive.X subdirectories of 1/psf, 2/psf,...N/psf, then the function is calling a family of waveforms and will not work.

    If you are running the script outside of ADE, then you can traverse the ADE Interactive.X directory structure and access each individual waveform and the function will work correctly. In prior posts, I have provided a sample ocean script (with annotations to allow one to modify it for one's results directory) that traverses an ADE results database. If that is of interest, let me know and I will include a Cadence Forum link to the script and its instructions.

    Shawn

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 1 year ago in reply to ShawnLogan
    ShawnLogan said:

    Hence, in your case, include the line:

    load("path/abBestFit.ils")

    in your ocean script.

    As I mentioned in another post, this is not the way I'd recommend to do this. Instead, use the "fx" button in the calculator or the "+" button in the expression builder and add the file that way - the ocnmRegGUIBuilder function in the code will mean that the function then shows up in the calculator (abBestFit specifically) and in future sessions it will be auto-loaded and you can use it directly in the calculator/expression builder, and both ADE output expressions and OCEAN script expressions will have access to the function. If you've written your own functions, the fx/+ button can take care of adding the ocnmRegGUIBuilder template code into your script which means you get a decent UI for calculator functions as well as them being useful in scripts.

    abBestFitCoeffs is a little different though. It is not a function that's designed to be used in the calculator - it doesn't return a single number or a waveform, but instead returns a list of two numbers. Because of this, it can't really be extended like most calculator functions should be to handle waveforms as inputs - because the result is a list of two numbers. You see the common pattern in calculator functions that they have a cond() function call to then distinguish between the argument being a waveform or a family - and if a family, the function gets recursively called via famMap. That won't work if the return value is a list because you can't end up with waveforms of lists or families of lists.

    NewScreenName said:
    Regarding this, once I use it the way I do, so defined in an ocean script, doesn't each simulation point run the function on a single waveform (rather than a family of waveforms)? Or should I still expect issues when used this way?

    A refinement on Shawn's answer as it wasn't entirely accurate (although the outcome is the same, most likely). During simulation, the OCEAN script measurements are indeed run with the results of just each point alone (provided that EvalType is set to "points" for the ocean script measurement output) - and then the functions don't need to deal with family data (unless of course the waveforms being accessed are the output of a swept analysis in Spectre, such as swept hb/pss). However, if you use the "re-evaluate" icon to re-evaluate results post-simulation (such as after modifying the script), then the script will see the entire set of results in a single go - so will be presented with the root of the results as a family. Because of this, any function really ought to expect to see family data.

    abBestFitCoeffs was really intended for situations such as in conventional OCEAN scripts (run outside of ADE) where you might be dealing with a single set of simulation results only rather than sweeps over design variables/parameters/corners - the internal function within the code was already there, so I just exposed it too in case it was useful.

    Regards,

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel
  • Frank Wiedmann
    Frank Wiedmann over 1 year ago in reply to Andrew Beckett

    How about creating two functions, one for each coefficient, that could then each be extended with famMap to handle waveforms as inputs?

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 1 year ago in reply to Frank Wiedmann
    Frank Wiedmann said:
    How about creating two functions, one for each coefficient, that could then each be extended with famMap to handle waveforms as inputs?

    Frank - that's on my to-do list (just didn't have a chance yet to do it when I replied earlier). I'll update the code in the other thread once I've done it and post here to say it's ready.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • Andrew Beckett
    Andrew Beckett over 1 year ago in reply to Andrew Beckett

    I updated the code in the original post to add two new functions - abBestFitSlope and abBestFitIntercept which do handle family data (they will return a waveform of the slope or intercept versus the swept parameter for each curve in the family.

    Andrew

    • Cancel
    • Vote Up +1 Vote Down
    • Cancel

Community Guidelines

The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.

© 2025 Cadence Design Systems, Inc. All Rights Reserved.

  • Terms of Use
  • Privacy
  • Cookie Policy
  • US Trademarks
  • Do Not Sell or Share My Personal Information