• Skip to main content
  • Skip to search
  • Skip to footer
Cadence Home
  • This search text may be transcribed, used, stored, or accessed by our third-party service providers per our Cookie Policy and Privacy Policy.

  1. Community Forums
  2. Custom IC Design
  3. Sampled point inaccuracy in AMS simulation

Stats

  • Locked Locked
  • Replies 4
  • Subscribers 129
  • Views 16064
  • 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

Sampled point inaccuracy in AMS simulation

auran
auran over 8 years ago

Hello,

I am trying to simulate a Verilog-AMS model of an ideal ADC, together with some Verilog-A and Verilog modules. Versions of the tools I use:

virtuoso : IC6-1-6.64b.500.11

spectre : 13.1.1.292.isr12 64bit

irun(64) : 14.10-s008

Netlist and run mode: AMS Unified Netlister with irun

Output log gives the following simulator parameters:

Important parameter values:
start = 0 s
outputstart = 0 s
stop = 1.89433 us
step = 1.89433 ns
maxstep = 18.9433 ns
ic = all
useprevic = no
skipdc = no
reltol = 100e-06
abstol(V) = 1 uV
abstol(I) = 1 pA
temp = 27 C
tnom = 27 C
tempeffects = all
errpreset = conservative
method = gear2only
lteratio = 10
relref = alllocal
cmin = 0 F
gmin = 1 pS

The Verilog-AMS code for the ADC looks like this:

always @ (posedge dclk) begin
   rin = V(vin) ;
   sample = V(vin) ;
   for (i=`NBITS-1; i>=0; i=i-1) begin
      is_over = (sample > halfref);
      if (is_over) sample = sample - halfref;
      sample = 2.0 * sample;
      dout[i] = is_over;
   end
end

Here, dclk and dout are of logic discipline, and vin is of electrical discipline. It works correctly except for some samples.

Here is a particular sampling instant:

There is a difference of 40 mV between V(vin) and the sampled value rin, which is unacceptable for my application.

I also checked the computed points and observed a cluster of points near the rising clock edge, but the sampled value occurs quite far away from this edge:

The time difference between those two samples is more than 4ps, but I use a timescale precision of 1fs in all my Verilog and Verilog-AMS modules in the netlist, so I have no idea where this error comes from.

Do you have any idea on the cause and solution of this abnormality? Or an advice on how to further debug?

Thanks in advance!

Arda

  • Cancel
Parents
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Arda,

    I ran your example with INCISIVE152 (as that was the version I had to hand). I ran the full 85us that you had in your example, and then wrote some SKILL code to sample the input signal IN at the points where the signal rin changes (i.e the clock edges), and then took the difference and plotted that. Here's the code I used:

    /*****************************************************************
    *                                                                *
    *               abSampleByReal(realWave contWave)                *
    *                                                                *
    *   The first argument is a real number waveform (i.e. sample    *
    *  and held, with time points only when a new sample is taken).  *
    *  This function samples the second waveform (continuous time)   *
    * at the instants in time where the real waveform changes (which *
    *              should be on the clock transitions)               *
    *                                                                *
    *****************************************************************/
    
    procedure(abSampleByReal(realWave contWave)
        let((rXVec rYVec cXVec cYVec rLen cLen oYVec rX rY cX cY oY 
                cXprev cYprev cInd)
            rXVec=drGetWaveformXVec(realWave)
            rYVec=drGetWaveformYVec(realWave)
            cXVec=drGetWaveformXVec(contWave)
            cYVec=drGetWaveformYVec(contWave)
            rLen=drVectorLength(rXVec)
            cLen=drVectorLength(cXVec)
            oYVec=drCreateVec('double rLen)
            cInd=0
            ;----------------------------------------------------------------
            ; this is a cheat just to prevent first point in waveform
            ; being wrong because real value hasn't sampled yet
            ;----------------------------------------------------------------
            drAddElem(oYVec drGetElem(rYVec 0))
            ;----------------------------------------------------------------
            ; Loop through each remaining sample point and linearly interpolate
            ; the continuous waveform at the sample points
            ;----------------------------------------------------------------
            for(ind 1 rLen-1
                rX=drGetElem(rXVec ind)
                rY=drGetElem(rYVec ind)
                cX=drGetElem(cXVec cInd)
                cY=drGetElem(cYVec cInd)
                while(cX<rX && cInd<cLen
                    cXprev=cX
                    cYprev=cY
                    cInd++
                    cX=drGetElem(cXVec cInd)
                    cY=drGetElem(cYVec cInd)
                )
                ;------------------------------------------------------------
                ; linearly interpolate or if no previous point
                ; just output directly
                ;------------------------------------------------------------
                oY=
                    if(cXprev then
                        (cY-cYprev)*(rX-cXprev)/(cX-cXprev)+cYprev
                    else
                        cY
                    )
                drAddElem(oYVec oY)
            )
            drCreateWaveform(rXVec oYVec)
        )
    )
    

    The OCEAN script to do the plotting was this:

    load("abSampleByReal.il")
    openResults("psf")
    selectResult("tran-tran")
    IN=v("test_timestep.IN")
    rin=v("test_timestep.ADC.rin")
    sampled=abSampleByReal(rin IN)
    plot(rin-sampled)

    The resulting waveform (zoomed in so you can see the detail) looks like this:

    It's the same all the way through - the peak is no more than about 10uV difference, so tiny - given that you are under sampling the input waveform (so it's changing rapidly) this is insignificant, I think. Certainly not the 40mV you were talking about.

    Perhaps it was a bug in the rather old INCISIVE version you were using? Not sure - I'd try with something more recent...

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Reply
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    Hi Arda,

    I ran your example with INCISIVE152 (as that was the version I had to hand). I ran the full 85us that you had in your example, and then wrote some SKILL code to sample the input signal IN at the points where the signal rin changes (i.e the clock edges), and then took the difference and plotted that. Here's the code I used:

    /*****************************************************************
    *                                                                *
    *               abSampleByReal(realWave contWave)                *
    *                                                                *
    *   The first argument is a real number waveform (i.e. sample    *
    *  and held, with time points only when a new sample is taken).  *
    *  This function samples the second waveform (continuous time)   *
    * at the instants in time where the real waveform changes (which *
    *              should be on the clock transitions)               *
    *                                                                *
    *****************************************************************/
    
    procedure(abSampleByReal(realWave contWave)
        let((rXVec rYVec cXVec cYVec rLen cLen oYVec rX rY cX cY oY 
                cXprev cYprev cInd)
            rXVec=drGetWaveformXVec(realWave)
            rYVec=drGetWaveformYVec(realWave)
            cXVec=drGetWaveformXVec(contWave)
            cYVec=drGetWaveformYVec(contWave)
            rLen=drVectorLength(rXVec)
            cLen=drVectorLength(cXVec)
            oYVec=drCreateVec('double rLen)
            cInd=0
            ;----------------------------------------------------------------
            ; this is a cheat just to prevent first point in waveform
            ; being wrong because real value hasn't sampled yet
            ;----------------------------------------------------------------
            drAddElem(oYVec drGetElem(rYVec 0))
            ;----------------------------------------------------------------
            ; Loop through each remaining sample point and linearly interpolate
            ; the continuous waveform at the sample points
            ;----------------------------------------------------------------
            for(ind 1 rLen-1
                rX=drGetElem(rXVec ind)
                rY=drGetElem(rYVec ind)
                cX=drGetElem(cXVec cInd)
                cY=drGetElem(cYVec cInd)
                while(cX<rX && cInd<cLen
                    cXprev=cX
                    cYprev=cY
                    cInd++
                    cX=drGetElem(cXVec cInd)
                    cY=drGetElem(cYVec cInd)
                )
                ;------------------------------------------------------------
                ; linearly interpolate or if no previous point
                ; just output directly
                ;------------------------------------------------------------
                oY=
                    if(cXprev then
                        (cY-cYprev)*(rX-cXprev)/(cX-cXprev)+cYprev
                    else
                        cY
                    )
                drAddElem(oYVec oY)
            )
            drCreateWaveform(rXVec oYVec)
        )
    )
    

    The OCEAN script to do the plotting was this:

    load("abSampleByReal.il")
    openResults("psf")
    selectResult("tran-tran")
    IN=v("test_timestep.IN")
    rin=v("test_timestep.ADC.rin")
    sampled=abSampleByReal(rin IN)
    plot(rin-sampled)

    The resulting waveform (zoomed in so you can see the detail) looks like this:

    It's the same all the way through - the peak is no more than about 10uV difference, so tiny - given that you are under sampling the input waveform (so it's changing rapidly) this is insignificant, I think. Certainly not the 40mV you were talking about.

    Perhaps it was a bug in the rather old INCISIVE version you were using? Not sure - I'd try with something more recent...

    Regards,

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
Children
No Data

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