• 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 126
  • Views 15638
  • 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
  • Andrew Beckett
    Andrew Beckett over 8 years ago

    That's quite hard to debug without seeing the complete example. If you could provide the whole ADC model and a simple test bench that shows the problem, that would help.

    Otherwise, please contact customer support.

    Andrew.

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • auran
    auran over 8 years ago

    Hello Andrew, thanks for your reply.

    Here is a simple test case which includes:

    -the ADC model

    -two ideal voltage sources for input sine and clock

    -an electrical to logic interface to create a discrete-event clock from the voltage source.

    -the netlist for test bench that combines the above

    -the ocean script generated from the ADE L window

    Another strange behavior I notice is that the errors occur at different times for each different run of the same netlist.

    Best,

    Arda

    ADC:

    //Verilog-AMS HDL for "tiadc_ams", "interface_adc_10bit" "verilogams"
    `include "constants.vams"
    `include "disciplines.vams"

    `define NBITS 10
    `timescale 1s/1fs

    module test_timestep_interface_adc_10bit(vin, dclk, dout);

    input vin;
    input dclk;
    output reg [`NBITS-1:0] dout;

    //disciplines
    electrical vin;
    logic dclk;
    logic [`NBITS-1:0] dout;

    real vref;
    reg [`NBITS-1:0] dout_reg [0:127]; //the input sine period is set to repeat every 128 samples
    integer counter;
    integer ok, error;

    real rin, sample, halfref;
    reg is_over;

    integer i;

    //initialize
    initial begin
    dout = 0;
    vref = 1.0;
    halfref = vref/2.0;
    counter = 0;
    ok = 0;
    error = 0;
    end

    //A/D conversion
    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
    //store expected values and inform in case of inequality
    if ((ok == 1) && (dout_reg[counter] != dout)) begin
    error = 1;
    end
    if (ok != 1) dout_reg[counter] = dout;
    if (counter == 127) ok = 1; //expected values are stored
    counter = (counter + 1)%128;
    end
    endmodule

    Electrical to logic interface:

    //Verilog-AMS HDL for "tiadc_ams", "interface_e2l" "verilogams"

    `include "constants.vams"
    `include "disciplines.vams"

    `timescale 1s/1fs

    module interface_e2l( vin, dout );
    input vin;
    output reg dout;

    //disciplines
    electrical vin;
    logic dout;

    parameter real vtrans = 0.5 from [0:inf);
    parameter integer logic_out_initial = 1 from [0:1];

    initial begin
    dout = logic_out_initial;
    end

    always @ (cross(V(vin) - vtrans, 1)) dout = 1;
    always @ (cross(V(vin) - vtrans, -1)) dout = 0;

    endmodule

    Netlist:

    ////////////////////////////////////////////////////////////////////////
    // PLEASE DO NOT EDIT OR COMPILE THIS FILE.
    // IT IS MEANT FOR VIEWING PURPOSE ONLY.
    //
    // All files for configuration: (tiadc_ams test_timestep config)
    ////////////////////////////////////////////////////////////////////////

    // AMS netlist generated by the AMS Unified netlister
    // IC subversion: IC6.1.6-64b.500.11
    // IUS version: 15.10-s021
    // Copyright(C) 2005-2009, Cadence Design Systems, Inc
    // User: auran Pid: 32612
    // Design library name: tiadc_ams
    // Design cell name: test_timestep
    // Design view name: config
    // Solver: Spectre

    `include "disciplines.vams"
    `include "userDisciplines.vams"
    // HDL file - tiadc_ams, interface_e2l, verilogams.
    // HDL file - tiadc_ams, test_timestep_interface_adc_10bit, verilogams.
    // Library - tiadc_ams, Cell - test_timestep, View - schematic
    // LAST TIME SAVED: Apr 2 23:37:21 2017
    // NETLIST TIME: Apr 3 00:10:34 2017

    `worklib tiadc_ams
    `view schematic

    `timescale 1ns / 1ns
    (* cds_ams_schematic *)

    module test_timestep ( );
    wire [9:0] DOUT;
    wire IN;
    wire DCLK;
    wire CLK_MASTER;
    test_timestep_interface_adc_10bit ADC (.dclk( DCLK ), .dout( DOUT ), .vin( IN ));
    interface_e2l #(.logic_out_initial(0)) I2 (.dout( DCLK ), .vin( CLK_MASTER ));
    vsource #(.type("sine"), .sinedc(0.5), .ampl(0.91/2), .freq(12e+9*509/1024)) VIN_SINE (IN, cds_globals.\gnd! );
    vsource #(.type("pulse"), .val0(0), .val1(1), .period(1/(12e+9/16)), .delay(0), .rise(1/(12e+9/16)/100), .fall(1/(12e+9/16)/100)) VCLK_MASTER (CLK_MASTER, cds_globals.\gnd! );

    endmodule
    `noworklib
    `noview
    // Verilog-AMS cds_globals module for top-level cell:
    // tiadc_ams/test_timestep.
    // Generated by ADE.
    // Cadence Design Systems, Inc.

    // This is an autoGenerated file, any changes done to this file may get lost.

    `include "disciplines.vams"
    `include "userDisciplines.vams"

    module cds_globals;

    // Global Signals
    electrical \gnd! ;
    ground \gnd! ;

    // Design Variables

    endmodule

    // This is the Cadence AMS Designer(R) analog simulation control file.
    // It specifies the options and analyses for the Spectre analog solver.

    simulator lang=spectre

    global 0

    simulatorOptions options temp=27 tnom=27 scale=1.0 scalem=1.0 reltol=1e-7 \
    vabstol=1e-6 iabstol=1e-12 gmin=1e-12 rforce=1 maxnotes=5 maxwarns=5 \
    digits=5 pivrel=1e-3 checklimitdest=psf

    tran tran stop=853.333333e-7 errpreset=conservative save=none \
    write="spectre.ic" writefinal="spectre.fc" annotate=status maxiters=5

    finalTimeOP info what=oppoint where=rawfile

    modelParameter info what=models where=rawfile
    element info what=inst where=rawfile
    outputParameter info what=output where=rawfile

    # This is the NC-SIM(R) probe command file
    # used in the AMS-ADE integration.


    #
    # Database settings
    #
    if { [info exists ::env(AMS_RESULTS_DIR) ] } { set AMS_RESULTS_DIR $env(AMS_RESULTS_DIR)} else {set AMS_RESULTS_DIR "../psf"}
    database -open ams_database -into ${AMS_RESULTS_DIR} -default

    #
    # Probe settings
    #
    probe -create -emptyok -database ams_database -all -memories -depth all {test_timestep}
    probe -create -emptyok -database ams_database -all -memories cds_globals
    probe -create -emptyok -database ams_database -aicms -all {test_timestep}

    Ocean script:

    simulator( 'ams )
    solver( 'Spectre )
    design( "RUNDIR/simulation/test_timestep/ams/config/netlist/netlist")
    ocnAmsSetUnlNetlister()
    resultsDir( "RUNDIR/simulation/test_timestep/ams/config" )
    globalSignal(?name "gnd!" ?lang "CDBA" ?wireType "wire" ?discipline "" ?ground "YES")
    definitionFile(
    "models.scs"
    )
    analysis('tran ?stop "853.333333e-7" ?errpreset "conservative" )
    envOption(
    'netlisterMode "AMS-UNL"
    )
    option( 'reltol "1e-7"
    )
    saveOption( ?probeMemories t )
    saveOption( 'currents "none" )
    saveOption( 'cmSave "all" )
    saveOption( 'netLevelsToSave "all" )
    saveOption( 'save "all" )
    temp( 27 )
    run()

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • 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
  • auran
    auran over 8 years ago
    Hi Andrew,

    Then I guess it could be a bug as well. I'm not sure if I have access to INCISIVE152 to try it, but I came up with a workaround. Instead of using analogLib voltage sources for
    the input and the clock, I generate them using Verilog-AMS codes, and the error vanishes.

    Thank you very much for your time and effort.

    Best,

    Arda
    • Cancel
    • Vote Up 0 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