<?xml version="1.0" encoding="ISO-8859-1"?>

<!--
     Written by Laurent Lemaitre - r29173@users.sourceforge.net
     Documentation:
       http://sourceforge.net/docman/display_doc.php?docid=18993&group_id=84289
     Target Interface: ngspice
     Supported by adms-1.x.x
     This file is used by adms - http://sourceforge.net/projects/mot-adms.
     adms is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
     adms is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
     You should have received a copy of the GNU General Public License
     along with adms; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-->

<!DOCTYPE admst SYSTEM "admst.dtd">
<admst version="2.3.0" xmlns:admst="http://mot-adms.sourceforge.net/xml-files/admst">

<admst:template match="dectype">
  <admst:choose>
    <admst:when test="[type='real']">
      <admst:text format="  double "/>
    </admst:when>
    <admst:when test="[type='integer']">
      <admst:text format="  int "/>
    </admst:when>
    <admst:otherwise>
      <admst:text format="  char* "/>
    </admst:otherwise>
  </admst:choose>
</admst:template>

<admst:template match="code">
<admst:value-of select="attribute[name='ngspicename']/value"/>
<admst:variable name="module" select="%s"/>

#ifndef $(module)
#define $(module)

#include &quot;ngspice/cktdefs.h&quot;
#include &quot;ngspice/ifsim.h&quot;
#include &quot;ngspice/gendefs.h&quot;
#include &quot;ngspice/complex.h&quot;
#include &quot;ngspice/noisedef.h&quot;

<admst:for-each select="variable">
<admst:value-of select="name"/>
<admst:variable name="variable" select="%s"/>
#ifdef $(variable)
  #warning conflict: $(variable) is declared as a variable of module '$(module)'.
  #warning conflict: However in the API of ngspice '$(variable)' is also defined as a pragma.
  #warning conflict: Pragma '$(variable)' will be undefined.
  #warning conflict: You can solve the confict by renaming variable '$(variable)' in module '$(module)'.
  #undef $(variable)
#endif
</admst:for-each>
<admst:for-each select="node">
<admst:value-of select="name"/>
<admst:variable name="node" select="%s"/>
#ifdef $(variable)
  #warning conflict: $(node) is declared as a node of module '$(module)'.
  #warning conflict: However in the API of ngspice '$(node)' is also defined as a pragma.
  #warning conflict: Pragma '$(node)' will be undefined.
  #warning conflict: You can solve the confict by renaming variable '$(node)' in module '$(module)'.
  #undef $(variable)
#endif
</admst:for-each>

#ifdef NGSPICE_DEBUG_OK
#define NGSPICE_DEBUG \\
{ \\
  if(getenv(&quot;ngspice_debug&quot;)) \\
    $(module)debug(ckt,model,here); \\
  else \\
  { \\
    printf(&quot;  To get more info run your simulation after setting shell variable ngspice_debug to 1\\n&quot;); \\
    printf(&quot;  For example in sh shell just type: export ngspice_debug=1\\n&quot;); \\
  } \\
}
#else
#define NGSPICE_DEBUG
#endif

#define EXIT_IF_ISNAN(var) \\
if(isnan((double) var)) \\
{ \\
  printf(&quot;%%s:%%i:bug:isnan:&quot;#var&quot;\\n&quot;,__FILE__,__LINE__); \\
  printf(&quot;Please send this message to laurent.lemaitre@freescale.com\\n&quot;); \\
  NGSPICE_DEBUG \\
  exit(1); /*__asm__ __volatile__ (&quot;int \$03&quot;);*/ \\
} \\
if(isinf((double) var)) \\
{ \\
  printf(&quot;%%s:%%i:bug:isinf:&quot;#var&quot;\\n&quot;,__FILE__,__LINE__); \\
  printf(&quot;Please send this message to laurent.lemaitre@freescale.com\\n&quot;); \\
  NGSPICE_DEBUG \\
  exit(1); /*__asm__ __volatile__ (&quot;int \$03&quot;);*/ \\
}

/* ngspice \$simparam variables
    gdev                (1/Ohms): Additional conductance to be added to nonlinear branches for conductance homotopy convergence algorithm.
    gmin                (1/Ohms): Minimum conductance placed in parallel with nonlinear branches.
    imax                (Amps)  : Branch current threshold above which the constitutive relation of a nonlinear branch should be linearized.
    imelt               (Amps)  : Branch current threshold indicating device failure.
    iteration                   : Iteration number of the analog solver.
    scale                       : Scale factor for device instance geometry parameters.
    shrink                      : Optical linear shrink factor.
    simulatorSubversion         : The simulator sub-version.
    simulatorVersion            : The simulator version.
    sourceScaleFactor           : Multiplicative factor for independent sources for source stepping homotopy convergence algorithm.
    tnom degrees       (Celsius): Default value of temperature at which model parameters were extracted.
*/

#define _circuit_gdev                ckt-&gt;CKTgmin
#define _circuit_gmin                ((ckt-&gt;CKTgmin)&gt;(ckt-&gt;CKTdiagGmin))?(ckt-&gt;CKTgmin):(ckt-&gt;CKTdiagGmin)
#define _circuit_imax                1.0
#define _circuit_imelt               1.0
#define _circuit_iteration           1.0
#define _circuit_scale               1.0
#define _circuit_shrink              1.0
#define _circuit_simulatorSubversion 0
#define _circuit_simulatorVersion    3.5
#define _circuit_sourceScaleFactor   1.0
#define _circuit_tnom                ckt-&gt;CKTnomTemp

#define _circuit_temp      ckt-&gt;CKTtemp
#define _scale             1.0

#define _cos(val,arg)            val = cos(arg);
#define _d_cos(val,dval,arg)     val = cos(arg);     dval = (-sin(arg));
#define _sin(val,arg)            val = sin(arg);
#define _d_sin(val,dval,arg)     val = sin(arg);     dval = (cos(arg));
#define _tan(val,arg)            val = tan(arg);
#define _d_tan(val,dval,arg)     val = tan(arg);     dval = (1.0/cos(arg)/cos(arg));
#define _hypot(xy,x,y)           xy = sqrt((x)*(x)+(y)*(y));
#define _dx_hypot(dx,xy,x,y)     dx = (x)/(xy);
#define _dy_hypot(dy,xy,x,y)     dy = (y)/(xy);
#define _max(xy,x,y)             xy = ((x)&gt;(y))?(x):(y);
#define _dx_max(dx,xy,x,y)       dx = ((x)&gt;(y))?1.0:0.0;
#define _dy_max(dy,xy,x,y)       dy = ((x)&gt;(y))?0.0:1.0;
#define _min(xy,x,y)             xy = ((x)&lt;(y))?(x):(y);
#define _dx_min(dx,xy,x,y)       dx = ((x)&lt;(y))?1.0:0.0;
#define _dy_min(dy,xy,x,y)       dy = ((x)&lt;(y))?0.0:1.0;
#define _cosh(val,arg)           val = cosh(arg);
#define _d_cosh(val,dval,arg)    val = cosh(arg);    dval = (sinh(arg));
#define _sinh(val,arg)           val = sinh(arg);
#define _d_sinh(val,dval,arg)    val = sinh(arg);    dval = (cosh(arg));
#define _tanh(val,arg)           val = tanh(arg);
#define _d_tanh(val,dval,arg)    val = tanh(arg);    dval = (1.0/cosh(arg)/cosh(arg));
#define _acos(val,arg)           val = acos(arg);
#define _d_acos(val,dval,arg)    val = acos(arg);    dval = (-1.0/sqrt(1-arg*arg));
#define _asin(val,arg)           val = asin(arg);
#define _d_asin(val,dval,arg)    val = asin(arg);    dval = (+1.0/sqrt(1-arg*arg));
#define _atan(val,arg)           val = atan(arg);
#define _d_atan(val,dval,arg)    val = atan(arg);    dval = (+1.0/(1+arg*arg));
#define _logE(val,arg)           val = log(arg);
#define _d_logE(val,dval,arg)    val = log(arg);     dval = (1.0/arg);
#define _log10(val,arg)          val = log10(arg);
#define _d_log10(val,dval,arg)   val = log10(arg);   dval = (1.0/arg/log(10));
#define _exp(val,arg)            val = exp(arg);
#define _d_exp(val,dval,arg)     val = exp(arg);     dval = val;
#define _sqrt(val,arg)           val = sqrt(arg);
#define _d_sqrt(val,dval,arg)    val = sqrt(arg);    dval = (1.0/val/2.0);
#define _pow(xy,x,y)             xy = pow(x,y);
#define _dx_pow(dx,xy,x,y)       dx = (x==0.0)?0.0:((y/x)*xy);
#define _dy_pow(dy,xy,x,y)       dy = (x==0.0)?0.0:((log(x)/exp(0.0))*xy);

#define _div1(x,y)               ((x)/(y))
#define _div0(xy,x,y)            xy=(x)/(y);
#define _div(xy,dx,x,y)          dx=1/(y); xy=(x)*dx;
#define _dx_div(dx,xy,x,y)
#define _dy_div(dy,dx,xy,x,y)    dy = -xy*dx;

#define _limexp(val,arg)         val = ((arg)&lt;(90)) ? (exp(arg)) : (exp(90)*(1.0+(arg-90)));
#define _d_limexp(val,dval,arg)  val = ((arg)&lt;(90)) ? (exp(arg)) : (exp(90)*(1.0+(arg-90))); dval = val;
#define _fabs(val,arg)           val = fabs(arg);
#define _d_fabs(val,dval,arg)    val = fabs(arg);    dval = (((val)&gt;=0)?(+1.0):(-1.0));
#define _abs(val)                ((val)&lt;(0) ? (-(val)):(val))

/* declarations for $(module) MOSFETs */

/* information needed for each instance */
typedef struct s$(module)instance {
  struct s$(module)model *$(module)modPtr;           /* pointer to model */
  struct s$(module)instance *$(module)nextInstance;  /* pointer to next instance of current model*/
  IFuid $(module)name; /* pointer to character string naming this instance */
  int $(module)state; /* index into state table for this device */

  /* node */
<admst:for-each select="node[grounded='no']">
  <admst:value-of select="name"/>
  <admst:text format="  int %sNode;"/>
  <admst:if test="attribute[name='info']">
    <admst:value-of select="."/>
    <admst:text format="  /*%s*/"/>
  </admst:if>
  <admst:text format="\n"/>
</admst:for-each>
  /* instance parameters */
<admst:for-each select="variable[parametertype='instance' and input='yes']">
  <admst:value-of select="name"/>
  <admst:value-of select="name"/>
  <admst:apply-templates select="." match="dectype"/>
  <admst:text format="%s;\n"/>
  <admst:text format="  unsigned %s_Given  :1;"/>
  <admst:if test="attribute[name='info']">
    <admst:value-of select="."/>
    <admst:text format="  /*%s*/"/>
  </admst:if>
  <admst:text format="\n"/>
</admst:for-each>
 // noise\n
  <admst:text select="$fnoise/item" format="  double fpnoise%(index($fnoise/item,.)), fenoise%(index($fnoise/item,.));\n"/>
  <admst:text select="$tnoise/item" format="  double tnoise%(index($tnoise/item,.));\n"/>
  <admst:text select="$wnoise/item" format="  double wnoise%(index($wnoise/item,.));\n"/>

  /* variables */
<admst:for-each select="variable[input='no' and scope='global_instance']">
  <admst:value-of select="name"/>
  <admst:apply-templates select="." match="dectype"/>
  <admst:text format="%s;\n"/>
  <admst:for-each select="attribute[name='info']">
    <admst:value-of select="."/>
    <admst:text format="  /*%s*/"/>
  </admst:for-each>
</admst:for-each>
  /* states */
<admst:for-each select="source[dynamic='yes']">
  <admst:value-of select="branch/nnode/name"/>
  <admst:value-of select="branch/pnode/name"/>
  <admst:text format="  int state_%s_%s;\n"/>
</admst:for-each>
  /* pointer to sparse matrix (+ values)*/
<admst:for-each select="jacobian">
  <admst:value-of select="column/name"/>
  <admst:value-of select="row/name"/>
  <admst:text format="  double *PTR_J_%s_%s;\n"/>
  <admst:value-of select="column/name"/>
  <admst:value-of select="row/name"/>
  <admst:text format="    int PTR_J_%s_%s_required;\n"/>
  <admst:if test="[static='yes']">
    <admst:value-of select="column/name"/>
    <admst:value-of select="row/name"/>
    <admst:text format="    double JSVAL_%s_%s;\n"/>
  </admst:if>
  <admst:if test="[dynamic='yes']">
    <admst:value-of select="column/name"/>
    <admst:value-of select="row/name"/>
    <admst:text format="    double JDVAL_%s_%s;\n"/>
  </admst:if>
</admst:for-each>

#define $(module)numStates 0

} $(module)instance ;


/* per model data */

typedef struct s$(module)model {         /* model structure */
  int $(module)modType;        /* type index of this device type */
  struct s$(module)model *$(module)nextModel; /* pointer to next possible model in linked list */
  $(module)instance * $(module)instances;  /* pointer to list of instances that have this model */
  IFuid $(module)modName;         /* pointer to the name of this model */

  /* --- end of generic struct GENmodel --- */

  /* model parameters */
  <admst:for-each select="variable[parametertype='model' and input='yes']">
    <admst:value-of select="name"/>
    <admst:value-of select="name"/>
    <admst:apply-templates select="." match="dectype"/>
    <admst:text format="%s;\n"/>
    <admst:text format="  unsigned %s_Given  :1;"/>
    <admst:if test="attribute[name='info']">
      <admst:value-of select="."/>
      <admst:text format="  /*%s*/"/>
    </admst:if>
    <admst:text format="\n"/>
  </admst:for-each>
  /* variable */
  <admst:for-each select="variable[input='no' and scope='global_model']">
    <admst:value-of select="name"/>
    <admst:apply-templates select="." match="dectype"/>
    <admst:text format="%s;\n"/>
    <admst:for-each select="attribute[name='info']">
      <admst:value-of select="."/>
      <admst:text format="  /*%s*/"/>
    </admst:for-each>
  </admst:for-each>

} $(module)model;

  <admst:text format="  /* flags */\n"/>
  <admst:text format="typedef enum {\n"/>
  <admst:for-each select="variable[parametertype='model' and input='yes']">
    <admst:value-of select="name"/>
    <admst:text format="  $(module)_model_%s,\n"/>
  </admst:for-each>
    <admst:text format="  DUMMY_MODEL"/>
  <admst:text format="\n} e_$(module)_model;\n"/>
  <admst:text format="typedef enum {\n"/>
  <admst:for-each select="variable[parametertype='instance' and input='yes']">
    <admst:value-of select="name"/>
    <admst:text format="  $(module)_instance_%s,\n"/>
  </admst:for-each>
  <admst:text format="  DUMMY_INSTANCE"/>
  <admst:text format="\n} e_$(module)_instance;\n"/>

<admst:value-of select="attribute[name='ngspicename']/value"/>
<admst:variable name="module" select="%s"/>

#include &quot;$(module)ext.h&quot;
<admst:if test="[not(nilled(analogfunction))]">
#include &quot;analogfunction.h&quot;
</admst:if>

#endif /*$(module)*/

</admst:template>

<admst:for-each select="/module">
  <admst:value-of select="attribute[name='ngspicename']/value"/>
  <admst:open file="%sdefs.h">
    <admst:value-of select="/simulator/package_string"/>
    <admst:text format="/***\n*** Interface: %s\n"/>
    <admst:value-of select="/simulator/currentdate"/>
    <admst:value-of select="/simulator/fullname"/>
    <admst:text format=" *** created by: %s - %s ***/\n"/>
    <admst:apply-templates select="." match="code"/>
  </admst:open>
  <admst:value-of select="attribute[name='ngspicename']/value"/>
  <admst:message format="%sdefs.h: file created\n"/>
</admst:for-each>

</admst>
