home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk1.iso / altsrc / articles / 10852 < prev    next >
Text File  |  1994-07-11  |  61KB  |  1,993 lines

  1. Newsgroups: alt.sources
  2. Path: wupost!crcnis1.unl.edu!news.mid.net!newsfeed.ksu.ksu.edu!moe.ksu.ksu.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!cs.utexas.edu!convex!news.duke.edu!eff!news.kei.com!travelers.mail.cornell.edu!newstand.syr.edu!galileo.cc.rochester.edu!ee.rochester.edu!atd.rochester.ny.us!al
  3. From: al@atd.rochester.ny.us (Al Davis)
  4. Subject: ACS (Al's Circuit Simulator) version 0.14 part14/21
  5. Message-ID: <1994Jul6.032705.13506@atd.rochester.ny.us>
  6. Organization: Huh?
  7. Date: Wed, 6 Jul 1994 03:27:05 GMT
  8. Lines: 1983
  9.  
  10. Archive-name: acs-0.14/part14
  11. Submitted-by: atd@cs.rit.edu
  12. Supercedes: acs-0.13
  13. Environment: UNIX, MS-DOS
  14.  
  15. #! /bin/sh
  16. # This is a shell archive, meaning:
  17. # 1. Remove everything above the #! /bin/sh line.
  18. # 2. Save the resulting text in a file.
  19. # 3. Execute the file with /bin/sh (not csh) to create the files:
  20. #    src/d_mos1.c
  21. #    src/d_mos2.c
  22. #    src/d_mos3.c
  23. #    src/d_mosc.c
  24. #    src/d_res.c
  25. #    src/d_subckt.c
  26. #    src/d_trln.c
  27. #    src/d_vccs.c
  28. #    src/d_vcvs.c
  29. #    src/d_vs.c
  30. # This archive created: Tue Jul  5 15:24:08 1994
  31. export PATH; PATH=/bin:$PATH
  32. if test -f 'src/d_mos1.c'
  33. then
  34.     echo shar: will not over-write existing file "'src/d_mos1.c'"
  35. else
  36. cat << \SHAR_EOF > 'src/d_mos1.c'
  37. /* d_mos1.c  93.12.19
  38.  * mos model equations: spice level 1 equivalent
  39.  */
  40. #include "ecah.h"
  41. #include "branch.h"
  42. #include "d_mos.h"
  43. #include "error.h"
  44. #include "io.h"
  45. #include "options.h"
  46. #include "declare.h"
  47. /*--------------------------------------------------------------------------*/
  48.     void    eval_mos1(branch_t*);
  49. /*--------------------------------------------------------------------------*/
  50. extern const struct ioctrl io;
  51. extern const struct options opt;
  52. /*--------------------------------------------------------------------------*/
  53. void eval_mos1(branch_t *brh)
  54. {
  55.  static struct mos *x;
  56.  static struct mmod *m;
  57.  double sarg;
  58.  double dsarg_dvbs;
  59.  
  60.  x = (struct mos*)brh->x;
  61.  m = x->m;
  62.  
  63.  if (x->vbs <= 0.){
  64.     sarg = sqrt(m->phi - x->vbs);
  65.     dsarg_dvbs = -.5 / sarg;
  66.     x->sbfwd = NO;
  67.  }else{
  68.     double sphi3 = pow(m->phi, 1.5);
  69.     sarg = sqrt(m->phi) / (1. + .5 * x->vbs / m->phi);
  70.     dsarg_dvbs = -.5 * sarg * sarg / sphi3;    /* is wrong!! */
  71.     x->sbfwd = YES;
  72.     if (!io.suppresserrors){
  73.        error((sarg <= 0.) ? bPICKY : bTRACE,
  74.           "%s: source fwd biased.  vbs=%g\n", printlabel(brh,NO), x->vbs);
  75.     }
  76.  }
  77.  
  78.  x->von = m->vto + m->gamma * (sarg - sqrt(m->phi));
  79.  x->vgst = x->vdsat = x->vgs - x->von;
  80.  if (x->vdsat < 0.)
  81.     x->vdsat = 0.;
  82.  x->cutoff = (x->vgst < 0.);
  83.  x->saturated = (x->vds > x->vdsat);
  84.  
  85.  if (x->cutoff){
  86.     x->gm = x->ids = x->gmb = 0.;
  87.     x->gds = opt.gmin;
  88.  }else if (x->saturated){
  89.     x->gm  = x->beta * x->vgst * (1. + m->lambda * x->vds);
  90.     x->ids = x->gm * (.5 * x->vgst);
  91.     x->gds = .5 * x->beta * m->lambda * x->vgst * x->vgst;
  92.     x->gmb = - x->gm * m->gamma * dsarg_dvbs;
  93.  }else{ /* linear */
  94.     x->gm  = x->beta * x->vds * (1. + m->lambda * x->vds);
  95.     x->ids = x->gm * (x->vgst - .5*x->vds);
  96.     x->gds = x->beta * 
  97.         ((x->vgst - x->vds) + m->lambda * x->vds * (2.*x->vgst - 1.5*x->vds));
  98.     x->gmb = - x->gm * m->gamma * dsarg_dvbs;
  99.  }
  100. }
  101. /*--------------------------------------------------------------------------*/
  102. /*--------------------------------------------------------------------------*/
  103. SHAR_EOF
  104. fi # end of overwriting check
  105. if test -f 'src/d_mos2.c'
  106. then
  107.     echo shar: will not over-write existing file "'src/d_mos2.c'"
  108. else
  109. cat << \SHAR_EOF > 'src/d_mos2.c'
  110. /* d_mos2.c  94.04.28
  111.  * Copyright 1983-1992   Albert Davis
  112.  * mos model equations: spice level 2 equivalent
  113.  */
  114. #include "ecah.h"
  115. #include "branch.h"
  116. #include "d_mos.h"
  117. #include "error.h"
  118. #include "io.h"
  119. #include "options.h"
  120. #include "declare.h"
  121. /*--------------------------------------------------------------------------*/
  122.     void    eval_mos2(branch_t*);
  123. /*--------------------------------------------------------------------------*/
  124. #define short_channel    (m->xj != NOT_INPUT  &&  m->xj > 0.)
  125. #define do_subthreshold    (m->nfs != 0.)
  126.  
  127. extern const struct ioctrl io;
  128. extern const struct options opt;
  129. extern const double temp;
  130. /*--------------------------------------------------------------------------*/
  131. void eval_mos2(branch_t *brh)
  132. {
  133. static struct mos *x;
  134. static struct mmod *m;
  135.  double sarg, dsarg_dvbs/*ds*/;
  136.  double bargx;
  137.  double gamma_s/*mb*/, dgamma_s_dvds/*ds*/, dgamma_s_dvbs/*mb*/;
  138.  double beta;
  139.  double body;
  140.  double dvdsat_dvgs = 0./*m*/;
  141.  double dvdsat_dvbs = 0./*mb*/;
  142.  double vgsx;
  143.  double vdsx;
  144.  double ufact;
  145.  double dudvgs/*m*/, dudvds/*ds*/, dudvbs/*mb*/;
  146.  double clfact;
  147.  double dldvgs/*m*/, dldvds/*ds*/, dldvbs/*mb*/;
  148.  double dodvbs/*mb*/;
  149.  double xn = 0.;
  150.  double vtxn = 0.;
  151.  double expg;
  152.  double dxndvb =0./*mb*/;    /* subthreshold only */
  153.  double ids_on, didvds;
  154.  double vt/*ds*/;
  155.  double v_phi_d, v_phi_s, v_phi_ds;
  156.  double d2sdb2;
  157.  double barg, dbarg_dvbs, d2bdb2;
  158.  double bsarg, dbsarg_dvbs;
  159.  double vbdsat;
  160.  double dgddb2;
  161.  double vc, vbin, vc_eta;
  162.  double bodys;
  163.  double lambda;
  164.  double vbd, vbs;
  165.  double ueff = 0.;
  166.  
  167.  int use_vmax;
  168.  
  169.  x = (struct mos*)brh->x;
  170.  m = x->m;
  171.   
  172.  use_vmax = m->vmax != NOT_INPUT;
  173.  vt = (K/Q) * temp;
  174.  
  175.  vbs = x->vbs;
  176.  v_phi_s = m->phi - vbs;
  177.  if (vbs <= 0.){
  178.     sarg = sqrt(v_phi_s);
  179.     dsarg_dvbs = -.5 / sarg;
  180.     d2sdb2 = .5 * dsarg_dvbs / v_phi_s;
  181.     x->sbfwd = NO;
  182.  }else{
  183.     double sphi3 = pow(m->phi, 1.5);
  184.     if (opt.mosflags & 0001  &&  vbs > m->phi){
  185.        error(bDANGER,"%s: vbs(%g) > phi(%g)\n", printlabel(brh,0),vbs,m->phi);
  186.        vbs = m->phi;
  187.        v_phi_s = 0.;
  188.     }
  189.     sarg = sqrt(m->phi) / (1. + .5 * vbs / m->phi);
  190.     dsarg_dvbs = -.5 * sarg * sarg / sphi3;
  191.     d2sdb2 = -dsarg_dvbs * sarg / sphi3;
  192.     x->sbfwd = YES;
  193.     if (!io.suppresserrors){
  194.        error((x->vbs > m->phi) ? bPICKY : bTRACE,
  195.           "%s: source fwd biased. vbs=%g\n", printlabel(brh,NO), x->vbs);
  196.     }
  197.  }
  198.  
  199.  if (opt.mosflags & 0004){
  200.     vbd = vbs - x->vds;
  201.  }else{
  202.     vbd = x->vbs - x->vds;
  203.  }
  204.  v_phi_d = m->phi - vbd;
  205.  if (vbd <= 0.){
  206.     barg = sqrt(v_phi_d);
  207.     dbarg_dvbs = -.5 / barg;
  208.     d2bdb2 = .5 * dbarg_dvbs / v_phi_d;
  209.     x->dbfwd = NO;
  210.  }else{
  211.     double sphi3 = pow(m->phi, 1.5);
  212.     if (opt.mosflags & 0002  &&  vbd > m->phi){
  213.        error(bDANGER,"%s: vbd(%g) > phi(%g)\n", printlabel(brh,0),vbd,m->phi);
  214.        vbd = m->phi;
  215.        v_phi_d = 0.;
  216.     }
  217.     barg = sqrt(m->phi) / (1. + .5 * vbd / m->phi);
  218.     dbarg_dvbs = -.5 * barg * barg / sphi3;
  219.     d2bdb2 = -dbarg_dvbs * barg / sphi3;
  220.     x->dbfwd = YES;
  221.     if (!io.suppresserrors){
  222.        error((vbd > m->phi) ? bPICKY : bTRACE,
  223.           "%s: drain fwd biased. vbd=%g\n",printlabel(brh,NO), x->vbs-x->vds);
  224.     }
  225.  }
  226.  
  227.  if (short_channel){
  228.     double wd, ws;
  229.     double alpha_d, alpha_s;
  230.     double dalpha_d_dvds, dalpha_d_dvbs;
  231.     double dalpha_s_dvbs;
  232.     double argxs, argxd;
  233.     double args, argd;
  234.     double dasdb2, daddb2;
  235.  
  236.     wd = m->xd * barg;
  237.     argxd = 1. + 2.*wd/m->xj;
  238.     argd = sqrt(argxd);
  239.     alpha_d = x->relxj * (argd - 1.);
  240.     dalpha_d_dvds = m->xd / (4. * x->le * argd * barg);
  241.     dalpha_d_dvbs = -dalpha_d_dvds;
  242.     
  243.     ws = m->xd * sarg;
  244.     argxs = 1. + 2.*ws/m->xj;
  245.     args = sqrt(argxs);
  246.     alpha_s = x->relxj * (args - 1.);
  247.     dalpha_s_dvbs = -m->xd / (4. * x->le * args * sarg);
  248.     
  249.     gamma_s = m->gamma * (1. - alpha_s - alpha_d);
  250.     dgamma_s_dvds = -m->gamma *  dalpha_d_dvds;
  251.     dgamma_s_dvbs = -m->gamma * (dalpha_d_dvbs + dalpha_s_dvbs);
  252.  
  253.     dasdb2 = -m->xd*(d2sdb2 + dsarg_dvbs*dsarg_dvbs*m->xd / (m->xj*argxs))
  254.                     / (x->le*args);
  255.     daddb2 = -m->xd*(d2bdb2 + dbarg_dvbs*dbarg_dvbs*m->xd / (m->xj*argxd))
  256.                     / (x->le*argd);
  257.     dgddb2 = -.5 * m->gamma * (dasdb2 + daddb2);
  258.  
  259.     if (gamma_s <= 0. && m->gamma > 0. && !io.suppresserrors){
  260.        error(bWARNING, "%s: gamma is negative\n", printlabel(brh,NO));
  261.        error(bTRACE  , "+   gamma_s=%g, alpha_s=%g, alpha_d=%g\n",
  262.                        gamma_s,    alpha_s,    alpha_d);
  263.     }
  264.  }else{
  265.     gamma_s = m->gamma;
  266.     dgamma_s_dvds = dgamma_s_dvbs = 0.;
  267.     dgddb2 = 0.;
  268.  }
  269.  
  270.  
  271.  vbin = m->vbi + x->eta_1 * v_phi_s;
  272.  x->von = vbin + gamma_s * sarg;
  273.  
  274.  dodvbs = -x->eta_1 + dgamma_s_dvbs * sarg + gamma_s * dsarg_dvbs;
  275.  if (do_subthreshold){
  276.     double cdonco;
  277.     dxndvb = 2. * dgamma_s_dvbs * dsarg_dvbs
  278.                    + gamma_s * d2sdb2 + dgddb2 * sarg;
  279.     dodvbs += vt * dxndvb;
  280.     cdonco = - (gamma_s * dsarg_dvbs + dgamma_s_dvbs * sarg) + x->eta_1;
  281.     xn = 1. + m->cfsox + cdonco;
  282.     vtxn = vt * xn;
  283.     x->von += vtxn;
  284.     x->subthreshold = (x->vgs < x->von);
  285.     x->cutoff = NO;
  286.  }else if (x->vgs < x->von){
  287.     x->cutoff = YES;
  288.     x->subthreshold = NO;
  289.     x->ids = 0.;
  290.     x->gm = 0.;
  291.     if (opt.mosflags == 0100){
  292.        x->gds = opt.gmin;
  293.     }else{
  294.        x->gds = 0.;
  295.     }
  296.     x->gmb = 0.;
  297.     x->vgst = x->vgs - x->von;
  298.     return;
  299.  }else{
  300.     x->cutoff = x->subthreshold = NO;
  301.  }
  302.  
  303.  vgsx = (x->subthreshold) ? x->von : x->vgs;
  304.  vc = vgsx - vbin;
  305.  vc_eta = vc / x->eta;
  306.  x->vgst = x->vgs - x->von;
  307.  
  308.  if (m->uexp != NOT_INPUT  &&  x->vgst > m->vbp){
  309.     ufact = pow(m->vbp/x->vgst, m->uexp);
  310.     dudvgs = -ufact * m->uexp / x->vgst;
  311.     dudvds = 0.;    /* wrong, but as per spice2 */
  312.     dudvbs = dodvbs * ufact * m->uexp / x->vgst;
  313.  }else{
  314.     ufact = 1.;
  315.     dudvgs = dudvds = dudvbs = 0.;
  316.  }
  317.  
  318.  if (use_vmax){
  319.     double sarg3, gammad;
  320.     double v1, v2, xv, a1, b1, c1, d1;
  321.     double a, b, c, r, s, r3, s2, p, p0, p2, y3;
  322.     double xvalid = 0.;
  323.     double x4[8];
  324.     int iknt, j;
  325.     int root_count;
  326.     sarg3 = sarg*sarg*sarg;
  327.     gammad = gamma_s / x->eta;
  328.     ueff = m->uo * ufact;
  329.     v1 = vc_eta + v_phi_s;
  330.     v2 = v_phi_s;
  331.     xv = m->vmax * x->le / ueff;
  332.     a1 = gammad * (4./3.);
  333.     b1 = -2. * (v1+xv);
  334.     c1 = -2. * gammad * xv;                /* end of scope */
  335.     d1 = 2.*v1*(v2+xv) - v2*v2 - (4./3.)*gammad*sarg3;     /* xv, v1, v2, sarg3 */
  336.     a = -b1;
  337.     b = a1 * c1 - 4. * d1;
  338.     c = -d1 * (a1*a1 - 4.*b1) - c1*c1;
  339.     r = -a*a / 3. + b;
  340.     s = 2. * a*a*a / 27. - a*b / 3. + c;        /* b, c */
  341.     r3 = r*r*r;                        /* r */
  342.     s2 = s*s;
  343.     p = s2 / 4. + r3 / 27.;                /* r3 */
  344.     p0 = fabs(p);
  345.     p2 = sqrt(p0);
  346.     if (p < 0.){                    /* p */
  347.        double ro, fi;
  348.        ro = pow((s2 / 4. + p0), (1./6.));        /* s2, p0 */
  349.        fi = atan(-2. * p2 / s);
  350.        y3 = 2. * ro * cos(fi/3.) - a / 3.;
  351.     }else{
  352.        double p3, p4;
  353.        p3 = pow((fabs(-s/2.+p2)), (1./3.));
  354.        p4 = pow((fabs(-s/2.-p2)), (1./3.));        /* s, p2 */
  355.        y3 = p3 + p4 - a / 3.;                /* a */
  356.     }
  357.  
  358.     iknt = 0;
  359.     if (a1*a1 / 4. - b1 + y3  < 0.  &&  y3*y3 / 4. - d1  < 0.){
  360.        error(bWARNING,
  361.           "%s: internal error: a3,b4, a1=%g, b1=%g, y3=%g, d1=%g\n",
  362.            printlabel(brh,NO),          a1,    b1,    y3,    d1);
  363.     }else{
  364.        double a3, b3;
  365.        int i;
  366.        a3 = sqrt(a1*a1 / 4. - b1 + y3);
  367.        b3 = sqrt(y3*y3 / 4. - d1);
  368.        for (i = 0;   i < 4;   i++){
  369.           double delta4;
  370.           double a4, b4;
  371.           static const double sig1[4] = {1., -1., 1., -1.};
  372.           static const double sig2[4] = {1., 1., -1., -1.};
  373.           a4 = a1 / 2. + sig1[i] * a3;
  374.           b4 = y3 / 2. + sig2[i] * b3;            /* y3 */
  375.           delta4 = a4*a4 / 4. - b4;
  376.           if (delta4 >= 0.){
  377.              x4[iknt++] = - a4 / 2. + sqrt(delta4);
  378.              x4[iknt++] = - a4 / 2. - sqrt(delta4);    /* i */
  379.           }
  380.        }
  381.     }
  382.  
  383.     root_count = 0;
  384.     for (j = 0;   j < iknt;   j++){            /* iknt */
  385.        if (x4[j] > 0.){
  386.           double poly4;
  387.           poly4 =      x4[j]*x4[j]*x4[j]*x4[j]    /* ~= 0, used as check    */
  388.         + a1 * x4[j]*x4[j]*x4[j]    /* roundoff error not    */
  389.         + b1 * x4[j]*x4[j]        /* propagated, so ok    */
  390.         + c1 * x4[j]
  391.         + d1;                    /* a1, b1, c1, d1 */
  392.           if (fabs(poly4) <= 1e-6){
  393.              root_count++;
  394.              if (root_count <= 1)    /* xvalid = min(x4[j]) */
  395.                 xvalid=x4[j];
  396.              if (x4[j] <= xvalid)
  397.                 xvalid=x4[j];                /* x4[], j */
  398.       }else{
  399.       }
  400.        }
  401.     }
  402.     if (root_count <= 0){                /* root_count */
  403.        if (!io.suppresserrors)
  404.           error(bWARNING, "%s: Baum's theory rejected\n", printlabel(brh,NO));
  405.        use_vmax = NO;
  406.     }else{
  407.        x->vdsat = xvalid*xvalid - v_phi_s;
  408.     }
  409.  }
  410.  
  411.  if (!use_vmax){
  412.     if (gamma_s > 0.){
  413.        double argv;
  414.        argv = vc_eta + v_phi_s;
  415.        if (argv > 0.){
  416.           double gammad, gammd2, arg;
  417.           gammad = gamma_s / x->eta;
  418.           gammd2 = gammad * gammad;
  419.           arg = sqrt(1. + 4. * argv / gammd2);
  420.           x->vdsat = vc_eta  +  gammd2 * (1.-arg) / 2.;
  421.           dvdsat_dvgs = (1. - 1./arg) / x->eta;
  422.           dvdsat_dvbs = (gammad * (1.-arg) + 2.*argv / (gammad*arg))
  423.               / x->eta * dgamma_s_dvbs
  424.             + 1./arg + x->eta_1 * dvdsat_dvgs;
  425.        }else{
  426.           x->vdsat = 0.;
  427.           dvdsat_dvgs = dvdsat_dvbs = 0.;
  428.       if (!io.suppresserrors){
  429.              error(bWARNING, "%s: argv is negative\n", printlabel(brh,NO));
  430.          error(bTRACE  , "+   vc=%g, argv=%g, vdsat=%g\n",
  431.                   vc,    argv,    x->vdsat);
  432.          error(bTRACE  , "+   vds=%g, vgs=%g, vbs=%g\n",
  433.                   x->vds, x->vgs, x->vbs);
  434.       }
  435.        }
  436.     }else{
  437.        x->vdsat = vc_eta;
  438.        dvdsat_dvgs = 1.;
  439.        dvdsat_dvbs = 0.;
  440.     }
  441.  }
  442.  
  443.  if (x->vdsat < 0.){
  444.     error(bWARNING, "%s: calculated vdsat (%g) < 0.  using vdsat = 0.\n",
  445.             printlabel(brh,NO), x->vdsat);
  446.     x->vdsat = 0.;
  447.  }
  448.  
  449.  vbdsat = vbs - x->vdsat;
  450.  v_phi_ds = m->phi - vbdsat;
  451.  if (vbdsat <= 0.){
  452.     bsarg = sqrt(v_phi_ds);
  453.     dbsarg_dvbs = -.5 / bsarg;
  454.  }else{
  455.     double sphi3 = pow(m->phi, 1.5);
  456.     bsarg = sqrt(m->phi) / (1. + .5 * vbdsat / m->phi);
  457.     dbsarg_dvbs = -.5 * bsarg * bsarg / sphi3;
  458.  }
  459.  bodys = bsarg*bsarg*bsarg - sarg*sarg*sarg;
  460.  
  461.  if (use_vmax){
  462.     double argv, vqchan, dqdsat, vl, dfunds, dfundg, dfundb, gdbdvs;
  463.     gdbdvs = 2. * gamma_s * (bsarg*bsarg*dbsarg_dvbs - sarg*sarg*dsarg_dvbs);
  464.     argv = vc_eta - x->vdsat;
  465.     vqchan = argv - gamma_s * bsarg;
  466.     dqdsat = -1. + gamma_s * dbsarg_dvbs;
  467.     vl = m->vmax * x->le;
  468.     dfunds = vl * dqdsat - ueff * vqchan;
  469.     dfundg = (vl - ueff * x->vdsat) / x->eta;
  470.     dfundb = -vl * (1. + dqdsat - x->eta_1 / x->eta)
  471.                + ueff * (gdbdvs - dgamma_s_dvbs * bodys / 1.5) / x->eta;
  472.     dvdsat_dvgs = -dfundg / dfunds;
  473.     dvdsat_dvbs = -dfundb / dfunds;
  474.  }
  475.  
  476.  if (m->lambda == NOT_INPUT){
  477.     if (x->vds != 0.){
  478.        double dldsat;
  479.        if (use_vmax){
  480.       double xdv, xlv, argv, xls;
  481.           xdv = m->xd / sqrt(m->neff);
  482.           xlv = m->vmax * xdv / (2. * ueff);
  483.           argv = x->vds - x->vdsat;
  484.           if (argv < 0.)
  485.              argv = 0.;
  486.           xls = sqrt(xlv*xlv + argv);
  487.           lambda = (xls-xlv) * xdv / (x->le * x->vds);
  488.           dldsat = xdv / (2. * xls * x->le);
  489.        }else{
  490.           double argv, sargv, dl;
  491.           argv = (x->vds - x->vdsat) / 4.;
  492.       sargv = sqrt(1. + argv*argv);
  493.       if (argv + sargv >= 0.){
  494.          dl = m->xd * sqrt(argv + sargv);
  495.              lambda = dl / (x->le * x->vds);
  496.              dldsat = lambda * x->vds / (8. * sargv);
  497.              }else{
  498.          lambda = 0.;
  499.          dldsat = 0.;
  500.          error(bWARNING, "%s: internal error: vds(%g) < vdsat(%g)\n",
  501.                        printlabel(brh,NO), x->vds,   x->vdsat);
  502.       }
  503.        }
  504.        dldvgs =  dvdsat_dvgs * dldsat;
  505.        dldvds =              - dldsat;
  506.        dldvbs =  dvdsat_dvbs * dldsat;
  507.     }else{
  508.        lambda = 0.;
  509.        dldvgs = dldvds = dldvbs = 0.;
  510.     }
  511.  }else{
  512.     lambda = m->lambda;
  513.     dldvgs = dldvbs = 0.;
  514.     dldvds = -lambda;
  515.  }
  516.  
  517.  clfact = (1. - lambda * x->vds);
  518.  if (clfact < m->xwb/x->le){
  519.     double leff, dfact;
  520.     leff = m->xwb / (2. - (clfact * x->le / m->xwb));
  521.     clfact = leff / x->le;
  522.     dfact = (leff * leff) / (m->xwb * m->xwb);
  523.     dldvgs *= dfact;
  524.     dldvds *= dfact;
  525.     dldvbs *= dfact;
  526.  }
  527.  
  528.  x->saturated = (x->vds > x->vdsat);
  529.  vdsx =  (x->saturated) ? x->vdsat : x->vds;
  530.  bargx = (x->saturated) ? bsarg : barg;
  531.  body = bargx*bargx*bargx - sarg*sarg*sarg;
  532.  expg = (x->subthreshold) ? exp(x->vgst / vtxn) : 1.;
  533.  beta = x->beta * ufact / clfact;
  534.  
  535.  ids_on = beta * ((vc - x->eta_2 * vdsx) * vdsx  - (2./3.) * gamma_s * body);
  536.  didvds = beta * (vc  -  x->eta * vdsx  -  gamma_s * bargx);
  537.  
  538.  x->ids = ids_on * expg;
  539.  
  540.  x->gm = beta * vdsx;
  541.  x->gm += ids_on * (dudvgs/ufact - dldvgs/clfact);
  542.  if (x->saturated)
  543.     x->gm += didvds * dvdsat_dvgs;
  544.  if (x->subthreshold){
  545.     x->gm = ids_on / vtxn;
  546.     if (x->saturated)
  547.        x->gm += didvds * dvdsat_dvgs;
  548.     x->gm *= expg;
  549.  }
  550.  x->gds = (x->saturated) ? 0.: didvds;
  551.  x->gds += ids_on * (dudvds/ufact - dldvds/clfact);
  552.  if (short_channel)
  553.     x->gds -= beta * (2./3.) * body * dgamma_s_dvds;
  554.  if (x->subthreshold){
  555.     double dodvds, dxndvd, gmw;
  556.     dxndvd = dgamma_s_dvds * dsarg_dvbs;
  557.     dodvds = dgamma_s_dvds * sarg + vt * dxndvd;
  558.     gmw = x->ids * x->vgst / (vtxn * xn);
  559.     x->gds *= expg;
  560.     x->gds -= x->gm * dodvds + gmw * dxndvd;
  561.  }
  562.  x->gmb = beta * (x->eta_1 * vdsx - gamma_s * (sarg - bargx));
  563.  x->gmb += ids_on * (dudvbs/ufact - dldvbs/clfact);
  564.  if (short_channel)
  565.     x->gmb -= beta * (2./3.) * body * dgamma_s_dvbs;
  566.  if (x->saturated)
  567.     x->gmb += didvds * dvdsat_dvbs;
  568.  if (x->subthreshold){
  569.     double gmw;
  570.     gmw = x->ids * x->vgst / (vtxn * xn);
  571.     x->gmb += beta * dodvbs * vdsx;
  572.     x->gmb *= expg;
  573.     x->gmb -= x->gm * dodvbs + gmw * dxndvb;
  574.  }
  575. }
  576. /*--------------------------------------------------------------------------*/
  577. /*--------------------------------------------------------------------------*/
  578. SHAR_EOF
  579. fi # end of overwriting check
  580. if test -f 'src/d_mos3.c'
  581. then
  582.     echo shar: will not over-write existing file "'src/d_mos3.c'"
  583. else
  584. cat << \SHAR_EOF > 'src/d_mos3.c'
  585. /* dev_mos3  07/30/91  (XZ)  12/19/93, 94.01.13, 94.02.11
  586.  * mos model equations: spice level 3 equivalent
  587.  */
  588. #include "ecah.h"
  589. #include "branch.h"
  590. #include "d_diode.h"
  591. #include "d_mos.h"
  592. #include "error.h"
  593. #include "io.h"
  594. #include "declare.h"
  595. /*--------------------------------------------------------------------------*/
  596. extern const struct ioctrl io;
  597. /*--------------------------------------------------------------------------*/
  598. void eval_mos3(branch_t *brh)
  599. {
  600.  static struct mos *x;
  601.  static struct mmod *m;
  602.  double phi_0, phi_vbs, phi_vbd, vbd;
  603.  double beta;
  604.  double sigma;
  605.  double ids;
  606.  double us, ueff;
  607.  double fb, fs, fn;
  608.  double wc, wp;
  609.  double va, vb;
  610.  double ep, ep_xd;
  611.  double theta_vgs;
  612.  double cox_w_le;
  613.  double fb_1;
  614.  double xd_2;
  615.  double gamma_fs;
  616.  double us2_vmax_le;
  617.  double us_vds_vmax, us_vds_vmax2;
  618.  double us_vdsat_vmax, us_vdsat_vmax2;
  619.  double xjwp_sq, xjwp_sqrt;
  620.  double vgs_vth_vdsat, ueff_sat, dueff_dvdsat, gdsat;
  621.  double del_le, lfac;
  622.  double vgs_vth_vds;
  623.  double dus_dvgs;
  624.  double dfs_dvbs;
  625.  double dueff_dvds, dueff_dvgs;
  626.  double dwp_dvbs, dwc_dvbs;
  627.  double dvth_dvbs;
  628.  double dbeta_dvds, dbeta_dvgs;
  629.  double dids_dvds, dids_dvgs, dids_dvbs;
  630.  double a = 0.0631354;
  631.  double b = 0.8013292;
  632.  double c = 0.01110777;
  633.  
  634.  double vdsx, vgsx;
  635.  
  636.  int use_vmax;
  637.  int use_xj;
  638.  
  639.  x = (struct mos*)brh->x;
  640.  m = x->m;
  641.  
  642.  use_vmax = (m->vmax != NOT_INPUT  &&  m->vmax != 0.);
  643.  use_xj = (m->xj != NOT_INPUT  &&  m->xj > 0.);
  644.  
  645.  phi_0 = sqrt(m->phi);
  646.  if (x->vbs <= 0.){
  647.     phi_vbs = sqrt(m->phi - x->vbs);
  648.     x->sbfwd = NO;
  649.  }else{
  650.     phi_vbs = sqrt(m->phi) / (1. + .5 * x->vbs / m->phi);
  651.     x->sbfwd = YES;
  652.     if (!io.suppresserrors){
  653.        error((x->vbs < -.01) ? bPICKY : bTRACE,
  654.           "%s: source fwd biased.  vbs=%g\n", printlabel(brh,NO), x->vbs);
  655.     }
  656.  }
  657.  
  658.  vbd = x->vbs - x->vds;
  659.  if (vbd <= 0.){
  660.     phi_vbd = sqrt(m->phi - vbd);
  661.     x->dbfwd = NO;
  662.  }else{
  663.     phi_vbd = sqrt(m->phi) / (1. + .5 * vbd / m->phi);
  664.     x->dbfwd = YES;
  665.     if (!io.suppresserrors){
  666.        error((vbd < -.01) ? bPICKY : bTRACE,
  667.           "%s: drain fwd biased.  vbd=%g\n", printlabel(brh,NO), vbd);
  668.     }
  669.  }
  670.  
  671.                                /* threshold voltage */
  672.  sigma = 8.15e-22 * m->eta / (m->cox * x->le * x->le * x->le);
  673.  fn = (kPI * E_SI * m->delta) / (4. * m->cox * x->we);
  674.  wp = m->xd * sqrt(m->d->pb - x->vbs);
  675.  wc = use_xj ? a*m->xj + b*wp - c*wp*wp/m->xj : 0.;
  676.  xjwp_sq = wp / (m->xj + wp);
  677.  xjwp_sq *= xjwp_sq;
  678.  xjwp_sqrt = sqrt(1. - xjwp_sq);
  679.  fs = use_xj ? 1. - m->xj/x->le * ((m->ld + wc)/m->xj * xjwp_sqrt - m->ld/m->xj)
  680.              : 1.;
  681.  fb = m->gamma * fs / (2. * phi_vbs) + fn;
  682.  fb_1 = .5 * (1. + fb);
  683.  gamma_fs = m->gamma*fs*phi_vbs + fn*(m->phi - x->vbs);
  684.  x->von = m->vfb + m->phi - sigma*x->vds + gamma_fs;
  685.  x->vgst = x->vgs - x->von;
  686.  
  687.                              /* mobility modulation */
  688.  theta_vgs = 1. + m->theta * x->vgst;
  689.  us = m->uo / theta_vgs;
  690.  us_vds_vmax = use_vmax ? 1. + us * x->vds / (m->vmax * x->le)
  691.             : 1.;
  692.  us_vds_vmax2 = us_vds_vmax * us_vds_vmax;
  693.  us2_vmax_le = use_vmax ? -us*us / (m->vmax*x->le)
  694.             : 1.;
  695.  ueff = us / us_vds_vmax;
  696.  cox_w_le = m->cox * x->we / x->le;
  697.  beta = ueff * cox_w_le;
  698.  
  699.                               /* saturation voltage */
  700.  va = x->vgst / (1. + fb);
  701.  vb = use_vmax ? m->vmax * x->le / us : 0.;
  702.  x->vdsat = use_vmax ? va + vb - sqrt(va*va + vb*vb) : va;
  703.  vdsx = MIN(x->vds, x->vdsat);
  704.  vgsx = MAX(x->vgs, x->von);
  705.  ids = beta * (vgsx - x->von - fb_1*vdsx) * vdsx;
  706.  
  707.  x->saturated = (x->vds > x->vdsat);
  708.  x->cutoff = (x->vgst < 0.);
  709.  
  710.  if (x->cutoff){
  711.     lfac = 0.;
  712.  }else if (!x->saturated){
  713.     lfac = 1.;
  714.  }else{                           /* channel-length modulation */
  715.     us_vdsat_vmax = use_vmax ? 1. + us * x->vdsat/(m->vmax * x->le)
  716.                  : 1.;
  717.     us_vdsat_vmax2 = us_vdsat_vmax * us_vdsat_vmax;
  718.     ueff_sat = us / us_vdsat_vmax;
  719.     dueff_dvdsat = use_vmax ? us2_vmax_le / us_vdsat_vmax2
  720.                 : 0.;
  721.     vgs_vth_vdsat = vgsx - x->von - fb_1*x->vdsat;
  722.     gdsat = (cox_w_le*dueff_dvdsat*x->vdsat + beta) * vgs_vth_vdsat  -
  723.             beta * x->vdsat * (fb_1 - sigma);
  724.     xd_2 = m->xd * m->xd;
  725.     ep = m->kappa * ids / (gdsat * x->le);
  726.     ep_xd = .5 * ep * xd_2;
  727.     del_le = sqrt(m->kappa*xd_2*(x->vds - x->vdsat) + ep_xd*ep_xd) - ep_xd;
  728.     lfac = 1. / (1. - (del_le/x->le));
  729.  }
  730.  
  731.                              /* (trans)conductances */
  732.  vgs_vth_vds = vgsx - x->von - fb_1*x->vds;
  733.  dwp_dvbs = -.5 * m->xd / phi_vbs;
  734.  dwc_dvbs = use_xj ? (b - 2.*c*wp/m->xj) * dwp_dvbs : 0.;
  735.  dfs_dvbs = use_xj ? (m->ld + wc) * xjwp_sq / (x->le * m->xj * xjwp_sqrt) *
  736.              dwp_dvbs - xjwp_sqrt / x->le * dwc_dvbs
  737.            : 0.;
  738.  dus_dvgs = -m->uo * m->theta / (theta_vgs * theta_vgs);
  739.  dueff_dvgs = dus_dvgs / us_vds_vmax2;
  740.  dueff_dvds = use_vmax ? us2_vmax_le / us_vds_vmax2 : 0.;
  741.  dbeta_dvgs = dueff_dvgs * cox_w_le;
  742.  dbeta_dvds = cox_w_le * dueff_dvds;
  743.  dvth_dvbs = m->gamma * (phi_vbs*dfs_dvbs - .5*fs/phi_vbs);
  744.  
  745.  dids_dvds = (dbeta_dvds + beta)*vgs_vth_vds - beta*x->vds*(fb_1 - sigma);
  746.  dids_dvgs = (dbeta_dvgs*vgs_vth_vds + beta) * x->vds;
  747.  dids_dvbs = -beta * x->vds * (dvth_dvbs + x->vds*m->gamma/(4.*phi_vbs)*
  748.              dfs_dvbs);
  749.  
  750.  x->ids = ids * lfac;
  751.  x->gds = dids_dvds * lfac;
  752.  x->gm  = dids_dvgs * lfac;
  753.  x->gmb = dids_dvbs * lfac;
  754. }  
  755. /*--------------------------------------------------------------------------*/
  756. /*--------------------------------------------------------------------------*/
  757. SHAR_EOF
  758. fi # end of overwriting check
  759. if test -f 'src/d_mosc.c'
  760. then
  761.     echo shar: will not over-write existing file "'src/d_mosc.c'"
  762. else
  763. cat << \SHAR_EOF > 'src/d_mosc.c'
  764. /* d_mosc.c  93.12.19
  765.  * Copyright 1983-1992   Albert Davis
  766.  * mos model subcircuit functions
  767.  */
  768. #include "ecah.h"
  769. #include "branch.h"
  770. #include "d_mos.h"
  771. #include "declare.h"
  772. /*--------------------------------------------------------------------------*/
  773.     void    mos2_ids0(branch_t*);
  774.     void    mos2_gmf0(branch_t*);
  775.     void    mos2_gmr0(branch_t*);
  776.     void    mos2_gds0(branch_t*);
  777.     void    mos2_gmbf0(branch_t*);
  778.     void    mos2_gmbr0(branch_t*);
  779.     void    mos_cgb0(branch_t*);
  780.     void    mos_cgd0(branch_t*);
  781.     void    mos_cgs0(branch_t*);
  782.     void    mos2_ids1(branch_t*);
  783.     void    mos2_gmf1(branch_t*);
  784.     void    mos2_gmr1(branch_t*);
  785.     void    mos2_gds1(branch_t*);
  786.     void    mos2_gmbf1(branch_t*);
  787.     void    mos2_gmbr1(branch_t*);
  788.     void    mos_cgb1(branch_t*);
  789.     void    mos_cgd1(branch_t*);
  790.     void    mos_cgs1(branch_t*);
  791. /*--------------------------------------------------------------------------*/
  792. /*--------------------------------------------------------------------------*/
  793. /* mos2_ids: drain-source current calculations
  794.  * returns ids
  795.  */
  796. /*--------------------------------------------------------------------------*/
  797. void mos2_ids0(branch_t *brh)
  798. {
  799.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  800. }
  801. /*--------------------------------------------------------------------------*/
  802. void mos2_ids1(branch_t *brh)
  803. {
  804.  struct mos *x;
  805.  struct mmod *m;
  806.  
  807.  x = (struct mos*)brh->parent->x;
  808.  m = x->m;
  809.  if (brh->bypass){
  810.     brh->y0 = brh->y1;
  811.     brh->y1 = brh->y2;
  812.  }else{
  813.     double ids = (x->reversed) ? -x->ids : x->ids;
  814.     brh->y0.f1 = m->polarity * ids;
  815.     brh->y0.f0 = brh->y0.x * brh->y0.f1;
  816.     brh->y0.f0 = LINEAR;
  817.  }
  818. }
  819. /*--------------------------------------------------------------------------*/
  820. /*--------------------------------------------------------------------------*/
  821. /* mos2_gmf: gate transconductance calculations forward mode
  822.  * returns gm or 0
  823.  */
  824. /*--------------------------------------------------------------------------*/
  825. /*ARGSUSED*/
  826. void mos2_gmf0(branch_t *brh)
  827. {;}
  828. /*--------------------------------------------------------------------------*/
  829. void mos2_gmf1(branch_t *brh)
  830. {
  831.  struct mos *x;
  832.  
  833.  x = (struct mos*)brh->parent->x;
  834.  if (brh->bypass){
  835.     brh->y0 = brh->y1;
  836.     brh->y1 = brh->y2;
  837.  }else{
  838.     brh->y0.f1 = (x->reversed) ? 0. : x->gm;
  839.     brh->y0.f0 = 0.;
  840.  }
  841. }
  842. /*--------------------------------------------------------------------------*/
  843. /*--------------------------------------------------------------------------*/
  844. /* mos2_gmr: gate transconductance calculations reversed mode
  845.  * returns gm or 0
  846.  */
  847. /*--------------------------------------------------------------------------*/
  848. /*ARGSUSED*/
  849. void mos2_gmr0(branch_t *brh)
  850. {;}
  851. /*--------------------------------------------------------------------------*/
  852. void mos2_gmr1(branch_t *brh)
  853. {
  854.  struct mos *x;
  855.  
  856.  x = (struct mos*)brh->parent->x;
  857.  if (brh->bypass){
  858.     brh->y0 = brh->y1;
  859.     brh->y1 = brh->y2;
  860.  }else{
  861.     brh->y0.f1 = (x->reversed) ? x->gm : 0.;
  862.     brh->y0.f0 = 0.;
  863.  }
  864. }
  865. /*--------------------------------------------------------------------------*/
  866. /*--------------------------------------------------------------------------*/
  867. /* mos2_gds: self-conductance calculations
  868.  * returns gds
  869.  */
  870. /*--------------------------------------------------------------------------*/
  871. /*ARGSUSED*/
  872. void mos2_gds0(branch_t *brh)
  873. {;}
  874. /*--------------------------------------------------------------------------*/
  875. void mos2_gds1(branch_t *brh)
  876. {
  877.  struct mos *x;
  878.  
  879.  x = (struct mos*)brh->parent->x;
  880.  if (brh->bypass){
  881.     brh->y0 = brh->y1;
  882.     brh->y1 = brh->y2;
  883.  }else{
  884.     brh->y0.f1 = x->gds;
  885.     brh->y0.f0 = 0.;
  886.  }
  887. }
  888. /*--------------------------------------------------------------------------*/
  889. /*--------------------------------------------------------------------------*/
  890. /* mos2_gmbf: bulk transconductance calculations, forward mode
  891.  * returns gmb or 0
  892.  */
  893. /*--------------------------------------------------------------------------*/
  894. /*ARGSUSED*/
  895. void mos2_gmbf0(branch_t *brh)
  896. {;}
  897. /*--------------------------------------------------------------------------*/
  898. void mos2_gmbf1(branch_t *brh)
  899. {
  900.  struct mos *x;
  901.  
  902.  x = (struct mos*)brh->parent->x;
  903.  if (brh->bypass){
  904.     brh->y0 = brh->y1;
  905.     brh->y1 = brh->y2;
  906.  }else{
  907.     brh->y0.f1 = (x->reversed) ? 0. : x->gmb;
  908.     brh->y0.f0 = 0.;
  909.  }
  910. }
  911. /*--------------------------------------------------------------------------*/
  912. /*--------------------------------------------------------------------------*/
  913. /* mos2_gmbr: bulk transconductance calculations, reversed mode
  914.  * returns gmb or 0
  915.  */
  916. /*--------------------------------------------------------------------------*/
  917. /*ARGSUSED*/
  918. void mos2_gmbr0(branch_t *brh)
  919. {;}
  920. /*--------------------------------------------------------------------------*/
  921. void mos2_gmbr1(branch_t *brh)
  922. {
  923.  struct mos *x;
  924.  
  925.  x = (struct mos*)brh->parent->x;
  926.  if (brh->bypass){
  927.     brh->y0 = brh->y1;
  928.     brh->y1 = brh->y2;
  929.  }else{
  930.     brh->y0.f1 = (x->reversed) ? x->gmb : 0.;
  931.     brh->y0.f0 = 0.;
  932.  }
  933. }
  934. /*--------------------------------------------------------------------------*/
  935. /*--------------------------------------------------------------------------*/
  936. /* gate capacitors.  Meyer model.  
  937.  * Refs: Antognetti, Divekar, Spice 2 & 3 code
  938.  * final ref was Spice 2g6 code.
  939.  * all agree except for typos and smoothing.  (yup!!)
  940.  */
  941. /*--------------------------------------------------------------------------*/
  942. void mos_cgb0(branch_t *brh)
  943. {
  944.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  945. }
  946. /*--------------------------------------------------------------------------*/
  947. void mos_cgb1(branch_t *brh)
  948. {
  949.  double c;
  950.  struct mos *x;
  951.  struct mmod *m;
  952.  x = (struct mos*)brh->parent->x;
  953.  m = x->m;
  954.  
  955.  c = brh->val;
  956.  if (x->vgst < - m->phi){             /* accumulation */
  957.     c += x->cgate;
  958.  }else if (x->vgst < 0.){            /* depletion */
  959.     c += x->cgate * (-x->vgst) / m->phi;
  960.  }                        /* active, overlap only */
  961.  brh->y0.f1 = c;
  962.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  963. }
  964. /*--------------------------------------------------------------------------*/
  965. /*--------------------------------------------------------------------------*/
  966. void mos_cgd0(branch_t *brh)
  967. {
  968.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  969. }
  970. /*--------------------------------------------------------------------------*/
  971. void mos_cgd1(branch_t *brh)
  972. {
  973.  double c;
  974.  struct mos *x;
  975.  x = (struct mos*)brh->parent->x;
  976.  
  977.  c = brh->val;                    /* start with overlap cap */
  978.  if (x->vgst > x->vds){                /* linear */
  979.     double vdif = 2. * x->vgst - x->vds;
  980.     c += (2./3.) * x->cgate * (1. - (x->vgst*x->vgst)/(vdif*vdif));
  981.  }                        /* else overlap only */
  982.  brh->y0.f1 = c;
  983.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  984. }
  985. /*--------------------------------------------------------------------------*/
  986. /*--------------------------------------------------------------------------*/
  987. void mos_cgs0(branch_t *brh)
  988. {
  989.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  990. }
  991. /*--------------------------------------------------------------------------*/
  992. void mos_cgs1(branch_t *brh)
  993. {
  994.  double c;
  995.  struct mos *x;
  996.  struct mmod *m;
  997.  x = (struct mos*)brh->parent->x;
  998.  m = x->m;
  999.  
  1000.  c = brh->val;                    /* start with overlap cap */
  1001.  if (x->vgst > x->vds){                /* linear */
  1002.     double numer = x->vgst - x->vds;
  1003.     double denom = 2. * x->vgst - x->vds;
  1004.     c += (2./3.) * x->cgate * (1. - (numer*numer)/(denom*denom));
  1005.  }else if (x->vgst > 0.){            /* saturation */
  1006.     c += (2./3.) * x->cgate;
  1007.  }else if (x->vgst > -m->phi/2.){        /* depletion */
  1008.     c += (2./3.) * x->cgate * ((x->vgst / (m->phi/2.)) + 1.);
  1009.  }                        /* accum. = overlap only */
  1010.  brh->y0.f1 = c;
  1011.  brh->y0.f0 = brh->y0.x * brh->y0.f1;
  1012. }
  1013. /*--------------------------------------------------------------------------*/
  1014. /*--------------------------------------------------------------------------*/
  1015. /*--------------------------------------------------------------------------*/
  1016. /*--------------------------------------------------------------------------*/
  1017. SHAR_EOF
  1018. fi # end of overwriting check
  1019. if test -f 'src/d_res.c'
  1020. then
  1021.     echo shar: will not over-write existing file "'src/d_res.c'"
  1022. else
  1023. cat << \SHAR_EOF > 'src/d_res.c'
  1024. /* d_res.c  94.05.30
  1025.  * Copyright 1983-1992   Albert Davis
  1026.  * functions for resistor.
  1027.  * x = amps, y.f0 = volts, ev = y.f1 = ohms
  1028.  */
  1029. #include "ecah.h"
  1030. #include "branch.h"
  1031. #include "error.h"
  1032. #include "mode.h"
  1033. #include "options.h"
  1034. #include "declare.h"
  1035. /*--------------------------------------------------------------------------*/
  1036. static    void    expand_resistor(branch_t*);
  1037. static     int    tr_resistor_lin(branch_t*);
  1038. static     int    tr_resistor_nl(branch_t*);
  1039. static     void    ac_resistor_lin(branch_t*);
  1040. static     void    ac_resistor_nl(branch_t*);
  1041. /*--------------------------------------------------------------------------*/
  1042. extern const struct options opt;
  1043. /*--------------------------------------------------------------------------*/
  1044. functions_t dev_resistor = {
  1045.    (generic_t*)NULL,    /* x */
  1046.    sizeof(functions_t),    /* ssize */
  1047.    sizeof(branch_t),    /* elementsize */
  1048.    (functions_t*)NULL,    /* super */
  1049.    2,             /* numnodes */
  1050.    rnONEPORT,        /* refnode */
  1051.    rnONEPORT,        /* isdevice */
  1052.    create_std,        /* create */
  1053.    copy_std,        /* copy */
  1054.    parse_std,        /* parse */
  1055.    print_std,        /* print */
  1056.    expand_resistor,    /* expand */
  1057.    probe_std,        /* probe */
  1058.    tr_resistor_nl,    /* dotr */
  1059.    unloadpassive,    /* untr */
  1060.    ac_resistor_nl,    /* doac */
  1061.    trfix1,        /* trfun1 */
  1062.    trfix0,        /* trfun0 */
  1063.    acfix,        /* acfun */
  1064.    NULL,        /* tr_guess */
  1065.    NULL,        /* tr_advance */
  1066.    NULL            /* tr_review */
  1067. };
  1068. functions_t dev_resistor_lin = {
  1069.    (generic_t*)NULL,    /* x */
  1070.    sizeof(functions_t),    /* ssize */
  1071.    sizeof(branch_t),    /* elementsize */
  1072.    &dev_resistor,    /* super */
  1073.    2,             /* numnodes */
  1074.    rnLINEAR,        /* refnode */
  1075.    rnONEPORT,        /* isdevice */
  1076.    create_std,        /* create */
  1077.    copy_std,        /* copy */
  1078.    parse_std,        /* parse */
  1079.    print_std,        /* print */
  1080.    expand_resistor,    /* expand */
  1081.    probe_std,        /* probe */
  1082.    tr_resistor_lin,    /* dotr */
  1083.    unloadpassive,    /* untr */
  1084.    ac_resistor_lin,    /* doac */
  1085.    NULL,        /* trfun1 */
  1086.    NULL,        /* trfun0 */
  1087.    NULL,        /* acfun */
  1088.    NULL,        /* tr_guess */
  1089.    NULL,        /* tr_advance */
  1090.    NULL         /* tr_review */
  1091. };
  1092. /*--------------------------------------------------------------------------*/
  1093. static void expand_resistor(branch_t *brh)
  1094. {
  1095.  if (!brh->x){
  1096.     brh->f = &dev_resistor_lin;
  1097.     if (brh->val == 0.){
  1098.        error(bPICKY, "%s: short circuit\n", printlabel(brh,NO));
  1099.        brh->y0.f1 = opt.shortckt;
  1100.     }else{
  1101.        brh->y0.f1 = brh->val;
  1102.     }
  1103.     brh->y0.f0 = LINEAR;
  1104.  
  1105.     brh->m0.f1 = 1./brh->y0.f1;
  1106.     brh->m0.c0 = 0.;
  1107.     brh->ev.x  = brh->val;
  1108.     brh->ev.y  = 0.;
  1109.     brh->acg.x = brh->m0.f1;
  1110.     brh->acg.y = 0.;
  1111.  }
  1112. }
  1113. /*--------------------------------------------------------------------------*/
  1114. static int tr_resistor_lin(branch_t *brh)
  1115. {
  1116.  trloadpassive(brh);
  1117.  return brh->converged = YES;
  1118. }
  1119. /*--------------------------------------------------------------------------*/
  1120. static int tr_resistor_nl(branch_t *brh)
  1121. {
  1122.  brh->m0.x = tr_volts_limited(&(brh->n[OUT1]),&(brh->n[OUT2]));
  1123.  brh->y0.x = brh->m0.c0 + brh->m0.f1 * brh->m0.x;
  1124.  
  1125.  if (brh->f->trfun1){
  1126.     (*brh->f->trfun1)(brh);
  1127.     brh->m0.c0 = brh->y0.x - brh->y0.f0 / brh->y0.f1;
  1128.  }else{
  1129.     brh->y0.f1 = brh->val;
  1130.     brh->y0.f0 = brh->y0.x * brh->y0.f1;
  1131.     brh->m0.c0 = 0.;
  1132.  }
  1133.  if (brh->y0.f1 == 0.){
  1134.     error(bPICKY, "%s: short circuit\n", printlabel(brh,NO));
  1135.     brh->y0.f1 = opt.shortckt;
  1136.  }
  1137.  brh->m0.f1 = 1./brh->y0.f1;
  1138.  brh->m0.c0 = brh->y0.x - brh->y0.f0 / brh->y0.f1;
  1139.  
  1140.  trloadpassive(brh);
  1141.  return brh->converged = conv_check(brh);
  1142. }
  1143. /*--------------------------------------------------------------------------*/
  1144. static void ac_resistor_lin(branch_t *brh)
  1145. {
  1146.  acloadpassivereal(brh);
  1147. }
  1148. /*--------------------------------------------------------------------------*/
  1149. static void ac_resistor_nl(branch_t *brh)
  1150. {
  1151.  if (brh->f->acfun){
  1152.     double dcvolts = dc_volts(&(brh->n[OUT1]),&(brh->n[OUT2]));
  1153.     brh->acbias = brh->m0.c0 + brh->m0.f1*dcvolts;
  1154.     brh->ev = (*brh->f->acfun)(brh);
  1155.     if (brh->ev.y == 0.){
  1156.        if (brh->ev.x == 0.){
  1157.           error(bPICKY, "%s: short circuit\n", printlabel(brh,NO));
  1158.           brh->ev.x = opt.shortckt;
  1159.        }
  1160.        brh->acg.x = 1. / brh->ev.x;
  1161.        brh->acg.y = 0.;
  1162.     }else{
  1163.        brh->acg = cflip(brh->ev);
  1164.     }
  1165.     acloadpassive(brh);
  1166.  }else{
  1167.     brh->ev.x  = brh->y0.f1;
  1168.     brh->ev.y  = 0.;
  1169.     brh->acg.x = 1. / brh->ev.x;
  1170.     brh->acg.y = 0.;
  1171.     acloadpassivereal(brh);
  1172.  }
  1173. }
  1174. /*--------------------------------------------------------------------------*/
  1175. /*--------------------------------------------------------------------------*/
  1176. SHAR_EOF
  1177. fi # end of overwriting check
  1178. if test -f 'src/d_subckt.c'
  1179. then
  1180.     echo shar: will not over-write existing file "'src/d_subckt.c'"
  1181. else
  1182. cat << \SHAR_EOF > 'src/d_subckt.c'
  1183. /* d_subckt.c  94.01.01
  1184.  * Copyright 1983-1992   Albert Davis
  1185.  * subcircuit stuff
  1186.  * netlist syntax:
  1187.  * device: Xxxxx <nodelist> <subckt-name>
  1188.  * model:  .subckt <subckt-name> <nodelist>
  1189.  *       (device cards)
  1190.  *       .ends <subckt-name>
  1191.  */
  1192. #include "ecah.h"
  1193. #include "branch.h"
  1194. #include "d_subckt.h"
  1195. #include "error.h"
  1196. #include "mode.h"
  1197. #include "types.h"
  1198. #include "declare.h"
  1199. /*--------------------------------------------------------------------------*/
  1200.     void    cmd_ends(const char*,int*);
  1201. static  branch_t  *create_subckt(const functions_t*);
  1202. static  branch_t  *copy_subckt(const branch_t*);
  1203. static  void    parse_subckt(branch_t*,const char*,int*);
  1204. static  void    print_subckt(const branch_t*,int,int);
  1205. static  branch_t  *create_model_subckt(const functions_t*);
  1206. static  branch_t  *copy_model_subckt(const branch_t*);
  1207. static  void    parse_model_subckt(branch_t*,const char*,int*);
  1208. static  void    print_model_subckt(const branch_t*,int,int);
  1209. static  void    expand_subckt(branch_t*);
  1210.     void    expandsubckt(branch_t*,const char*);
  1211. static    double    probe_subckt(const branch_t*,const char*);
  1212. static  int     tr_subckt(branch_t*);
  1213. static  void    un_subckt(branch_t*);
  1214. static  void    ac_subckt(branch_t*);
  1215. static    double    tr_review_subckt(branch_t*);
  1216. /*--------------------------------------------------------------------------*/
  1217. static struct subckt defalt = {(generic_t*)NULL, sizeof(struct subckt), 
  1218.    (generic_t*)NULL, sDEFAULT_modelname, /*more*/};
  1219. static struct smod defaltmodel = {(generic_t*)NULL, sizeof(struct smod), 
  1220.    (generic_t*)NULL, sDEFAULT_modelname, /*more*/};
  1221. static branch_t modellist = {(generic_t*)NULL, sizeof(branch_t), 
  1222.    &model_subckt, &modellist, &modellist, &modellist, &modellist, 
  1223.    (branch_t*)NULL, (branch_t*)NULL, sDEFAULT_modelname, /*more*/};
  1224. static branch_t *(neststack[RECURSE]);
  1225. static char namestack[LABELEN+1][RECURSE];
  1226. static int nestlevel;
  1227. extern branch_t *insertbefore;
  1228. extern const char e_int[];
  1229. /*--------------------------------------------------------------------------*/
  1230. functions_t dev_subckt = {
  1231.    (generic_t*)&defalt,    /* x */
  1232.    sizeof(functions_t),    /* ssize */
  1233.    sizeof(branch_t),    /* elementsize */
  1234.    (functions_t*)NULL,    /* super */
  1235.    PORTSPERSUBCKT,     /* numnodes */
  1236.    rnALL,        /* refnode */
  1237.    YES,            /* isdevice */
  1238.    create_subckt,    /* create */
  1239.    copy_subckt,        /* copy */
  1240.    parse_subckt,    /* parse */
  1241.    print_subckt,    /* print */
  1242.    expand_subckt,    /* expand */
  1243.    probe_subckt,    /* probe */
  1244.    tr_subckt,        /* dotr */
  1245.    un_subckt,        /* untr */
  1246.    ac_subckt,        /* doac */
  1247.    NULL,        /* trfun1 */
  1248.    NULL,        /* trfun0 */
  1249.    NULL,        /* acfun */
  1250.    NULL,        /* tr_guess */
  1251.    NULL,        /* tr_advance */
  1252.    tr_review_subckt    /* tr_review */
  1253. };
  1254. functions_t model_subckt = {
  1255.    (generic_t*)&defaltmodel,    /* x */
  1256.    sizeof(functions_t),    /* ssize */
  1257.    sizeof(branch_t),    /* elementsize */
  1258.    (functions_t*)NULL,    /* super */
  1259.    PORTSPERSUBCKT,     /* numnodes */
  1260.    rnMODEL,        /* refnode */
  1261.    NO,            /* isdevice */
  1262.    create_model_subckt,    /* create */
  1263.    copy_model_subckt,    /* copy */
  1264.    parse_model_subckt,    /* parse */
  1265.    print_model_subckt,    /* print */
  1266.    NULL,        /* expand */
  1267.    NULL,        /* probe */
  1268.    NULL,        /* dotr */
  1269.    NULL,        /* untr */
  1270.    NULL,        /* doac */
  1271.    NULL,        /* trfun1 */
  1272.    NULL,        /* trfun0 */
  1273.    NULL,        /* acfun */
  1274.    NULL,        /* tr_guess */
  1275.    NULL,        /* tr_advance */
  1276.    NULL            /* tr_review */
  1277. };
  1278. /*--------------------------------------------------------------------------*/
  1279. void cmd_ends(const char* cmd, int *cnt)
  1280. {
  1281.  if (nestlevel == 0)
  1282.     error(bWARNING, "ends not in subckt\n");
  1283.  else
  1284.     nestlevel--;
  1285.  
  1286.  if (cmd[*cnt]){
  1287.     if (!pmatch(cmd, cnt, namestack[nestlevel]))
  1288.        error(bERROR, "ends tag [%s] does not match subckt [%s]\n",
  1289.           &cmd[*cnt], namestack[nestlevel]);
  1290.  }else{
  1291.     nestlevel = 0;
  1292.  }
  1293.  insertbefore = neststack[nestlevel];
  1294. }
  1295. /*--------------------------------------------------------------------------*/
  1296. static branch_t *create_subckt(const functions_t *func)
  1297. {
  1298.  branch_t *brh;
  1299.  struct subckt *x;
  1300.  
  1301.  brh = create_std(func);
  1302.  x = (struct subckt*)brh->x;
  1303.  brh->n = x->n;
  1304.  return brh;
  1305. }
  1306. /*--------------------------------------------------------------------------*/
  1307. static branch_t *copy_subckt(const branch_t *proto)
  1308. {
  1309.  branch_t *brh;
  1310.  struct subckt *x;
  1311.  
  1312.  brh = copy_std(proto);
  1313.  x = (struct subckt*)brh->x;
  1314.  brh->n = x->n;
  1315.  return brh;
  1316. }
  1317. /*--------------------------------------------------------------------------*/
  1318. static void parse_subckt(branch_t *brh, const char *cmd, int *cnt)
  1319. {
  1320.  struct subckt *x;
  1321.  x = (struct subckt*)brh->x;
  1322.  
  1323.  parselabel(brh,cmd,cnt);
  1324.  (void)parsenodes(brh,cmd,cnt,PORTSPERSUBCKT);
  1325.  (void)ctostr(cmd, cnt, x->modelname, LABELEN);
  1326. }
  1327. /*--------------------------------------------------------------------------*/
  1328. static void print_subckt(const branch_t *brh, int where, int detail)
  1329. {
  1330.  struct subckt *x;
  1331.  x = (struct subckt*)brh->x;
  1332.  
  1333.  (void)printlabel(brh,where);
  1334.  printnodes(brh,where);
  1335.  mprintf(where, " %s\n",    x->modelname);
  1336. }
  1337. /*--------------------------------------------------------------------------*/
  1338. static branch_t *create_model_subckt(const functions_t *func)
  1339. {
  1340.  branch_t *brh;
  1341.  struct smod *x;
  1342.  
  1343.  brh = create_std(func);
  1344.  x = (struct smod*)brh->x;
  1345.  brh->n = x->n;
  1346.  brh->stprev = &modellist;
  1347.  return brh;
  1348. }
  1349. /*--------------------------------------------------------------------------*/
  1350. static branch_t *copy_model_subckt(const branch_t *proto)
  1351. {
  1352.  branch_t *brh;
  1353.  struct smod *x;
  1354.  
  1355.  brh = copy_std(proto);
  1356.  x = (struct smod*)brh->x;
  1357.  brh->n = x->n;
  1358.  brh->stprev = &modellist;
  1359.  return brh;
  1360. }
  1361. /*--------------------------------------------------------------------------*/
  1362. static void parse_model_subckt(branch_t *brh, const char *cmd, int *cnt)
  1363. {
  1364.  struct smod *m;
  1365.  m = (struct smod*)brh->x;
  1366.  
  1367.  if (nestlevel >= RECURSE)
  1368.     error(bERROR,"%s: subckt nesting too deep\n", printlabel(brh,NO));
  1369.  
  1370.  (void)ctostr(cmd, cnt, brh->label, LABELEN);
  1371.  (void)parsenodes(brh,cmd,cnt,PORTSPERSUBCKT);
  1372.  
  1373.  strcpy(namestack[nestlevel], brh->label);
  1374.  neststack[nestlevel] = insertbefore;
  1375.  nestlevel++;
  1376.  brh->subckt = insertbefore = insertbranch(create_branch(&dev_comment));
  1377.  m->x = (generic_t*)NULL;
  1378. }
  1379. /*--------------------------------------------------------------------------*/
  1380. static void print_model_subckt(const branch_t *brh, int where, int detail)
  1381. {
  1382.  branch_t *x, *stop;
  1383.  
  1384.  mprintf(where, ".subckt %s ", brh->label);
  1385.  printnodes(brh,where);
  1386.  mprintf(where, "\n");
  1387.  
  1388.  x = stop = brh->subckt;
  1389.  if (x){
  1390.     do {
  1391.        print_branch(x, where, NO);
  1392.     } while (x = x->next,  x != stop);
  1393.  }
  1394.  mprintf(where, "*+ends %s\n", brh->label);
  1395. }
  1396. /*--------------------------------------------------------------------------*/
  1397. static void expand_subckt(branch_t *brh)
  1398. {
  1399.  struct subckt *x;
  1400.  x = (struct subckt*)brh->x;
  1401.  expandsubckt(brh,x->modelname);
  1402.  if (!brh->subckt){
  1403.     error(bERROR, "");
  1404.  }
  1405.  brh->tracesubckt = YES;
  1406. }
  1407. /*--------------------------------------------------------------------------*/
  1408. void expandsubckt(branch_t *brh, const char *modelname)
  1409. {
  1410.  const branch_t *model;
  1411.  /*struct subckt *x;*/
  1412.  branch_t *scan;
  1413.  branch_t *stop;
  1414.  int port, i;
  1415.  int map[NODESPERSUBCKT];
  1416.  
  1417.  /*x = (struct subckt*)brh->x;*/
  1418.  model = &modellist;                /* search for thing to copy */
  1419.  for (;;){
  1420.     model = model->stnext;
  1421.     if (wmatch(modelname, model->label)){
  1422.        break;
  1423.     }else if (model == &modellist){
  1424.        error(bDANGER, "%s: can't find model: %s\n",
  1425.               printlabel(brh,NO), modelname);
  1426.        if (brh->subckt){
  1427.           error(bERROR, e_int, "subckt exists but has no def\n");
  1428.        }else{
  1429.           return;
  1430.        }
  1431.     }
  1432.  }
  1433.  
  1434.  for (i = 0;  i < NODESPERSUBCKT;  i++)        /* initialize: all nodes unused */
  1435.     map[i] = UNUSED;
  1436.  
  1437.  stop = scan = nextbranch_dev(model->subckt);
  1438.  do {                         /* scan elements of subckt */
  1439.     int ii;                         /* mark nodes used */
  1440.     for (ii = 0;  scan->n[ii].e != INVALIDNODE;  ii++){
  1441.        if (scan->n[ii].e > NODESPERSUBCKT)
  1442.           error(bERROR, "%s: too many internal nodes\n", model->label);
  1443.        map[scan->n[ii].e] = USED;
  1444.     }
  1445.  } while (scan=nextbranch_dev(scan),  scan != stop);
  1446.  
  1447.  map[0] = 0;
  1448.  for (port = 0;  model->n[port].e != INVALIDNODE;  port++){    /* map ports */
  1449.     if (model->n[port].e > NODESPERSUBCKT)
  1450.        error(bERROR, "internal error: subckt node out of range: %s\n",
  1451.                    model->label);
  1452.     map[model->n[port].e] = brh->n[port].t;
  1453.  }
  1454.  
  1455.  for (i = 0;  i < NODESPERSUBCKT;  i++){
  1456.     if (map[i] == USED){
  1457.        map[i] = newnode_subckt();     /* assign number to internal nodes */
  1458.     }
  1459.  }
  1460.  
  1461.  if (!brh->subckt){
  1462.     error(bTRACE, "%s: expanding\n", printlabel(brh,NO));
  1463.     stop = scan = nextbranch_dev(model->subckt);
  1464.     do {
  1465.        branch_t *scratch;                     /* copy subckt */
  1466.        scratch = copy_branch(scan);
  1467.        scratch->parent = brh;
  1468.        scratch->next = brh->subckt;
  1469.        brh->subckt = insertbranch(scratch);
  1470.     } while (scan=nextbranch_dev(scan),  scan != stop);
  1471.  }else{
  1472.     error(bTRACE, "%s: re-expanding\n", printlabel(brh,NO));
  1473.  }
  1474.  
  1475.  stop = scan = nextbranch_dev(brh->subckt);
  1476.  do {                                 /* patch nodes */
  1477.     int ii;
  1478.     for (ii = 0;  scan->n[ii].e != INVALIDNODE;  ii++){
  1479.        if (scan->n[ii].e < 0)
  1480.       error(bERROR, e_int, "bad node");
  1481.        if (map[scan->n[ii].e] < 0)
  1482.           error(bERROR, e_int, "node map");
  1483.        scan->n[ii].t = map[scan->n[ii].e];
  1484.     }
  1485.     scan->n[ii].t = INVALIDNODE;
  1486.  } while (scan=nextbranch_dev(scan),  scan != stop);
  1487. }
  1488. /*--------------------------------------------------------------------------*/
  1489. static double probe_subckt(const branch_t *brh, const char *what)
  1490. {
  1491.  node_t ground;
  1492.  int dummy = 0;
  1493.  
  1494.  ground.e = ground.m = ground.t = 0;
  1495.  if (!brh->subckt)
  1496.     error(bERROR, "internal error: %s not expanded\n", printlabel(brh,NO));
  1497.  
  1498.  setmatch(what,&dummy);
  1499.  if (rematch("V")){
  1500.     int nn = ctoi(what,&dummy);            /* BUG: no bounds check */
  1501.     return tr_volts(&(brh->n[nn+1]),&ground);
  1502.  }else if (rematch("P")){
  1503.     branch_t *pb, *stop;
  1504.     double power = 0.;
  1505.     stop = pb = brh->subckt;
  1506.     do {
  1507.        power += probe_branch(pb,"P");
  1508.     } while (pb=nextbranch_dev(pb), pb != stop);
  1509.     return power;
  1510.  }else if (rematch("PD")){
  1511.     branch_t *pb, *stop;
  1512.     double power = 0.;
  1513.     stop = pb = brh->subckt;
  1514.     do {
  1515.        power += probe_branch(pb,"PD");
  1516.     } while (pb=nextbranch_dev(pb), pb != stop);
  1517.     return power;
  1518.  }else if (rematch("PS")){
  1519.     branch_t *pb, *stop;
  1520.     double power = 0.;
  1521.     stop = pb = brh->subckt;
  1522.     do {
  1523.        power += probe_branch(pb,"PS");
  1524.     } while (pb=nextbranch_dev(pb), pb != stop);
  1525.     return power;
  1526.  }else{ /* bad parameter */
  1527.     return NOT_VALID;
  1528.  }
  1529.  /*NOTREACHED*/
  1530. }
  1531. /*--------------------------------------------------------------------------*/
  1532. static int tr_subckt(branch_t *brh)
  1533. {
  1534.  if (!brh->subckt)
  1535.     error(bERROR, "internal error: %s not expanded\n", printlabel(brh,NO));
  1536.  return brh->converged = tr_fill_rl(brh->subckt);
  1537. }
  1538. /*--------------------------------------------------------------------------*/
  1539. static void un_subckt(branch_t *brh)
  1540. {
  1541.  tr_unfill_rl(brh->subckt);
  1542. }
  1543. /*--------------------------------------------------------------------------*/
  1544. static void ac_subckt(branch_t *brh)
  1545. {
  1546.  if (!brh->subckt)
  1547.     error(bERROR, "internal error: %s not expanded\n", printlabel(brh,NO));
  1548.  ac_fill_rl(brh->subckt);
  1549. }
  1550. /*--------------------------------------------------------------------------*/
  1551. static double tr_review_subckt(branch_t *brh)
  1552. {
  1553.  return tr_review_rl(brh->subckt);
  1554. }
  1555. /*--------------------------------------------------------------------------*/
  1556. /*--------------------------------------------------------------------------*/
  1557. SHAR_EOF
  1558. fi # end of overwriting check
  1559. if test -f 'src/d_trln.c'
  1560. then
  1561.     echo shar: will not over-write existing file "'src/d_trln.c'"
  1562. else
  1563. cat << \SHAR_EOF > 'src/d_trln.c'
  1564. /* d_trln.c  93.12.22
  1565.  * Copyright 1983-1992   Albert Davis
  1566.  * Transmission line. (ideal lossless.  for now, AC only)
  1567.  */
  1568. #include "ecah.h"
  1569. #include "ac.h"
  1570. #include "argparse.h"
  1571. #include "branch.h"
  1572. #include "d_trln.h"
  1573. #include "error.h"
  1574. #include "mode.h"
  1575. #include "declare.h"
  1576. /*--------------------------------------------------------------------------*/
  1577. static     void    parse_trnlin(branch_t*,const char*,int*);
  1578. static    void    setinitcond(const char*,int*);
  1579. static     void    print_trnlin(const branch_t*,int,int);
  1580. static     int    tr_trnlin(branch_t*);
  1581. static     void    ac_trnlin(branch_t*);
  1582. /*--------------------------------------------------------------------------*/
  1583. #define LINLENTOL .000001
  1584. extern const ac_t ac;
  1585. static struct trnlin *x;
  1586. static struct trnlin defalt = {(generic_t*)NULL, sizeof(struct trnlin),
  1587.     DEFAULT_Z0, DEFAULT_TD, DEFAULT_F, DEFAULT_NL, {0.,0.,0.,0.}, 0., NO};
  1588. /*--------------------------------------------------------------------------*/
  1589. functions_t dev_trnlin = {
  1590.    (generic_t*)&defalt,    /* x */
  1591.    sizeof(functions_t),    /* ssize */
  1592.    sizeof(branch_t),    /* elementsize */
  1593.    (functions_t*)NULL,    /* super */
  1594.    4,             /* numnodes */
  1595.    rnTWOPORT,        /* refnode */
  1596.    rnTWOPORT,        /* isdevice */
  1597.    create_std,        /* create */
  1598.    copy_std,        /* copy */
  1599.    parse_trnlin,    /* parse */
  1600.    print_trnlin,    /* print */
  1601.    NULL,        /* expand */
  1602.    NULL,        /* probe */
  1603.    tr_trnlin,        /* dotr */
  1604.    NULL,        /* untr */
  1605.    ac_trnlin,        /* doac */
  1606.    NULL,        /* trfun1 */
  1607.    NULL,        /* trfun0 */
  1608.    NULL,        /* acfun */
  1609.    NULL,        /* tr_guess */
  1610.    NULL,        /* tr_advance */
  1611.    NULL            /* tr_review */
  1612. };
  1613. /*--------------------------------------------------------------------------*/
  1614. /* parse_trnlin: parse input for transmission line, set up branch structure
  1615.  */
  1616. static void parse_trnlin(branch_t *brh, const char *cmd, int *cnt)
  1617. {
  1618.  x = (struct trnlin*)brh->x;
  1619.  
  1620.  parselabel(brh,cmd,cnt);
  1621.  (void)parsenodes(brh,cmd,cnt,4);
  1622.  for (;;){
  1623.     if (argparse(cmd,cnt,REPEAT,
  1624.     "Z",    a2DOUBLE,   &x->z0,    &x->z0,
  1625.     "Freq",    aUDOUBLE,   &x->f,
  1626.     "Nl",    aUDOUBLE,   &x->nl,
  1627.     "Ic",    aFUNCTION,  setinitcond,
  1628.     ""))
  1629.     ;
  1630.     else{
  1631.     syntax_check(cmd,cnt,bWARNING);
  1632.     break;
  1633.     }
  1634.  }
  1635.  if (x->nl == 0.)
  1636.     x->nl = DEFAULT_NL;
  1637.  x->reson = x->f * (.25 / x->nl);
  1638. }
  1639. /*--------------------------------------------------------------------------*/
  1640. /* setinitcond: set initial conditions
  1641.  * called indirectly thru argparse
  1642.  * reads NUM_INIT_COND args, put them in static struct x.
  1643.  * passed this way because of inability of argparse to return values,
  1644.  * and that only cmd and cnt are passed by argparse
  1645.  */
  1646. static void setinitcond(const char *cmd, int *cnt)
  1647. {
  1648.  int i;
  1649.  x->icset = YES;
  1650.  for (i=0;  i<NUM_INIT_COND;  i++)
  1651.     x->ic[i] = ctof(cmd,cnt);
  1652. }
  1653. /*--------------------------------------------------------------------------*/
  1654. /* print_trnlin: print (to "where") the transmission line data structure
  1655.  */
  1656. static void print_trnlin(const branch_t *brh, int where, int detail)
  1657. {
  1658.  struct trnlin *x;
  1659.  (void)printlabel(brh,where);
  1660.  printnodes(brh,where);
  1661.  x = (struct trnlin*)brh->x;
  1662.  mprintf(where, "  Z0=%s  F=%s  NL=%s",
  1663.     ftos(x->z0, "", 7, 0),
  1664.     ftos(x->f,  "", 7, 0),
  1665.     ftos(x->nl, "", 7, 0));
  1666.  if (x->icset){
  1667.     int i;
  1668.     mprintf(where, "  IC=");
  1669.     for (i=0;  i<NUM_INIT_COND;  i++)
  1670.     mprintf(where, "%s ",ftos(x->ic[i],"", 7, 0));
  1671.  }
  1672.  mputc('\n', where);
  1673. }
  1674. /*--------------------------------------------------------------------------*/
  1675. /* tr_trnlin:  transmission line for transient analysis
  1676.  * stub: doesn't work
  1677.  * always returns failure
  1678.  */
  1679. static int tr_trnlin(branch_t *brh)
  1680. {
  1681.  error(bWARNING, "%s: no transmission line in dc or transient\n",
  1682.          printlabel(brh,NO));
  1683.  return brh->converged = YES;
  1684. }
  1685. /*--------------------------------------------------------------------------*/
  1686. /* ac_trnlin:  transmission line procesing for AC analysis
  1687.  */
  1688. static void ac_trnlin(branch_t *brh)
  1689. {
  1690.  double y11, y12;    /* equivalent y parameters (y22, y21 are same)        */
  1691.  double lenth;        /* length, first in quarter waves, then radians        */
  1692.  double dif;        /* difference between actual length and resonance   */
  1693.  struct trnlin *x;
  1694.  
  1695.  x = (struct trnlin*)brh->x;
  1696.  
  1697.  lenth = ac.freq / x->reson;
  1698.  dif = lenth - floor(lenth+.5);
  1699.  if (fabs(dif) < LINLENTOL){                            
  1700.     error(bPICKY,
  1701.       "%s: transmission line too close to resonance\n", printlabel(brh,NO));
  1702.     lenth = (dif<0.) ? floor(lenth+.5)-LINLENTOL : floor(lenth+.5)+LINLENTOL;
  1703.  }
  1704.  lenth *= (kPId2);                      /* now in radians */
  1705.  
  1706.  y12 = -1 / ( x->z0 * sin(lenth) );
  1707.  y11 = tan(lenth/2) / x->z0 + y12;
  1708.  
  1709.  *im(brh->n[OUT1].m,brh->n[OUT1].m) += y11; /* BUG: bypasses load functions */
  1710.  *im(brh->n[OUT2].m,brh->n[OUT2].m) += y11; /* result is flags may not be   */
  1711.  *im(brh->n[OUT1].m,brh->n[OUT2].m) -= y11; /* updated.  No problem yet in  */
  1712.  *im(brh->n[OUT2].m,brh->n[OUT1].m) -= y11; /* AC but this will not work in */
  1713.                         /* transient.            */
  1714.  *im(brh->n[IN1].m,brh->n[IN1].m) += y11;
  1715.  *im(brh->n[IN2].m,brh->n[IN2].m) += y11;
  1716.  *im(brh->n[IN1].m,brh->n[IN2].m) -= y11;
  1717.  *im(brh->n[IN2].m,brh->n[IN1].m) -= y11;
  1718.  
  1719.  *im(brh->n[OUT1].m,brh->n[IN1].m) -= y12;
  1720.  *im(brh->n[OUT2].m,brh->n[IN2].m) -= y12;
  1721.  *im(brh->n[OUT1].m,brh->n[IN2].m) += y12;
  1722.  *im(brh->n[OUT2].m,brh->n[IN1].m) += y12;
  1723.  
  1724.  *im(brh->n[IN1].m,brh->n[OUT1].m) -= y12;
  1725.  *im(brh->n[IN2].m,brh->n[OUT2].m) -= y12;
  1726.  *im(brh->n[IN1].m,brh->n[OUT2].m) += y12;
  1727.  *im(brh->n[IN2].m,brh->n[OUT1].m) += y12;
  1728. }
  1729. /*--------------------------------------------------------------------------*/
  1730. /*--------------------------------------------------------------------------*/
  1731. SHAR_EOF
  1732. fi # end of overwriting check
  1733. if test -f 'src/d_vccs.c'
  1734. then
  1735.     echo shar: will not over-write existing file "'src/d_vccs.c'"
  1736. else
  1737. cat << \SHAR_EOF > 'src/d_vccs.c'
  1738. /* d_vccs.c  94.05.30
  1739.  * Copyright 1983-1992   Albert Davis
  1740.  * functions for vccs
  1741.  */
  1742. #include "ecah.h"
  1743. #include "branch.h"
  1744. #include "mode.h"
  1745. #include "declare.h"
  1746. /*--------------------------------------------------------------------------*/
  1747. static     int    tr_vccs(branch_t*);
  1748. static     void    ac_vccs(branch_t*);
  1749. /*--------------------------------------------------------------------------*/
  1750. /*--------------------------------------------------------------------------*/
  1751. functions_t dev_vccs = {
  1752.    (generic_t*)NULL,    /* x */
  1753.    sizeof(functions_t),    /* ssize */
  1754.    sizeof(branch_t),    /* elementsize */
  1755.    (functions_t*)NULL,    /* super */
  1756.    4,             /* numnodes */
  1757.    rnTWOPORT,        /* refnode */
  1758.    rnTWOPORT,        /* isdevice */
  1759.    create_std,        /* create */
  1760.    copy_std,        /* copy */
  1761.    parse_std,        /* parse */
  1762.    print_std,        /* print */
  1763.    NULL,        /* expand */
  1764.    probe_std,        /* probe */
  1765.    tr_vccs,        /* dotr */
  1766.    unloadactive,    /* untr */
  1767.    ac_vccs,        /* doac */
  1768.    trfix1,        /* trfun1 */
  1769.    trfix0,        /* trfun0 */
  1770.    acfix,        /* acfun */
  1771.    NULL,        /* tr_guess */
  1772.    NULL,        /* tr_advance */
  1773.    NULL            /* tr_review */
  1774. };
  1775. /*--------------------------------------------------------------------------*/
  1776. static int tr_vccs(branch_t *brh)
  1777. {
  1778.  brh->m0.x = tr_volts_limited(&(brh->n[IN1]),&(brh->n[IN2]));
  1779.  brh->y0.x = brh->m0.x;
  1780.  if (brh->f->trfun1){
  1781.     (*brh->f->trfun1)(brh);
  1782.     brh->m0.c0 = brh->y0.f0 - brh->y0.x * brh->y0.f1;
  1783.  }else{
  1784.     brh->y0.f1 = brh->val;
  1785.     brh->y0.f0 = brh->y0.x * brh->y0.f1;
  1786.     brh->m0.c0 = 0.;
  1787.  }
  1788.  brh->m0.x  = brh->y0.x;
  1789.  brh->m0.f1 = brh->y0.f1;
  1790.  trloadactive(brh);
  1791.  return brh->converged = conv_check(brh);
  1792. }
  1793. /*--------------------------------------------------------------------------*/
  1794. static void ac_vccs(branch_t *brh)
  1795. {
  1796.  if (brh->f->acfun){
  1797.     brh->acbias = dc_volts(&(brh->n[IN1]),&(brh->n[IN2]));
  1798.     brh->acg = brh->ev = (*brh->f->acfun)(brh);
  1799.  }else{
  1800.     brh->ev.x  = brh->y0.f1;
  1801.     brh->ev.y  = 0.;
  1802.     brh->acg = brh->ev;
  1803.  }
  1804.  acloadactive(brh);
  1805. }
  1806. /*--------------------------------------------------------------------------*/
  1807. /*--------------------------------------------------------------------------*/
  1808. SHAR_EOF
  1809. fi # end of overwriting check
  1810. if test -f 'src/d_vcvs.c'
  1811. then
  1812.     echo shar: will not over-write existing file "'src/d_vcvs.c'"
  1813. else
  1814. cat << \SHAR_EOF > 'src/d_vcvs.c'
  1815. /* d_vcvs.c  94.05.30
  1816.  * Copyright 1983-1992   Albert Davis
  1817.  * functions for vcvs
  1818.  * temporary kluge: it has resistance
  1819.  * BUG: doesn't work in incmode
  1820.  */
  1821. #include "ecah.h"
  1822. #include "branch.h"
  1823. #include "mode.h"
  1824. #include "options.h"
  1825. #include "declare.h"
  1826. /*--------------------------------------------------------------------------*/
  1827. static     int    tr_vcvs(branch_t*);
  1828. static    void    ac_vcvs(branch_t*);
  1829. /*--------------------------------------------------------------------------*/
  1830. extern const struct options opt;
  1831. static branch_t resistor = {(generic_t*)NULL, sizeof(branch_t),
  1832.     (functions_t*)NULL, (branch_t*)NULL, (branch_t*)NULL, (branch_t*)NULL,
  1833.     (branch_t*)NULL, /*more*/};
  1834. /*--------------------------------------------------------------------------*/
  1835. functions_t dev_vcvs = {
  1836.    (generic_t*)NULL,    /* x */
  1837.    sizeof(functions_t),    /* ssize */
  1838.    sizeof(branch_t),    /* elementsize */
  1839.    (functions_t*)NULL,    /* super */
  1840.    4,             /* numnodes */
  1841.    rnTWOPORT,        /* refnode */
  1842.    rnTWOPORT,        /* isdevice */
  1843.    create_std,        /* create */
  1844.    copy_std,        /* copy */
  1845.    parse_std,        /* parse */
  1846.    print_std,        /* print */
  1847.    NULL,        /* expand */
  1848.    probe_std,        /* probe */
  1849.    tr_vcvs,        /* dotr */
  1850.    unloadactive,    /* untr */
  1851.    ac_vcvs,        /* doac */
  1852.    trfix1,        /* trfun1 */
  1853.    trfix0,        /* trfun0 */
  1854.    acfix,        /* acfun */
  1855.    NULL,        /* tr_guess */
  1856.    NULL,        /* tr_advance */
  1857.    NULL            /* tr_review */
  1858. };
  1859. /*--------------------------------------------------------------------------*/
  1860. static int tr_vcvs(branch_t *brh)
  1861. {
  1862.  resistor.n = brh->n;
  1863.  resistor.loaditer = 0;
  1864.  resistor.y0.f1 = 1./opt.shortckt;        /* load the resistor */
  1865.  resistor.y0.f0 = LINEAR;            /* a big fudge */
  1866.  resistor.m0.x  = resistor.y0.x;
  1867.  resistor.m0.c0 = 0.;
  1868.  resistor.m0.f1 = resistor.y0.f1;
  1869.  trloadpassive(&resistor);
  1870.  
  1871.                         /* then do vccs */
  1872.  brh->m0.x = tr_volts_limited(&(brh->n[IN1]),&(brh->n[IN2]));
  1873.  brh->y0.x = brh->m0.x;
  1874.  if (brh->f->trfun1){
  1875.     (*brh->f->trfun1)(brh);
  1876.     brh->m0.c0 = (brh->y0.f0 - brh->y0.x * brh->y0.f1) / -opt.shortckt;
  1877.  }else{
  1878.     brh->y0.f1 = brh->val;
  1879.     brh->y0.f0 = brh->y0.x * brh->y0.f1;
  1880.     brh->m0.c0 = 0.;
  1881.  }
  1882.  brh->m0.f1 = brh->y0.f1 / -opt.shortckt;
  1883.  trloadactive(brh);
  1884.  return brh->converged = conv_check(brh);
  1885. }
  1886. /*--------------------------------------------------------------------------*/
  1887. static void ac_vcvs(branch_t *brh)
  1888. {
  1889.  brh->acg.x = 1./opt.shortckt;
  1890.  brh->acg.y = 0.;
  1891.  acloadpassivereal(brh);
  1892.  
  1893.  if (brh->f->acfun){
  1894.     brh->acbias = dc_volts(&(brh->n[IN1]),&(brh->n[IN2]));
  1895.     brh->ev = (*brh->f->acfun)(brh);
  1896.     brh->acg.x = brh->ev.x / -opt.shortckt;
  1897.     brh->acg.y = brh->ev.y / -opt.shortckt;
  1898.  }else{
  1899.     brh->ev.x  = brh->y0.f1;
  1900.     brh->ev.y  = 0.;
  1901.     brh->acg.x = brh->ev.x / -opt.shortckt;
  1902.     brh->acg.y = 0.;
  1903.  }
  1904.  acloadactive(brh);
  1905. }
  1906. /*--------------------------------------------------------------------------*/
  1907. /*--------------------------------------------------------------------------*/
  1908. SHAR_EOF
  1909. fi # end of overwriting check
  1910. if test -f 'src/d_vs.c'
  1911. then
  1912.     echo shar: will not over-write existing file "'src/d_vs.c'"
  1913. else
  1914. cat << \SHAR_EOF > 'src/d_vs.c'
  1915. /* d_vs.c  94.05.30
  1916.  * Copyright 1983-1992   Albert Davis
  1917.  * functions for fixed voltage sources
  1918.  * temporary kluge: it has resistance
  1919.  */
  1920. #include "ecah.h"
  1921. #include "branch.h"
  1922. #include "mode.h"
  1923. #include "options.h"
  1924. #include "declare.h"
  1925. /*--------------------------------------------------------------------------*/
  1926. static     int    tr_vs(branch_t*);
  1927. static     void    ac_vs(branch_t*);
  1928. /*--------------------------------------------------------------------------*/
  1929. extern const struct options opt;
  1930. /*--------------------------------------------------------------------------*/
  1931. functions_t dev_vs = {
  1932.    (generic_t*)NULL,    /* x */
  1933.    sizeof(functions_t),    /* ssize */
  1934.    sizeof(branch_t),    /* elementsize */
  1935.    (functions_t*)NULL,    /* super */
  1936.    2,             /* numnodes */
  1937.    rnONEPORT,        /* refnode */
  1938.    rnNISOURCE,        /* isdevice */
  1939.    create_std,        /* create */
  1940.    copy_std,        /* copy */
  1941.    parse_std,        /* parse */
  1942.    print_std,        /* print */
  1943.    NULL,        /* expand */
  1944.    probe_std,        /* probe */
  1945.    tr_vs,        /* dotr */
  1946.    unloadpassive,    /* untr */
  1947.    ac_vs,        /* doac */
  1948.    trfix1,        /* trfun1 */
  1949.    trfix0,        /* trfun0 */
  1950.    acfix,        /* acfun */
  1951.    NULL,        /* tr_guess */
  1952.    NULL,        /* tr_advance */
  1953.    NULL            /* tr_review */
  1954. };
  1955. /*--------------------------------------------------------------------------*/
  1956. static int tr_vs(branch_t *brh)
  1957. {
  1958.  brh->m0.x = 0.;
  1959.  brh->y0.x = 0.;
  1960.  if (brh->f->trfun1){
  1961.     (*brh->f->trfun1)(brh);
  1962.  }else{
  1963.     brh->y0.f1 = brh->val;
  1964.     brh->y0.f0 = 0.;
  1965.  }
  1966.  brh->m0.f1 = 1./opt.shortckt;
  1967.  brh->m0.c0 = brh->y0.f1 / -opt.shortckt;
  1968.  trloadpassive(brh);
  1969.  return brh->converged = conv_check(brh);
  1970. }
  1971. /*--------------------------------------------------------------------------*/
  1972. static void ac_vs(branch_t *brh)
  1973. {
  1974.  if (brh->f->acfun){
  1975.     brh->acbias = 0.;
  1976.     brh->ev = (*brh->f->acfun)(brh);
  1977.     brh->acg.x = brh->ev.x / -opt.shortckt;
  1978.     brh->acg.y = brh->ev.y / -opt.shortckt;
  1979.     acloadsource(brh);
  1980.  }else{
  1981.     brh->ev.x = brh->ev.y = 0.;    /* a DC only source   */
  1982.  }
  1983.  brh->acg.x = 1./opt.shortckt;
  1984.  brh->acg.y = 0.;
  1985.  acloadpassivereal(brh);
  1986. }
  1987. /*--------------------------------------------------------------------------*/
  1988. /*--------------------------------------------------------------------------*/
  1989. SHAR_EOF
  1990. fi # end of overwriting check
  1991. #    End of shell archive
  1992. exit 0
  1993.