• 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. systemVerilog equivalent of ahdlLib?

Stats

  • Locked Locked
  • Replies 2
  • Subscribers 125
  • Views 10460
  • 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

systemVerilog equivalent of ahdlLib?

aicdesigner
aicdesigner over 4 years ago

Hi,

        I was watching the presentation by Daniel Cross on the capacitive DAC model in SV. 

It would be nice to run the systemVerilog simulation on a schematic testbench. He has models for caps, resistors, switches, etc.

Is there a Cadence library like ahdlLib that would support the schematic > SV netlist > xrun flow?

Thanks

  • Cancel
  • Andrew Beckett
    Andrew Beckett over 4 years ago

    I checked with Daniel, and he's not aware (nor am I) of any Virtuoso library having been built by us containing such models.

    Andrew

    • Cancel
    • Vote Up 0 Vote Down
    • Cancel
  • aicdesigner
    aicdesigner over 4 years ago in reply to Andrew Beckett

    Thanks for checking Andrew. 

    I'm putting something together now. I can share what I have when I'm done.

    I'm running into a problem with a model for a switch. I wonder if Daniel or Ron Vogelsong could take a look. It might be an easy one.

    The switch resistance is always coming out OFF - the ctrl input is never seen as 1.


    //systemVerilog HDL for "mySV", "switch" "systemVerilog"

    `timescale 1ns/1ps
    import EE_pkg::*;

    // Shorthand for standard real constants:
    `define Z `wrealZState
    `define X `wrealXState

    module switch(P,N, ctrl);
    inout EEnet P,N;
    input ctrl;

    parameter real res=1000;

    parameter real tr=0; // risetime for analog changes (seconds)
    parameter real vtol=1e-6; // voltage tolerance for iterations.
    parameter real itermax=10; // max iterations at one timepoint.
    parameter real Kinc=1e-6; // fractional change at start of ramp

    real vval, rval;
    real Vval,Rval; // limited versions of vval,rval inputs
    EEnet Pext,Next; // external drive values
    real VPdrv,RPdrv,VNdrv,RNdrv; // voltage & resistance output drives
    bit newP,newN; // flag whether to update P & N drivers
    real VPo,RPo,VNo,RNo; // tolerance & iteration limited output drivers
    real Imeas; // current flowing through this element
    real Tdrv=0; // time of most recent driver updates
    integer Niter=0; // number iterations at this timepoint
    real trt; // risetime value in timescale units
    real vktol; // voltage tolerance dependent on Niter

    initial begin
    vval = 0;
    rval = ctrl === 1 ? res : 1000000000;
    VPdrv=0;
    RPdrv=`Z;
    VNdrv=0;
    RNdrv=`Z;
    vktol=1e-14; // voltage tolerance (adjusts with Niter)
    trt=0; // no risetime at time zero
    #(1step) trt=tr*1s; // risetime converted to timescale
    end

    // System calls to measure external drive seen at each pin:
    reg sie;
    initial sie = $SIE_input(P,Pext);
    initial sie = $SIE_input(N,Next);

    // Update Vval & Rval, including optional risetime and special cases:
    always begin
    rval = ctrl === 1 ? res : 1000000000;
    if (vval<1e12 && rval>=0) begin // normal drive
    if (trt>0) begin // if risetime included:
    if (Rval===`Z) Rval=1e10; // leaving high-Z region
    else if (vval!=Vval) Vval += Kinc*(vval-Vval); // bump V slightly
    else if (rval<Rval) Rval -= Kinc*(Rval+1); // bump R slightly
    else Rval += Kinc*(Rval+1); // in proper direction
    end
    Vval <= #(trt) vval; // change to new values after risetime
    Rval <= #(trt) rval;
    end
    else if ((vval===`Z) || (rval===`Z)) begin // going to high Z case
    if (trt>0) Rval += Kinc*(Rval+1); // if risetime, bump R value
    Rval <= #(trt) `Z; // change to Z state
    Vval <= #(trt) 0; // V not used when R=Z
    end
    else begin // going to invalid drive
    if (trt>0) Rval += Kinc*(Rval+1); // if risetime, bump R first
    Rval <= #(trt) `X; // change to X state
    Vval <= #(trt) `X;
    end
    @(vval,rval);
    end

    always begin //////// P->N PROCESSING ////////
    if (Rval===`Z || Pext.R===`Z) begin // high-Z drive
    VNdrv <= 0;
    RNdrv <= `Z;
    end
    else begin // normal drive
    VNdrv <= Pext.V-Vval;
    RNdrv <= Pext.R+Rval;
    end
    @(Pext.V,Pext.R,Vval,Rval); // repeat on change to P or input
    end

    always begin //////// N->P PROCESSING ////////
    if (Rval===`Z || Next.R===`Z) begin // high-Z drive
    VPdrv <= 0;
    RPdrv <= `Z;
    end
    else begin // normal drive
    VPdrv <= Next.V+Vval;
    RPdrv <= Next.R+Rval;
    end
    @(Next.V,Next.R,Vval,Rval); // repeat on change to N or input
    end

    always @(VPdrv,RPdrv,VNdrv,RNdrv) begin
    if ($realtime>Tdrv) begin // if new timepoint
    Tdrv=$realtime; // save time value
    Niter=0; // init counter
    vktol=1e-14; // first iterations update on any change
    end
    // Update on R change or nontrivial V change:
    if (Niter==3) vktol=vtol; // only update change of >vtol after 3 iterations
    newN = (RNdrv!==RNo || abs(VNdrv-VNo)>vktol);
    newP = (RPdrv!==RPo || abs(VPdrv-VPo)>vktol);
    Niter++; // bump iteration counter
    if (newP|newN) begin // if any signficant change
    if (Niter<=itermax) begin // and if within normal iterations
    if (newP) begin
    VPo <= VPdrv; // update P node driver
    RPo <= RPdrv;
    end
    if (newN) begin
    VNo <= VNdrv; // update N node driver
    RNo <= RNdrv;
    end // Compute measured current flow:
    if (RPdrv+Pext.R>0) Imeas <= (Pext.V-VPdrv)/(Pext.R+RPdrv);
    else Imeas <= 0; // this case should never occur!
    end
    else if (Niter==itermax+1) $display( // message when past iteration limit
    "<EE> ERROR: VRsrc instance %M node%s unconverged at T=%.0fns",
    (newP&newN)? "s P&N" : (newP)?" P" : " N", $realtime);
    end
    end

    assign P = '{VPo, 0, RPo}; // drive output pins
    assign N = '{VNo, 0, RNo};

    assign imeas = Imeas; // return current flow (P to N)

    endmodule

    • 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