// Model generated by Verilog-A Distiller.
// (c)2026 Arpad Buermen. All rights reserved.
// SPDX-License-Identifier: AGPL-3.0-or-later
// 
// SPICE flavour: ngspice
// Version      : ngspice-44-549-ga4ff5a204
// Origin       : https://sourceforge.net/u/arpadbuermen/ngspice/ci/vadng-pre-48/tree/
// Date         : 2026-08-18 12:22:40 UTC
// Module name  : sp_mos9
// Model variant: full
// 
// Notes:
//   Parameter m was replaced with builtin Verilog-A parameter $mfactor.
//
//   All parameters and output variables refer to a single parallel instance,
//   even if $mfactor>1.
//
//   Parameter off was removed. Bypassing is not available in Verilog-A. 
//   
//   Device type is set by the type parameter to NMOS (1) or PMOS (-1). 
//   
//   Output variables rs and rd were removed due to a conflict with model 
//   parameters. Their inverses are available as sourceconductance and 
//   drainconductance output variables. 
//   
//   Output variables cbd, cbs, ig, id, is, and ib were renamed to c_bd, 
//   c_bs, i_g, i_d, i_s, i_b due to conflicts with model parameters. 
//   
//   Meyer charge is not computed and therefore not available. 
//   Output variables qgs, qgd, and qgb were removed. 
//   
//   Parameters ic, icvds, icvgs, and icvbs were removed. Initial conditions 
//   should be set via the simulator's initial conditions mechanism. 
//   
//   Noise model excludes Meyer capacitance currents from the drain 
//   current that is used for computing noise. This is a SPICE3 feature. 
//   Simplified noise model also excludes the capacitive current of the 
//   B-D diode. Due to the way OpenVAF handles c(v)*ddt(v) the implicit 
//   equations do not go away even if simplified noise model is used.
//
//   This model exposes output variables that can lead to creation of
//   implicit equations by OpenVAF.
//
//   Full noise model used (appropriate for all noise analyses).
//   OpenVAF may create implicit equations.
//
// CKTcircuit member mapping
//        CKTbadMos3 -> ('badmos3', '$simparam("badmos3", 0)', 'const')
//   CKTdefaultMosAD -> ('defad', '$simparam("defad", 0)', 'const')
//   CKTdefaultMosAS -> ('defas', '$simparam("defas", 0)', 'const')
//    CKTdefaultMosL -> ('defl', '$simparam("defl", 1e-4)', 'const')
//    CKTdefaultMosW -> ('defw', '$simparam("defw", 1e-4)', 'const')
//       CKTfixLimit -> ('oldlimit', '$simparam("oldlimit", 0)', 'const')
//           CKTgmin -> ('gmin', '$simparam("gmin", 1e-12)')
//        CKTnomTemp -> ('tnom', '($simparam("tnom", 27)+273.15)')
//           CKTtemp -> (None, '$temperature')
//
// Source files and copyright information:
//   devsup.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1985 Thomas L. Quarles
//     Modified: 2000 AlansFixes
//   mos9/mos9defs.h
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1985 Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1987 Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9par.c
//   mos9/mos9mpar.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1985 Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9ask.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1987 Mathew Lew and Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9mask.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1987 Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9set.c
//   mos9/mos9temp.c
//   mos9/mos9load.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1985 Thomas L. Quarles
//     Modified: Alan Gillespie
//   mos9/mos9noi.c
//     Copyright 1990 Regents of the University of California.  All rights reserved.
//     Author: 1987 Gary W. Ng
//     Modified: Alan Gillespie

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

module sp_mos9(d, g, s, b);
  inout d, g, s, b;
  electrical d, g, s, b, d_int, s_int;

  // Instance parameters
  (* desc = "Length", type = "instance" *) parameter real l = 0;
  (* desc = "Width", type = "instance" *) parameter real w = 0;
  (* desc = "Drain area", type = "instance" *) parameter real ad = 0;
  (* desc = "Source area", type = "instance" *) parameter real as = 0;
  (* desc = "Drain perimeter", type = "instance" *) parameter real pd = 0;
  (* desc = "Source perimeter", type = "instance" *) parameter real ps = 0;
  (* desc = "Drain squares", type = "instance" *) parameter real nrd = 1;
  (* desc = "Source squares", type = "instance" *) parameter real nrs = 1;
  (* desc = "Instance operating temperature", type = "instance" *) parameter real temp = 0;
  (* desc = "Instance operating temperature difference", type = "instance" *) parameter real dtemp = 0.0;

  // Model parameters
  (* desc = "NMOS (1) or PMOS (-1)" *) parameter integer type = 1;
  (* desc = "Threshold voltage" *) parameter real vto = 0;
  aliasparam vt0 = vto;
  (* desc = "Transconductance parameter" *) parameter real kp = 2e-05;
  (* desc = "Bulk threshold parameter" *) parameter real gamma = 0;
  (* desc = "Surface potential" *) parameter real phi = 0.6;
  (* desc = "Drain ohmic resistance" *) parameter real rd = 0;
  (* desc = "Source ohmic resistance" *) parameter real rs = 0;
  (* desc = "B-D junction capacitance" *) parameter real cbd = 0;
  (* desc = "B-S junction capacitance" *) parameter real cbs = 0;
  (* desc = "Bulk junction sat. current" *) parameter real is = 1e-14;
  (* desc = "Bulk junction potential" *) parameter real pb = 0.8;
  (* desc = "Gate-source overlap cap." *) parameter real cgso = 0;
  (* desc = "Gate-drain overlap cap." *) parameter real cgdo = 0;
  (* desc = "Gate-bulk overlap cap." *) parameter real cgbo = 0;
  (* desc = "Sheet resistance" *) parameter real rsh = 0;
  (* desc = "Bottom junction cap per area" *) parameter real cj = 0;
  (* desc = "Bottom grading coefficient" *) parameter real mj = 0.5;
  (* desc = "Side junction cap per area" *) parameter real cjsw = 0;
  (* desc = "Side grading coefficient" *) parameter real mjsw = 0.33;
  (* desc = "Bulk jct. sat. current density" *) parameter real js = 0;
  (* desc = "Oxide thickness" *) parameter real tox = 1e-07;
  (* desc = "Lateral diffusion" *) parameter real ld = 0;
  (* desc = "Length mask adjustment" *) parameter real xl = 0;
  (* desc = "Width Narrowing (Diffusion)" *) parameter real wd = 0;
  (* desc = "Width mask adjustment" *) parameter real xw = 0;
  (* desc = "Threshold voltage Adjust" *) parameter real delvto = 0;
  aliasparam delvt0 = delvto;
  (* desc = "Surface mobility" *) parameter real u0 = 600;
  aliasparam uo = u0;
  (* desc = "Forward bias jct. fit parm." *) parameter real fc = 0.5;
  (* desc = "Substrate doping" *) parameter real nsub = 0;
  (* desc = "Gate type" *) parameter integer tpg = 1;
  (* desc = "Surface state density" *) parameter real nss = 0;
  (* desc = "Maximum carrier drift velocity" *) parameter real vmax = 0;
  (* desc = "Junction depth" *) parameter real xj = 0;
  (* desc = "Fast surface state density" *) parameter real nfs = 0;
  (* desc = "Vds dependence of threshold voltage" *) parameter real eta = 0;
  (* desc = "Width effect on threshold" *) parameter real delta = 0;
  (* desc = "Vgs dependence on mobility" *) parameter real theta = 0;
  (* desc = "Kappa" *) parameter real kappa = 0.2;
  (* desc = "Parameter measurement temperature" *) parameter real tnom = 0;
  (* desc = "Flicker noise coefficient" *) parameter real kf = 0;
  (* desc = "Flicker noise exponent" *) parameter real af = 1;

  // Instance output variables
  (* desc = "Drain current" *) real i_d;
  (* desc = "B-D junction current" *) real ibd;
  (* desc = "B-S junction current" *) real ibs;
  (* desc = "Source current" *) real i_s;
  (* desc = "Gate current" *) real i_g;
  (* desc = "Bulk current" *) real i_b;
  (* desc = "Gate-Source voltage" *) real vgs;
  (* desc = "Drain-Source voltage" *) real vds;
  (* desc = "Bulk-Source voltage" *) real vbs;
  (* desc = "Bulk-Drain voltage" *) real vbd;
  (* desc = "Turn-on voltage" *) real von;
  (* desc = "Saturation drain voltage" *) real vdsat;
  (* desc = "Critical source voltage" *) real sourcevcrit;
  (* desc = "Critical drain voltage" *) real drainvcrit;
  (* desc = "Source conductance" *) real sourceconductance;
  (* desc = "Drain conductance" *) real drainconductance;
  (* desc = "Transconductance" *) real gm;
  (* desc = "Drain-Source conductance" *) real gds;
  (* desc = "Bulk-Source transconductance" *) real gmb;
  (* desc = "Bulk-Drain conductance" *) real gbd;
  (* desc = "Bulk-Source conductance" *) real gbs;
  (* desc = "Bulk-Drain capacitance" *) real c_bd;
  (* desc = "Bulk-Source capacitance" *) real c_bs;
  (* desc = "Gate-Source capacitance" *) real cgs;
  (* desc = "Gate-Drain capacitance" *) real cgd;
  (* desc = "Gate-Bulk capacitance" *) real cgb;
  (* desc = "Capacitance due to gate-source charge storage" *) real cqgs;
  (* desc = "Capacitance due to gate-drain charge storage" *) real cqgd;
  (* desc = "Capacitance due to gate-bulk charge storage" *) real cqgb;
  (* desc = "Capacitance due to bulk-drain charge storage" *) real cqbd;
  (* desc = "Capacitance due to bulk-source charge storage" *) real cqbs;
  (* desc = "Zero-Bias B-D junction capacitance" *) real cbd0;
  (* desc = "Zero-Bias B-D sidewall capacitance" *) real cbdsw0;
  (* desc = "Zero-Bias B-S junction capacitance" *) real cbs0;
  (* desc = "Zero-Bias B-S sidewall capacitance" *) real cbssw0;
  (* desc = "Bulk-Source charge storage" *) real qbs;
  (* desc = "Bulk-Drain charge storage" *) real qbd;
  (* desc = "Instantaneous power" *) real p;

  // Model output variables
  (* desc = "Depletion layer width" *) real xd;
  (* desc = "Alpha" *) real alpha;
  (* desc = "" *) real input_delta;

  // Instance fields
  real MOS9l = 0;
  real MOS9w = 0;
  real MOS9drainArea = 0;
  real MOS9sourceArea = 0;
  real MOS9sourceConductance = 0;
  real MOS9drainConductance = 0;
  real MOS9temp = 0;
  real MOS9tTransconductance = 0;
  real MOS9tSurfMob = 0;
  real MOS9tPhi = 0;
  real MOS9tVto = 0;
  real MOS9tSatCur = 0;
  real MOS9tSatCurDens = 0;
  real MOS9tCbd = 0;
  real MOS9tCbs = 0;
  real MOS9tCj = 0;
  real MOS9tCjsw = 0;
  real MOS9tBulkPot = 0;
  real MOS9tDepCap = 0;
  real MOS9tVbi = 0;
  real MOS9von = 0;
  real MOS9vdsat = 0;
  real MOS9sourceVcrit = 0;
  real MOS9drainVcrit = 0;
  real MOS9cd = 0;
  real MOS9cbs = 0;
  real MOS9cbd = 0;
  real MOS9gmbs = 0;
  real MOS9gm = 0;
  real MOS9gds = 0;
  real MOS9gbd = 0;
  real MOS9gbs = 0;
  real MOS9capbd = 0;
  real MOS9capbs = 0;
  real MOS9Cbd = 0;
  real MOS9Cbdsw = 0;
  real MOS9Cbs = 0;
  real MOS9Cbssw = 0;
  real MOS9f2d = 0;
  real MOS9f3d = 0;
  real MOS9f4d = 0;
  real MOS9f2s = 0;
  real MOS9f3s = 0;
  real MOS9f4s = 0;
  integer MOS9mode = 0;
  real MOS9cgs = 0;
  real MOS9cgd = 0;
  real MOS9cgb = 0;
  real MOS9dcCurrent = 0;
  real meyer_scale = 0;
  real meyer_unscale = 0;
  integer MOS9tempGiven = 0;

  // Model fields
  real MOS9tnom = 0;
  real MOS9transconductance = 0;
  real MOS9oxideCapFactor = 0;
  real MOS9vt0 = 0;
  real MOS9phi = 0;
  real MOS9gamma = 0;
  real MOS9substrateDoping = 0;
  real MOS9coeffDepLayWidth = 0;
  real MOS9narrowFactor = 0;
  real MOS9alpha = 0;
  integer MOS9type = 0;
  integer MOS9tnomGiven = 0;

  // States
  real MOS9vbd = 0;
  real MOS9vbs = 0;
  real MOS9vgs = 0;
  real MOS9vds = 0;
  real MOS9capgs = 0;
  real MOS9qgs = 0;
  real MOS9cqgs = 0;
  real MOS9capgd = 0;
  real MOS9qgd = 0;
  real MOS9cqgd = 0;
  real MOS9capgb = 0;
  real MOS9qgb = 0;
  real MOS9cqgb = 0;
  real MOS9qbd = 0;
  real MOS9cqbd = 0;
  real MOS9qbs = 0;
  real MOS9cqbs = 0;

  // Model parameter access locals

  // Instance parameter access locals
  real instask_temp = 0;

  // Device setup locals

  // Device temperature dependence locals
  real wkfngs = 0;
  real wkfng = 0;
  real fermig = 0;
  real fermis = 0;
  real vfb = 0;
  real fact1 = 0;
  real fact2 = 0;
  real vt = 0;
  real vtnom = 0;
  real kt = 0;
  real kt1 = 0;
  real ratio = 0;
  real ratio4 = 0;
  real egfet = 0;
  real egfet1 = 0;
  real pbfact = 0;
  real pbfact1 = 0;
  real pbo = 0;
  real phio = 0;
  real arg1 = 0;
  real capfact = 0;
  real gmanew = 0;
  real gmaold = 0;
  real ni_temp = 0;
  real nifact = 0;
  real czbd = 0;
  real czbdsw = 0;
  real czbs = 0;
  real czbssw = 0;
  real arg = 0;
  real sarg = 0;
  real sargsw = 0;

  // Device load locals
  integer limited = 0;
  real Beta = 0;
  real DrainSatCur = 0;
  real EffectiveLength = 0;
  real EffectiveWidth = 0;
  real GateBulkOverlapCap = 0;
  real GateDrainOverlapCap = 0;
  real GateSourceOverlapCap = 0;
  real OxideCap = 0;
  real SourceSatCur = 0;
  real load_arg = 0;
  real cdrain = 0;
  real cdreq = 0;
  real ceq = 0;
  real ceqbd = 0;
  real ceqbs = 0;
  real ceqgb = 0;
  real ceqgd = 0;
  real ceqgs = 0;
  real evbd = 0;
  real evbs = 0;
  real gcgb = 0;
  real gcgd = 0;
  real gcgs = 0;
  real geq = 0;
  real load_sarg = 0;
  real load_sargsw = 0;
  real load_vbd = 0;
  real load_vbs = 0;
  real load_vds = 0;
  real load_vdsat = 0;
  real vgb = 0;
  real vgd = 0;
  real vgdo = 0;
  real load_vgs = 0;
  real load_von = 0;
  real xfact = 0;
  integer xnrm = 0;
  integer xrev = 0;
  real capgs = 0;
  real capgd = 0;
  real capgb = 0;
  real load_vt = 0;
  real coeff0 = 0;
  real coeff1 = 0;
  real coeff2 = 0;
  real oneoverxl = 0;
  real load_eta = 0;
  real phibs = 0;
  real sqphbs = 0;
  real dsqdvb = 0;
  real sqphis = 0;
  real sqphs3 = 0;
  real wps = 0;
  real oneoverxj = 0;
  real xjonxl = 0;
  real djonxj = 0;
  real wponxj = 0;
  real arga = 0;
  real argb = 0;
  real argc = 0;
  real dwpdvb = 0;
  real dadvb = 0;
  real dbdvb = 0;
  real gammas = 0;
  real fbodys = 0;
  real fbody = 0;
  real onfbdy = 0;
  real qbonco = 0;
  real vbix = 0;
  real wconxj = 0;
  real dfsdvb = 0;
  real dfbdvb = 0;
  real dqbdvb = 0;
  real vth = 0;
  real dvtdvb = 0;
  real csonco = 0;
  real cdonco = 0;
  real dxndvb = 0;
  real dvodvb = 0;
  real dvodvd = 0;
  real vgsx = 0;
  real dvtdvd = 0;
  real onfg = 0;
  real fgate = 0;
  real us = 0;
  real dfgdvg = 0;
  real dfgdvd = 0;
  real dfgdvb = 0;
  real dvsdvg = 0;
  real dvsdvb = 0;
  real dvsdvd = 0;
  real xn = 0;
  real vdsc = 0;
  real onvdsc = 0;
  real dvsdga = 0;
  real vdsx = 0;
  real dcodvb = 0;
  real cdnorm = 0;
  real cdo = 0;
  real cd1 = 0;
  real fdrain = 0;
  real fd2 = 0;
  real dfddvg = 0;
  real dfddvb = 0;
  real dfddvd = 0;
  real gdsat = 0;
  real cdsat = 0;
  real gdoncd = 0;
  real gdonfd = 0;
  real gdonfg = 0;
  real dgdvg = 0;
  real dgdvd = 0;
  real dgdvb = 0;
  real emax = 0;
  real emongd = 0;
  real demdvg = 0;
  real demdvd = 0;
  real demdvb = 0;
  real delxl = 0;
  real dldvd = 0;
  real dldem = 0;
  real ddldvg = 0;
  real ddldvd = 0;
  real ddldvb = 0;
  real dlonxl = 0;
  real xlfact = 0;
  real diddl = 0;
  real gds0 = 0;
  real emoncd = 0;
  real ondvt = 0;
  real onxn = 0;
  real wfact = 0;
  real gms = 0;
  real gmw = 0;
  real fshort = 0;
  integer innerline1000 = 0;
  integer line900 = 1;
  integer line700 = 2;
  integer line520 = 3;
  integer line510 = 4;
  integer goto_destination = -1;

  // Device noise locals
  real flicker_psd = 0;
  real flicker_exp = 1;

  // Global constants
  real CONSTroot2 = sqrt(2.0);
  real CONSTvt0 = 1.38064852e-23*(27+273.15)/1.6021766208e-19;
  real CONSTKoverQ = 1.38064852e-23/1.6021766208e-19;
  real CONSTe = exp(1.0);
  real VACONSTcharge = 1.6021766208e-19;
  real VACONSTboltz = 1.38064852e-23;
  real badmos3 = $simparam("badmos3", 0);
  real defad = $simparam("defad", 0);
  real defas = $simparam("defas", 0);
  real defl = $simparam("defl", 1e-4);
  real defw = $simparam("defw", 1e-4);
  real oldlimit = $simparam("oldlimit", 0);
  real VACONST_tnom = ($simparam("tnom", 27)+273.15);

  // Evaluation constants
  real lc_gmin = 0;

  // Translated function definitions
  analog function real DEVqmeyer;
    input vgs, vgd, vgb, von, _vdsat;
    inout capgs, capgd, capgb;
    input phi, cox;
    real vgs;
    real vgd;
    real vgb;
    real von;
    real _vdsat;
    real capgs;
    real capgd;
    real capgb;
    real phi;
    real cox;
    real vdsat;
    real vds;
    real vddif;
    real vddif1;
    real vddif2;
    real vgst;
    begin
      DEVqmeyer = 0;
      vdsat = _vdsat;
      vgst = vgs-von;
      vdsat = ((vdsat>0.025) ? (vdsat) : (0.025));
      if (vgst<=-phi) begin
        capgb = cox/2;
        capgs = 0;
        capgd = 0;
      end else if (vgst<=-phi/2) begin
        capgb = -vgst*cox/(2*phi);
        capgs = 0;
        capgd = 0;
      end else if (vgst<=0) begin
        capgb = -vgst*cox/(2*phi);
        capgs = vgst*cox/(1.5*phi)+cox/3;
        vds = vgs-vgd;
        if (vds>=vdsat) begin
          capgd = 0;
        end else begin
          vddif = 2.0*vdsat-vds;
          vddif1 = vdsat-vds;
          vddif2 = vddif*vddif;
          capgd = capgs*(1.0-vdsat*vdsat/vddif2);
          capgs = capgs*(1.0-vddif1*vddif1/vddif2);
        end
      end else begin
        vds = vgs-vgd;
        vdsat = ((vdsat>0.025) ? (vdsat) : (0.025));
        if (vdsat<=vds) begin
          capgs = cox/3;
          capgd = 0;
          capgb = 0;
        end else begin
          vddif = 2.0*vdsat-vds;
          vddif1 = vdsat-vds;
          vddif2 = vddif*vddif;
          capgd = cox*(1.0-vdsat*vdsat/vddif2)/3;
          capgs = cox*(1.0-vddif1*vddif1/vddif2)/3;
          capgb = 0;
        end
      end
    end
  endfunction

  // Verbatim analog functions
  analog function integer initialize_limiting;
    integer il;
    begin
      il = $simparam("iniLim", -1);
      if (il<0) begin
        // iniLim not available, use heuristics
        initialize_limiting = 
          $simparam("iteration", 10)==1 && 
          (analysis("dc") || analysis("static")) && 
          analysis("nodeset");
      end else begin
        initialize_limiting = il;
      end
    end
  endfunction

  analog function real DEVlimitOldGet;
    input vnew, vold;
    real vnew, vold, result;
    begin
      DEVlimitOldGet = vold;
    end
  endfunction

  analog function real DEVlimitNewSet;
    input vnew, vold, new_value, limited;
    real vnew, vold, new_value;
    integer limited;
    begin
      DEVlimitNewSet = new_value;
      if (limited) begin
        $discontinuity(-1);
      end
    end
  endfunction

  analog function real DEVpnjlim;
    input vnew, vold, vt, vcrit;
    inout limiting_applied;
    real vnew, vold, vt, vcrit, limited, arg;
    integer limiting_applied;
    
    begin
      limited = vnew;
      if ((vnew > vcrit) && (abs(vnew - vold) > (vt + vt))) begin
        // Positive vnew above vcrit, change greater than 2*vt
        if(vold > 0) begin
          arg = (vnew - vold) / vt;
          if(arg > 0) begin
            limited = vold + vt * ln(1+arg);
            limiting_applied = 1;
          end else begin
            limited = vold - vt * ln(1-arg);
            limiting_applied = 1;
          end
        end else begin
          limited = vt *ln(vnew/vt);
          limiting_applied = 1;
        end
      end else if (vnew<0) begin
        // Negative vnew, use ngspice limiting
        if (vold > 0) begin
          arg = -1*vold-1; 
        end else begin
          arg = 2*vold-1;
        end
        if (vnew<arg) begin
          limited = arg;
          limiting_applied = 1;
        end
      end 
      DEVpnjlim = limited;
    end
  endfunction

  analog function real DEVfetlim;
    input vnew, vold, vto;
    inout limiting_applied;
    real vnew, vold, vto, vlimited;
    real vtsthi, vtstlo, vtox, delv, vtemp;
    integer limiting_applied;  
    begin
      vlimited = vnew;
      vtsthi = abs(2*(vold-vto))+2;
      // vtstlo = vtsthi/2 +2;
      vtstlo = abs(vold-vto)+1;
      vtox = vto + 3.5;
      delv = vnew-vold;
      
      if (vold >= vto) begin
        if(vold >= vtox) begin
          if(delv <= 0) begin
            /* going off */
            if(vlimited >= vtox) begin
                if(-delv > vtstlo) begin
                vlimited =  vold - vtstlo;
                end
            end else begin
              vlimited = max(vnew,vto+2);
            end
          end else begin
            /* staying on */
            if(delv >= vtsthi) begin
              vlimited = vold + vtsthi;
            end
          end
        end else begin
          /* middle region */
          if(delv <= 0) begin
            /* decreasing */
            vlimited = max(vnew,vto-0.5);
          end else begin
            /* increasing */
            vlimited = min(vnew,vto+4);
          end
        end
      end else begin
        /* off */
        if(delv <= 0) begin
          if(-delv >vtsthi) begin
            vlimited = vold - vtsthi;
          end
        end else begin
          vtemp = vto + 0.5;
          if(vnew <= vtemp) begin
            if(delv > vtstlo) begin
              vlimited = vold + vtstlo;
            end
          end else begin
            vlimited = vtemp;
          end
        end
      end
      if (vlimited!=vnew) begin
        limiting_applied = 1;
      end
      DEVfetlim = vlimited;
    end
  endfunction

  analog function real DEVlimvds;
    input vnew, vold;
    inout limiting_applied;
    real vnew, vold, vlimited;
    integer limiting_applied;
    begin
      if (vold >= 3.5) begin
        if(vnew > vold) begin
          vlimited = min(vnew, (3 * vold) + 2);
        end else begin
          if (vnew < 3.5) begin
            vlimited = max(vnew, 2);
          end else begin
            vlimited = vnew;
          end
        end
      end else begin
        if(vnew > vold) begin
          vlimited = min(vnew, 4);
        end else begin
          vlimited = max(vnew, -0.5);
        end
      end
      DEVlimvds = vlimited;
      if (vlimited!=vnew) begin
        limiting_applied = 1;
      end
    end
  endfunction

  // Analog block
  analog begin

    // Instance field assignments
    if ($param_given(l)) begin
      MOS9l = l;
    end
    if ($param_given(w)) begin
      MOS9w = w;
    end
    if ($param_given(ad)) begin
      MOS9drainArea = ad;
    end
    if ($param_given(as)) begin
      MOS9sourceArea = as;
    end
    if ($param_given(temp)) begin
      MOS9temp = temp+273.15;
      MOS9tempGiven = 1;
    end

    // Model field assignments
    MOS9type = type;
    if ($param_given(vto)) begin
      MOS9vt0 = vto;
    end
    if ($param_given(kp)) begin
      MOS9transconductance = kp;
    end
    if ($param_given(gamma)) begin
      MOS9gamma = gamma;
    end
    if ($param_given(phi)) begin
      MOS9phi = phi;
    end
    if ($param_given(nsub)) begin
      MOS9substrateDoping = nsub;
    end
    if ($param_given(tnom)) begin
      MOS9tnom = tnom+273.15;
      MOS9tnomGiven = 1;
    end

    // Evaluation constants
    lc_gmin = $simparam("gmin", 1e-12);

    // Tag: setup, function: MOS9setup
    if (!$param_given(kp)) begin
      MOS9transconductance = 2e-5;
    end
    if (!$param_given(vto)) begin
      MOS9vt0 = 0;
    end
    if (!$param_given(phi)) begin
      MOS9phi = 0.6;
    end
    if (!$param_given(gamma)) begin
      MOS9gamma = 0;
    end
    if (!$param_given(ad)) begin
      MOS9drainArea = defad;
    end
    MOS9vdsat = 0;
    MOS9von = 0;
    MOS9mode = 1;
    if (!(rd!=0||rsh!=0&&nrd!=0)) begin
      V(d_int, d) <+ 0;
    end
    if (!(rs!=0||rsh!=0&&nrs!=0)) begin
      V(s_int, s) <+ 0;
    end

    // Tag: temp, function: MOS9temp
    if (!MOS9tnomGiven) begin
      MOS9tnom = VACONST_tnom;
    end
    fact1 = MOS9tnom/(27.0+273.15);
    vtnom = MOS9tnom*CONSTKoverQ;
    kt1 = 1.38064852e-23*MOS9tnom;
    egfet1 = 1.16-7.02e-4*MOS9tnom*MOS9tnom/(MOS9tnom+1108);
    arg1 = -egfet1/(kt1+kt1)+1.1150877/(1.38064852e-23*(27.0+273.15+(27.0+273.15)));
    pbfact1 = -2*vtnom*(1.5*ln(fact1)+1.6021766208e-19*arg1);
    nifact = MOS9tnom/300*sqrt(MOS9tnom/300);
    nifact = nifact * (exp(0.5*egfet1*(1.0/300.0-1/MOS9tnom)/CONSTKoverQ));
    ni_temp = 1.45e16*nifact;
    if (MOS9phi<=0.0) begin
      $fatal(0, "Phi is not positive.");
    end
    MOS9oxideCapFactor = 3.9*8.854214871e-12/tox;
    if (!$param_given(kp)) begin
      MOS9transconductance = u0*MOS9oxideCapFactor*1e-4;
    end
    if ($param_given(nsub)) begin
      if (MOS9substrateDoping*1e6>ni_temp) begin
        if (!$param_given(phi)) begin
          MOS9phi = 2*vtnom*ln(MOS9substrateDoping*1e6/ni_temp);
          MOS9phi = ((0.1>MOS9phi) ? (0.1) : (MOS9phi));
        end
        fermis = MOS9type*0.5*MOS9phi;
        wkfng = 3.2;
        if (tpg!=0) begin
          fermig = MOS9type*tpg*0.5*egfet1;
          wkfng = 3.25+0.5*egfet1-fermig;
        end
        wkfngs = wkfng-(3.25+0.5*egfet1+fermis);
        if (!$param_given(gamma)) begin
          MOS9gamma = sqrt(2*(11.7*8.854214871e-12)*1.6021766208e-19*MOS9substrateDoping*1e6)/MOS9oxideCapFactor;
        end
        if (!$param_given(vto)) begin
          vfb = wkfngs-nss*1e4*1.6021766208e-19/MOS9oxideCapFactor;
          MOS9vt0 = vfb+MOS9type*(MOS9gamma*sqrt(MOS9phi)+MOS9phi);
        end else begin
          vfb = MOS9vt0-MOS9type*(MOS9gamma*sqrt(MOS9phi)+MOS9phi);
        end
        MOS9alpha = (11.7*8.854214871e-12+11.7*8.854214871e-12)/(1.6021766208e-19*MOS9substrateDoping*1e6);
        MOS9coeffDepLayWidth = sqrt(MOS9alpha);
      end else begin
        MOS9substrateDoping = 0;
        $fatal(0, "Nsub < Ni ");
      end
    end
    MOS9narrowFactor = delta*0.5*3.1415926535897932384626433832795*(11.7*8.854214871e-12)/MOS9oxideCapFactor;
    if (!MOS9tempGiven) begin
      MOS9temp = $temperature+dtemp;
    end
    vt = MOS9temp*CONSTKoverQ;
    ratio = MOS9temp/MOS9tnom;
    fact2 = MOS9temp/(27.0+273.15);
    kt = MOS9temp*1.38064852e-23;
    egfet = 1.16-7.02e-4*MOS9temp*MOS9temp/(MOS9temp+1108);
    arg = -egfet/(kt+kt)+1.1150877/(1.38064852e-23*(27.0+273.15+(27.0+273.15)));
    pbfact = -2*vt*(1.5*ln(fact2)+1.6021766208e-19*arg);
    if (!$param_given(l)) begin
      MOS9l = defl;
    end
    if (!$param_given(as)) begin
      MOS9sourceArea = defas;
    end
    if (!$param_given(w)) begin
      MOS9w = defw;
    end
    if ($param_given(rd)) begin
      if (rd!=0) begin
        MOS9drainConductance = 1.0/rd;
      end else begin
        MOS9drainConductance = 0;
      end
    end else if ($param_given(rsh)) begin
      if (rsh!=0&&nrd!=0) begin
        MOS9drainConductance = 1.0/(rsh*nrd);
      end else begin
        MOS9drainConductance = 0;
      end
    end else begin
      MOS9drainConductance = 0;
    end
    if ($param_given(rs)) begin
      if (rs!=0) begin
        MOS9sourceConductance = 1.0/rs;
      end else begin
        MOS9sourceConductance = 0;
      end
    end else if ($param_given(rsh)) begin
      if (rsh!=0&&nrs!=0) begin
        MOS9sourceConductance = 1.0/(rsh*nrs);
      end else begin
        MOS9sourceConductance = 0;
      end
    end else begin
      MOS9sourceConductance = 0;
    end
    if (MOS9l-2*ld+xl<1e-6) begin
      $fatal(0, "effective channel length less than zero");
    end
    if (MOS9w-2*wd+xw<1e-6) begin
      $fatal(0, "effective channel width less than zero");
    end
    ratio4 = ratio*sqrt(ratio);
    MOS9tTransconductance = MOS9transconductance/ratio4;
    MOS9tSurfMob = u0/ratio4;
    phio = (MOS9phi-pbfact1)/fact1;
    MOS9tPhi = fact2*phio+pbfact;
    MOS9tVbi = delvto+MOS9vt0-MOS9type*(MOS9gamma*sqrt(MOS9phi))+0.5*(egfet1-egfet)+MOS9type*0.5*(MOS9tPhi-MOS9phi);
    MOS9tVto = MOS9tVbi+MOS9type*MOS9gamma*sqrt(MOS9tPhi);
    MOS9tSatCur = is*exp(-egfet/vt+egfet1/vtnom);
    MOS9tSatCurDens = js*exp(-egfet/vt+egfet1/vtnom);
    pbo = (pb-pbfact1)/fact1;
    gmaold = (pb-pbo)/pbo;
    capfact = 1/(1+mj*(4e-4*(MOS9tnom-(27.0+273.15))-gmaold));
    MOS9tCbd = cbd*capfact;
    MOS9tCbs = cbs*capfact;
    MOS9tCj = cj*capfact;
    capfact = 1/(1+mjsw*(4e-4*(MOS9tnom-(27.0+273.15))-gmaold));
    MOS9tCjsw = cjsw*capfact;
    MOS9tBulkPot = fact2*pbo+pbfact;
    gmanew = (MOS9tBulkPot-pbo)/pbo;
    capfact = 1+mj*(4e-4*(MOS9temp-(27.0+273.15))-gmanew);
    MOS9tCbd = MOS9tCbd * (capfact);
    MOS9tCbs = MOS9tCbs * (capfact);
    MOS9tCj = MOS9tCj * (capfact);
    capfact = 1+mjsw*(4e-4*(MOS9temp-(27.0+273.15))-gmanew);
    MOS9tCjsw = MOS9tCjsw * (capfact);
    MOS9tDepCap = fc*MOS9tBulkPot;
    if (js==0||MOS9drainArea==0||MOS9sourceArea==0) begin
      MOS9drainVcrit = vt*ln(vt/(CONSTroot2*MOS9tSatCur));
      MOS9sourceVcrit = MOS9drainVcrit;
    end else begin
      MOS9drainVcrit = vt*ln(vt/(CONSTroot2*MOS9tSatCurDens*MOS9drainArea));
      MOS9sourceVcrit = vt*ln(vt/(CONSTroot2*MOS9tSatCurDens*MOS9sourceArea));
    end
    if ($param_given(cbd)) begin
      czbd = MOS9tCbd;
    end else if ($param_given(cj)) begin
      czbd = MOS9tCj*MOS9drainArea;
    end else begin
      czbd = 0;
    end
    if ($param_given(cjsw)) begin
      czbdsw = MOS9tCjsw*pd;
    end else begin
      czbdsw = 0;
    end
    arg = 1-fc;
    sarg = exp(-mj*ln(arg));
    sargsw = exp(-mjsw*ln(arg));
    MOS9Cbd = czbd;
    MOS9Cbdsw = czbdsw;
    MOS9f2d = czbd*(1-fc*(1+mj))*sarg/arg+czbdsw*(1-fc*(1+mjsw))*sargsw/arg;
    MOS9f3d = czbd*mj*sarg/arg/MOS9tBulkPot+czbdsw*mjsw*sargsw/arg/MOS9tBulkPot;
    MOS9f4d = czbd*MOS9tBulkPot*(1-arg*sarg)/(1-mj)+czbdsw*MOS9tBulkPot*(1-arg*sargsw)/(1-mjsw)-MOS9f3d/2*(MOS9tDepCap*MOS9tDepCap)-MOS9tDepCap*MOS9f2d;
    if ($param_given(cbs)) begin
      czbs = MOS9tCbs;
    end else if ($param_given(cj)) begin
      czbs = MOS9tCj*MOS9sourceArea;
    end else begin
      czbs = 0;
    end
    if ($param_given(cjsw)) begin
      czbssw = MOS9tCjsw*ps;
    end else begin
      czbssw = 0;
    end
    arg = 1-fc;
    sarg = exp(-mj*ln(arg));
    sargsw = exp(-mjsw*ln(arg));
    MOS9Cbs = czbs;
    MOS9Cbssw = czbssw;
    MOS9f2s = czbs*(1-fc*(1+mj))*sarg/arg+czbssw*(1-fc*(1+mjsw))*sargsw/arg;
    MOS9f3s = czbs*mj*sarg/arg/MOS9tBulkPot+czbssw*mjsw*sargsw/arg/MOS9tBulkPot;
    MOS9f4s = czbs*MOS9tBulkPot*(1-arg*sarg)/(1-mj)+czbssw*MOS9tBulkPot*(1-arg*sargsw)/(1-mjsw)-MOS9f3s/2*(MOS9tDepCap*MOS9tDepCap)-MOS9tDepCap*MOS9f2s;

    // Tag: load, function: MOS9load
    xfact = 0.0;
    capgs = 0.0;
    capgd = 0.0;
    capgb = 0.0;
    load_vt = CONSTKoverQ*MOS9temp;
    EffectiveWidth = MOS9w-2*wd+xw;
    EffectiveLength = MOS9l-2*ld+xl;
    if (MOS9tSatCurDens==0||MOS9drainArea==0||MOS9sourceArea==0) begin
      DrainSatCur = MOS9tSatCur;
      SourceSatCur = MOS9tSatCur;
    end else begin
      DrainSatCur = MOS9tSatCurDens*MOS9drainArea;
      SourceSatCur = MOS9tSatCurDens*MOS9sourceArea;
    end
    GateSourceOverlapCap = cgso*EffectiveWidth;
    GateDrainOverlapCap = cgdo*EffectiveWidth;
    GateBulkOverlapCap = cgbo*EffectiveLength;
    Beta = MOS9tTransconductance*EffectiveWidth/EffectiveLength;
    OxideCap = MOS9oxideCapFactor*EffectiveLength*EffectiveWidth;
    limited = 0;
    /* Previous vgs, vds, vbs, and vbd */
    MOS9vgs = MOS9type * $limit(V(g, s_int), DEVlimitOldGet);
    MOS9vds = MOS9type * $limit(V(d_int, s_int), DEVlimitOldGet);
    MOS9vbs = MOS9type * $limit(V(b, s_int), DEVlimitOldGet);
    MOS9vbd = MOS9type * $limit(V(b, d_int), DEVlimitOldGet);
    
    /* Simplified von value used in limiting, does not require introduction of a hidden state */
    load_von = MOS9type*MOS9tVbi;
    MOS9von = MOS9type*load_von;
    load_vbs = MOS9type*V(b, s_int);
    load_vgs = MOS9type*V(g, s_int);
    load_vds = MOS9type*V(d_int, s_int);
    load_vbd = load_vbs-load_vds;
    vgd = load_vgs-load_vds;
    vgdo = MOS9vgs-MOS9vds;
    load_von = MOS9type*MOS9von;
    if (MOS9vds>=0) begin
      load_vgs = DEVfetlim(load_vgs, MOS9vgs, load_von, limited);
      load_vds = load_vgs-vgd;
      load_vds = DEVlimvds(load_vds, MOS9vds, limited);
      vgd = load_vgs-load_vds;
    end else begin
      vgd = DEVfetlim(vgd, vgdo, load_von, limited);
      load_vds = load_vgs-vgd;
      if (!oldlimit) begin
        load_vds = -DEVlimvds(-load_vds, -MOS9vds, limited);
      end
      load_vgs = vgd+load_vds;
    end
    if (load_vds>=0) begin
      load_vbs = DEVpnjlim(load_vbs, MOS9vbs, load_vt, MOS9sourceVcrit, limited);
      load_vbd = load_vbs-load_vds;
    end else begin
      load_vbd = DEVpnjlim(load_vbd, MOS9vbd, load_vt, MOS9drainVcrit, limited);
      load_vbs = load_vbd+load_vds;
    end
    if (initialize_limiting()) begin
        load_vbs = -1;
        load_vgs = MOS9type * MOS9tVto;
        load_vds = 0;
        load_vbd = load_vbs - load_vds;
    end
    
    load_vgs = MOS9type * $limit(V(g, s_int), DEVlimitNewSet, MOS9type * load_vgs, limited);
    load_vds = MOS9type * $limit(V(d_int, s_int), DEVlimitNewSet, MOS9type * load_vds, limited);
    load_vbs = MOS9type * $limit(V(b, s_int), DEVlimitNewSet, MOS9type * load_vbs, limited);
    load_vbd = MOS9type * $limit(V(b, d_int), DEVlimitNewSet, MOS9type * load_vbd, limited);
    load_vbd = load_vbs-load_vds;
    vgd = load_vgs-load_vds;
    vgb = load_vgs-load_vbs;
    if (load_vbs<=-3*load_vt) begin
      load_arg = 3*load_vt/(load_vbs*CONSTe);
      load_arg = load_arg*load_arg*load_arg;
      MOS9cbs = -SourceSatCur*(1+load_arg)+lc_gmin/$mfactor*load_vbs;
      MOS9gbs = SourceSatCur*3*load_arg/load_vbs+lc_gmin/$mfactor;
    end else begin
      evbs = exp(((709.0<load_vbs/load_vt) ? (709.0) : (load_vbs/load_vt)));
      MOS9gbs = SourceSatCur*evbs/load_vt+lc_gmin/$mfactor;
      MOS9cbs = SourceSatCur*(evbs-1)+lc_gmin/$mfactor*load_vbs;
    end
    if (load_vbd<=-3*load_vt) begin
      load_arg = 3*load_vt/(load_vbd*CONSTe);
      load_arg = load_arg*load_arg*load_arg;
      MOS9cbd = -DrainSatCur*(1+load_arg)+lc_gmin/$mfactor*load_vbd;
      MOS9gbd = DrainSatCur*3*load_arg/load_vbd+lc_gmin/$mfactor;
    end else begin
      evbd = exp(((709.0<load_vbd/load_vt) ? (709.0) : (load_vbd/load_vt)));
      MOS9gbd = DrainSatCur*evbd/load_vt+lc_gmin/$mfactor;
      MOS9cbd = DrainSatCur*(evbd-1)+lc_gmin/$mfactor*load_vbd;
    end
    if (load_vds>=0) begin
      MOS9mode = 1;
    end else begin
      MOS9mode = -1;
    end
    coeff0 = 0.0631353e0;
    coeff1 = 0.8013292e0;
    coeff2 = -0.01110777e0;
    dxndvb = 0.0;
    dvodvb = 0.0;
    dvodvd = 0.0;
    xn = 0.0;
    onvdsc = 0.0;
    fdrain = 0.0;
    dfddvg = 0.0;
    dfddvb = 0.0;
    dfddvd = 0.0;
    gds0 = 0.0;
    load_vdsat = 0.0;
    oneoverxl = 1.0/EffectiveLength;
    load_eta = eta*8.15e-22/(MOS9oxideCapFactor*EffectiveLength*EffectiveLength*EffectiveLength);
    if (((MOS9mode==1) ? (load_vbs) : (load_vbd))<=0.0) begin
      phibs = MOS9tPhi-((MOS9mode==1) ? (load_vbs) : (load_vbd));
      sqphbs = sqrt(phibs);
      dsqdvb = -0.5/sqphbs;
    end else begin
      sqphis = sqrt(MOS9tPhi);
      sqphs3 = MOS9tPhi*sqphis;
      sqphbs = sqphis/(1.0+((MOS9mode==1) ? (load_vbs) : (load_vbd))/(MOS9tPhi+MOS9tPhi));
      phibs = sqphbs*sqphbs;
      dsqdvb = -phibs/(sqphs3+sqphs3);
    end
    if (xj!=0.0&&MOS9coeffDepLayWidth!=0.0) begin
      wps = MOS9coeffDepLayWidth*sqphbs;
      oneoverxj = 1.0/xj;
      xjonxl = xj*oneoverxl;
      djonxj = ld*oneoverxj;
      wponxj = wps*oneoverxj;
      wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj;
      arga = wconxj+djonxj;
      argc = wponxj/(1.0+wponxj);
      argb = sqrt(1.0-argc*argc);
      fshort = 1.0-xjonxl*(arga*argb-djonxj);
      dwpdvb = MOS9coeffDepLayWidth*dsqdvb;
      dadvb = (coeff1+coeff2*(wponxj+wponxj))*dwpdvb*oneoverxj;
      dbdvb = -argc*argc*(1.0-argc)*dwpdvb/(argb*wps);
      dfsdvb = -xjonxl*(dadvb*argb+arga*dbdvb);
    end else begin
      fshort = 1.0;
      dfsdvb = 0.0;
    end
    gammas = MOS9gamma*fshort;
    fbodys = 0.5*gammas/(sqphbs+sqphbs);
    fbody = fbodys+MOS9narrowFactor/EffectiveWidth;
    onfbdy = 1.0/(1.0+fbody);
    dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort;
    qbonco = gammas*sqphbs+MOS9narrowFactor*phibs/EffectiveWidth;
    dqbdvb = gammas*dsqdvb+MOS9gamma*dfsdvb*sqphbs-MOS9narrowFactor/EffectiveWidth;
    vbix = MOS9tVbi*MOS9type-load_eta*(MOS9mode*load_vds);
    vth = vbix+qbonco;
    dvtdvd = -load_eta;
    dvtdvb = dqbdvb;
    load_von = vth;
    if (nfs!=0.0) begin
      csonco = 1.6021766208e-19*nfs*1e4*EffectiveLength*EffectiveWidth/OxideCap;
      cdonco = qbonco/(phibs+phibs);
      xn = 1.0+csonco+cdonco;
      load_von = vth+load_vt*xn;
      dxndvb = dqbdvb/(phibs+phibs)-qbonco*dsqdvb/(phibs*sqphbs);
      dvodvd = dvtdvd;
      dvodvb = dvtdvb+load_vt*dxndvb;
    end else if (((MOS9mode==1) ? (load_vgs) : (vgd))<=load_von) begin
      cdrain = 0.0;
      MOS9gm = 0.0;
      MOS9gds = 0.0;
      MOS9gmbs = 0.0;
      goto_destination = innerline1000;
    end
    if (goto_destination<0) begin
      vgsx = ((((MOS9mode==1) ? (load_vgs) : (vgd))>load_von) ? (((MOS9mode==1) ? (load_vgs) : (vgd))) : (load_von));
      onfg = 1.0+theta*(vgsx-vth);
      fgate = 1.0/onfg;
      us = MOS9tSurfMob*1e-4*fgate;
      dfgdvg = -theta*fgate*fgate;
      dfgdvd = -dfgdvg*dvtdvd;
      dfgdvb = -dfgdvg*dvtdvb;
      load_vdsat = (vgsx-vth)*onfbdy;
      if (vmax<=0.0) begin
        dvsdvg = onfbdy;
        dvsdvd = -dvsdvg*dvtdvd;
        dvsdvb = -dvsdvg*dvtdvb-load_vdsat*dfbdvb*onfbdy;
      end else begin
        vdsc = EffectiveLength*vmax/us;
        onvdsc = 1.0/vdsc;
        arga = (vgsx-vth)*onfbdy;
        argb = sqrt(arga*arga+vdsc*vdsc);
        load_vdsat = arga+vdsc-argb;
        dvsdga = (1.0-arga/argb)*onfbdy;
        dvsdvg = dvsdga-(1.0-vdsc/argb)*vdsc*dfgdvg*onfg;
        dvsdvd = -dvsdvg*dvtdvd;
        dvsdvb = -dvsdvg*dvtdvb-arga*dvsdga*dfbdvb;
      end
      vdsx = ((MOS9mode*load_vds<load_vdsat) ? (MOS9mode*load_vds) : (load_vdsat));
      if (vdsx==0.0) begin
        goto_destination = line900;
      end
      if (goto_destination<0) begin
        cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx;
        dcodvb = -dvtdvb-0.5*dfbdvb*vdsx;
        cdnorm = cdo*vdsx;
        MOS9gm = vdsx;
        if (MOS9mode*load_vds>load_vdsat) begin
          MOS9gds = -dvtdvd*vdsx;
        end else begin
          MOS9gds = vgsx-vth-(1.0+fbody+dvtdvd)*vdsx;
        end
        MOS9gmbs = dcodvb*vdsx;
        cd1 = Beta*cdnorm;
        Beta = Beta*fgate;
        cdrain = Beta*cdnorm;
        MOS9gm = Beta*MOS9gm+dfgdvg*cd1;
        MOS9gds = Beta*MOS9gds+dfgdvd*cd1;
        MOS9gmbs = Beta*MOS9gmbs+dfgdvb*cd1;
        if (vmax>0.0) begin
          fdrain = 1.0/(1.0+vdsx*onvdsc);
          fd2 = fdrain*fdrain;
          arga = fd2*vdsx*onvdsc*onfg;
          dfddvg = -dfgdvg*arga;
          if (MOS9mode*load_vds>load_vdsat) begin
            dfddvd = -dfgdvd*arga;
          end else begin
            dfddvd = -dfgdvd*arga-fd2*onvdsc;
          end
          dfddvb = -dfgdvb*arga;
          MOS9gm = fdrain*MOS9gm+dfddvg*cdrain;
          MOS9gds = fdrain*MOS9gds+dfddvd*cdrain;
          MOS9gmbs = fdrain*MOS9gmbs+dfddvb*cdrain;
          cdrain = fdrain*cdrain;
          Beta = Beta*fdrain;
        end
        if (MOS9mode*load_vds<=load_vdsat) begin
          if (vmax>0.0||MOS9alpha==0.0||badmos3) begin
            goto_destination = line700;
          end else begin
            arga = MOS9mode*load_vds/load_vdsat;
            delxl = sqrt(kappa*MOS9alpha*load_vdsat/8);
            dldvd = 4*delxl*arga*arga*arga/load_vdsat;
            arga = arga * (arga);
            arga = arga * (arga);
            delxl = delxl * (arga);
            ddldvg = 0.0;
            ddldvd = -dldvd;
            ddldvb = 0.0;
            goto_destination = line520;
          end
        end
        if (goto_destination<0) begin
          if (vmax<=0.0) begin
            goto_destination = line510;
          end
          if (goto_destination<0) begin
            if (MOS9alpha==0.0) begin
              goto_destination = line700;
            end
            if (goto_destination<0) begin
              cdsat = cdrain;
              gdsat = cdsat*(1.0-fdrain)*onvdsc;
              gdsat = ((1.0e-12>gdsat) ? (1.0e-12) : (gdsat));
              gdoncd = gdsat/cdsat;
              gdonfd = gdsat/(1.0-fdrain);
              gdonfg = gdsat*onfg;
              dgdvg = gdoncd*MOS9gm-gdonfd*dfddvg+gdonfg*dfgdvg;
              dgdvd = gdoncd*MOS9gds-gdonfd*dfddvd+gdonfg*dfgdvd;
              dgdvb = gdoncd*MOS9gmbs-gdonfd*dfddvb+gdonfg*dfgdvb;
              if (badmos3) begin
                emax = cdsat*oneoverxl/gdsat;
              end else begin
                emax = kappa*cdsat*oneoverxl/gdsat;
              end
              emoncd = emax/cdsat;
              emongd = emax/gdsat;
              demdvg = emoncd*MOS9gm-emongd*dgdvg;
              demdvd = emoncd*MOS9gds-emongd*dgdvd;
              demdvb = emoncd*MOS9gmbs-emongd*dgdvb;
              arga = 0.5*emax*MOS9alpha;
              argc = kappa*MOS9alpha;
              argb = sqrt(arga*arga+argc*(MOS9mode*load_vds-load_vdsat));
              delxl = argb-arga;
              dldvd = argc/(argb+argb);
              dldem = 0.5*(arga/argb-1.0)*MOS9alpha;
              ddldvg = dldem*demdvg;
              ddldvd = dldem*demdvd-dldvd;
              ddldvb = dldem*demdvb;
              goto_destination = line520;
            end
          end
        end
      end
    end
    if (goto_destination<0||goto_destination==line510) begin
      goto_destination = -1;
      if (badmos3) begin
        delxl = sqrt(kappa*(MOS9mode*load_vds-load_vdsat)*MOS9alpha);
        dldvd = 0.5*delxl/(MOS9mode*load_vds-load_vdsat);
      end else begin
        delxl = sqrt(kappa*MOS9alpha*(MOS9mode*load_vds-load_vdsat+load_vdsat/8));
        dldvd = 0.5*delxl/(MOS9mode*load_vds-load_vdsat+load_vdsat/8);
      end
      ddldvg = 0.0;
      ddldvd = -dldvd;
      ddldvb = 0.0;
    end
    if (goto_destination<0||goto_destination==line520) begin
      goto_destination = -1;
      if (delxl>0.5*EffectiveLength) begin
        delxl = EffectiveLength-EffectiveLength*EffectiveLength/(4.0*delxl);
        arga = 4.0*(EffectiveLength-delxl)*(EffectiveLength-delxl)/(EffectiveLength*EffectiveLength);
        ddldvg = ddldvg*arga;
        ddldvd = ddldvd*arga;
        ddldvb = ddldvb*arga;
        dldvd = dldvd*arga;
      end
      dlonxl = delxl*oneoverxl;
      xlfact = 1.0/(1.0-dlonxl);
      cd1 = cdrain;
      cdrain = cdrain*xlfact;
      diddl = cdrain/(EffectiveLength-delxl);
      MOS9gm = MOS9gm*xlfact+diddl*ddldvg;
      MOS9gmbs = MOS9gmbs*xlfact+diddl*ddldvb;
      gds0 = diddl*ddldvd;
      MOS9gm = MOS9gm+gds0*dvsdvg;
      MOS9gmbs = MOS9gmbs+gds0*dvsdvb;
      MOS9gds = MOS9gds*xlfact+diddl*dldvd+gds0*dvsdvd;
    end
    if (goto_destination<0||goto_destination==line700) begin
      goto_destination = -1;
      if (((MOS9mode==1) ? (load_vgs) : (vgd))<load_von) begin
        onxn = 1.0/xn;
        ondvt = onxn/load_vt;
        wfact = exp((((MOS9mode==1) ? (load_vgs) : (vgd))-load_von)*ondvt);
        cdrain = cdrain*wfact;
        gms = MOS9gm*wfact;
        gmw = cdrain*ondvt;
        MOS9gm = gmw;
        if (MOS9mode*load_vds>load_vdsat) begin
          MOS9gm = MOS9gm+gds0*dvsdvg*wfact;
        end
        MOS9gds = MOS9gds*wfact+(gms-gmw)*dvodvd;
        MOS9gmbs = MOS9gmbs*wfact+(gms-gmw)*dvodvb-gmw*(((MOS9mode==1) ? (load_vgs) : (vgd))-load_von)*onxn*dxndvb;
      end
      goto_destination = innerline1000;
    end
    if (goto_destination<0||goto_destination==line900) begin
      goto_destination = -1;
      Beta = Beta*fgate;
      cdrain = 0.0;
      MOS9gm = 0.0;
      MOS9gds = Beta*(vgsx-vth);
      MOS9gmbs = 0.0;
      if (nfs!=0.0&&((MOS9mode==1) ? (load_vgs) : (vgd))<load_von) begin
        MOS9gds = MOS9gds * (exp((((MOS9mode==1) ? (load_vgs) : (vgd))-load_von)/(load_vt*xn)));
      end
    end
    goto_destination = -1;
    MOS9von = MOS9type*load_von;
    MOS9vdsat = MOS9type*load_vdsat;
    MOS9dcCurrent = MOS9mode*cdrain-MOS9cbd;
    MOS9cd = MOS9dcCurrent;
    if (OxideCap==0) begin
        meyer_scale = 0;
        meyer_unscale = 1;
    end else begin
        meyer_scale = OxideCap;
        meyer_unscale = OxideCap;
    end
    if (MOS9Cbs!=0||MOS9Cbssw!=0) begin
      if (load_vbs<MOS9tDepCap) begin
        load_arg = 1-load_vbs/MOS9tBulkPot;
        if (mj==mjsw) begin
          if (mj==0.5) begin
            load_sargsw = 1/sqrt(load_arg);
            load_sarg = load_sargsw;
          end else begin
            load_sargsw = exp(-mj*ln(load_arg));
            load_sarg = load_sargsw;
          end
        end else begin
          if (mj==0.5) begin
            load_sarg = 1/sqrt(load_arg);
          end else begin
            load_sarg = exp(-mj*ln(load_arg));
          end
          if (mjsw==0.5) begin
            load_sargsw = 1/sqrt(load_arg);
          end else begin
            load_sargsw = exp(-mjsw*ln(load_arg));
          end
        end
        MOS9qbs = MOS9tBulkPot*(MOS9Cbs*(1-load_arg*load_sarg)/(1-mj)+MOS9Cbssw*(1-load_arg*load_sargsw)/(1-mjsw));
        MOS9capbs = MOS9Cbs*load_sarg+MOS9Cbssw*load_sargsw;
      end else begin
        MOS9qbs = MOS9f4s+load_vbs*(MOS9f2s+load_vbs*(MOS9f3s/2));
        MOS9capbs = MOS9f2s+MOS9f3s*load_vbs;
      end
    end else begin
      MOS9qbs = 0;
      MOS9capbs = 0;
    end
    if (MOS9Cbd!=0||MOS9Cbdsw!=0) begin
      if (load_vbd<MOS9tDepCap) begin
        load_arg = 1-load_vbd/MOS9tBulkPot;
        if (mj==0.5&&mjsw==0.5) begin
          load_sargsw = 1/sqrt(load_arg);
          load_sarg = load_sargsw;
        end else begin
          if (mj==0.5) begin
            load_sarg = 1/sqrt(load_arg);
          end else begin
            load_sarg = exp(-mj*ln(load_arg));
          end
          if (mjsw==0.5) begin
            load_sargsw = 1/sqrt(load_arg);
          end else begin
            load_sargsw = exp(-mjsw*ln(load_arg));
          end
        end
        MOS9qbd = MOS9tBulkPot*(MOS9Cbd*(1-load_arg*load_sarg)/(1-mj)+MOS9Cbdsw*(1-load_arg*load_sargsw)/(1-mjsw));
        MOS9capbd = MOS9Cbd*load_sarg+MOS9Cbdsw*load_sargsw;
      end else begin
        MOS9qbd = MOS9f4d+load_vbd*(MOS9f2d+load_vbd*MOS9f3d/2);
        MOS9capbd = MOS9f2d+load_vbd*MOS9f3d;
      end
    end else begin
      MOS9qbd = 0;
      MOS9capbd = 0;
    end
    geq = 0;
    MOS9cqbd = ddt(MOS9qbd);
    ceq = MOS9cqbd;
    MOS9gbd = MOS9gbd + (geq);
    MOS9cbd = MOS9cbd + (MOS9cqbd);
    MOS9cd = MOS9cd - (MOS9cqbd);
    geq = 0;
    MOS9cqbs = ddt(MOS9qbs);
    ceq = MOS9cqbs;
    MOS9gbs = MOS9gbs + (geq);
    MOS9cbs = MOS9cbs + (MOS9cqbs);
    MOS9vbs = load_vbs;
    MOS9vbd = load_vbd;
    MOS9vgs = load_vgs;
    MOS9vds = load_vds;
    if (MOS9mode>0) begin
      DEVqmeyer(load_vgs, vgd, vgb, load_von, load_vdsat, MOS9capgs, MOS9capgd, MOS9capgb, MOS9tPhi, OxideCap);
    end else begin
      DEVqmeyer(vgd, load_vgs, vgb, load_von, load_vdsat, MOS9capgd, MOS9capgs, MOS9capgb, MOS9tPhi, OxideCap);
    end
    capgs = MOS9capgs+MOS9capgs+GateSourceOverlapCap;
    capgd = MOS9capgd+MOS9capgd+GateDrainOverlapCap;
    capgb = MOS9capgb+MOS9capgb+GateBulkOverlapCap;
    if (capgs==0) begin
      MOS9cqgs = 0;
    end
    if (capgd==0) begin
      MOS9cqgd = 0;
    end
    if (capgb==0) begin
      MOS9cqgb = 0;
    end
    gcgs = 0;
    ceqgs = capgs*(ddt(meyer_scale*load_vgs)/meyer_unscale);
    MOS9cqgs = ceqgs;
    gcgd = 0;
    ceqgd = capgd*(ddt(meyer_scale*vgd)/meyer_unscale);
    MOS9cqgd = ceqgd;
    gcgb = 0;
    ceqgb = capgb*(ddt(meyer_scale*vgb)/meyer_unscale);
    MOS9cqgb = ceqgb;
    ceqbs = MOS9type*(MOS9cbs-MOS9gbs*load_vbs);
    ceqbd = MOS9type*(MOS9cbd-MOS9gbd*load_vbd);
    if (MOS9mode>=0) begin
      xnrm = 1;
      xrev = 0;
      cdreq = MOS9type*cdrain;
    end else begin
      xnrm = 0;
      xrev = 1;
      cdreq = -MOS9type*cdrain;
    end
    
    // Residuals
    I(d) <+ MOS9drainConductance*V(d, d_int);
    I(g) <+ gcgb*V(g, b)+gcgd*V(g, d_int)+gcgs*V(g, s_int)+MOS9type*(ceqgs+ceqgb+ceqgd);
    I(s) <+ MOS9sourceConductance*V(s, s_int);
    I(b) <+ MOS9gbd*V(b, d_int)+MOS9gbs*V(b, s_int)+gcgb*V(b, g)+(ceqbs+ceqbd-MOS9type*ceqgb);
    I(d_int) <+ MOS9drainConductance*V(d_int, d)+MOS9gbd*V(d_int, b)+gcgd*V(d_int, g)+-(ceqbd-cdreq+MOS9type*ceqgd);
    I(s_int) <+ MOS9gbs*V(s_int, b)+MOS9sourceConductance*V(s_int, s)+gcgs*V(s_int, g)+-(cdreq+ceqbs+MOS9type*ceqgs);

    // Tag: noise, function: MOS9noise
    I(d_int, d) <+ white_noise(4*(VACONSTboltz*($temperature*MOS9drainConductance)), "rd");
    I(s_int, s) <+ white_noise(4*(VACONSTboltz*($temperature*MOS9sourceConductance)), "rs");
    I(d_int, s_int) <+ white_noise(4*(VACONSTboltz*($temperature*(2.0/3.0*abs(MOS9gm)))), "id");
    flicker_psd = ((MOS9cd>=0) ? (1) : (-1))*(kf*exp(af*ln(((abs(MOS9cd)>1E-38) ? (abs(MOS9cd)) : (1E-38))))/((MOS9w-2*wd)*(MOS9l-2*ld)*MOS9oxideCapFactor*MOS9oxideCapFactor));
    flicker_exp = 1;
    I(d_int, s_int) <+ flicker_noise(flicker_psd, flicker_exp, "flicker");

    // Instance output variable computation
    i_d = MOS9cd;
    ibd = MOS9cbd;
    ibs = MOS9cbs;
    i_s = -MOS9cd;
    i_s = i_s - (MOS9cbd+MOS9cbs-MOS9cqgb);
    i_s = i_s - (MOS9cqgb+MOS9cqgd+MOS9cqgs);
    i_g = MOS9cqgb+MOS9cqgd+MOS9cqgs;
    i_b = MOS9cbd+MOS9cbs-MOS9cqgb;
    vgs = MOS9vgs;
    vds = MOS9vds;
    vbs = MOS9vbs;
    vbd = MOS9vbd;
    von = MOS9von;
    vdsat = MOS9vdsat;
    sourcevcrit = MOS9sourceVcrit;
    drainvcrit = MOS9drainVcrit;
    sourceconductance = MOS9sourceConductance;
    drainconductance = MOS9drainConductance;
    gm = MOS9gm;
    gds = MOS9gds;
    gmb = MOS9gmbs;
    gbd = MOS9gbd;
    gbs = MOS9gbs;
    c_bd = MOS9capbd;
    c_bs = MOS9capbs;
    cgs = 2*MOS9capgs;
    cgs = cgs + (cgso*(MOS9w+xw-2*wd));
    cgd = 2*MOS9capgd;
    cgd = cgd + (cgdo*(MOS9w+xw-2*wd));
    cgb = 2*MOS9capgb;
    cgb = cgb + (cgbo*(MOS9l+xl-2*ld));
    cqgs = MOS9cqgs;
    cqgd = MOS9cqgd;
    cqgb = MOS9cqgb;
    cqbd = MOS9cqbd;
    cqbs = MOS9cqbs;
    cbd0 = MOS9Cbd;
    cbdsw0 = MOS9Cbdsw;
    cbs0 = MOS9Cbs;
    cbssw0 = MOS9Cbssw;
    qbs = MOS9qbs;
    qbd = MOS9qbd;
    p = MOS9cd*V(d);
    p = p + ((MOS9cbd+MOS9cbs-MOS9cqgb)*V(b));
    p = p + ((MOS9cqgb+MOS9cqgd+MOS9cqgs)*V(g));
    instask_temp = -MOS9cd;
    instask_temp = instask_temp - (MOS9cbd+MOS9cbs);
    instask_temp = instask_temp - (MOS9cqgb+MOS9cqgd+MOS9cqgs);
    p = p + (instask_temp*V(s));

    // Model output variable computation

  end
endmodule
