text: %
  % Description -- Verilog-AMS interface
  %
  % Copyright (C) 2007 Stefan Jahn <stefan@lkcc.org>
  %
  % Permission is granted to copy, distribute and/or modify this document
  % under the terms of the GNU Free Documentation License, Version 1.1
  % or any later version published by the Free Software Foundation.
  %
  
  \tutsection{Introduction}
  
  Verilog-AMS is a hardware description language.  It can be used to
  specify the analogue behaviour of compact device models.  Usually
  these are C or C++ implementations in analogue simulators.  The effort
  to implement modern compact models in C/C++ is quite high compared to
  the description in Verilog-AMS.
  
  \tutsection{ADMS}
  
  The software ADMS (see \url{http://mot-adms.sourceforge.net}) allows
  Verilog-AMS descriptions to be translated into any other programming
  language.  It generates a structured XML tree representing the compact
  device model description.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.8\linewidth]{admsflow}
  \end{center}
  \caption{ADMS data flow}
  \label{fig:admsflow}
  \end{figure}
  \FloatBarrier
  
  The internal XML tree is used to generate ready-to-compile C or C++
  code which is specific to the simulators API.  The code generator is
  able to produce
  \begin{itemize}
  \item evaluation of device equations (current and charge) including
  their derivatives,
  \item glue code for the simulator API,
  \item documentation and
  \item any other data described by the original Verilog-AMS input file.
  \end{itemize}
  
  \tutsection{XML admst scripts}
  
  The language transformation uses a language named \textbf{admst}.  It
  is itself a XML description.  The command line in order to run a
  transformation is
  \begin{Verbatim}[fontsize=\small]
    $ admsXml <device.va> -e <interface-1.xml> -e <interface-2.xml>
  \end{Verbatim}
  
  From version 0.0.11 Qucs comes with the following Verilog-AMS
  transformers
  \begin{itemize}
  \item \verb+qucsMODULEcore.xml+\\
  creating the actual analogue simulator implementation
  \item \verb+qucsMODULEdefs.xml+\\
  creating the parameter descriptions for the analogue simulator
  \item \verb+qucsMODULEgui.xml+\\
  creating the implementation for the GUI integration
  \item \verb+qucsVersion.xml+\\
  basic admst library
  \item \verb+analogfunction.xml+\\
  creating analogue function code
  \end{itemize}
  
  In order to create \textbf{admst} scripts for a simulator it is
  necessary to understand both, the simulator specific API and how the
  ADMS data tree items -- which are based on the Verilog-AMS source file
  describing the model -- relate to the API.
  
  \addvspace{12pt}
  
  The command lines for transforming a Verilog-AMS source file into the
  appropiate Qucs C++ source files are
  \begin{Verbatim}[fontsize=\small]
    $ admsXml <device.va> -e qucsVersion.xml -e qucsMODULEcore.xml
    $ admsXml <device.va> -e qucsVersion.xml -e qucsMODULEgui.xml
    $ admsXml <device.va> -e qucsVersion.xml -e qucsMODULEdefs.xml
    $ admsXml <device.va> -e analogfunction.xml
  \end{Verbatim}
  
  each creating an appropriate \verb+*.cpp+ and \verb+*.h+ file.
  
  \addvspace{12pt}
  
  The \textbf{admst} language is used to traverse the internal tree.
  The tree's root is defined by the Verilog-AMS module definition.
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  module device (node1, node2, ...)
    // module definitions and code
  endmodule
  \end{lstlisting}
  
  \tutsubsection{Short introduction into the \textbf{admst} language syntax}
  
  Usually the \textbf{admst} language instructions are basically formed
  as
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:instruction argument=...>
    ...
  </admst:instruction>
  \end{lstlisting}
  or
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:instruction argument=.../>
  \end{lstlisting}
  
  Any other text outside these instruction is output to the console or
  into an appropriate file.  Some of the most important language
  construct are listed below.
  
  \begin{itemize}
  
  \item
  Traversing a list: The construct allows to traverse all children of
  the selected branch.
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:for-each select="/module">
    ...
  </admst:for-each>
  \end{lstlisting}
  
  \item
  Defining and using variables: Values from the data tree can be put
  into named and typed variables which are then accessible using the \$
  operator.
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:value-of select="name">
  <admst:variable name="module" select="%s">
  \end{lstlisting}
  
  \item
  Opening a file: Printed text (see below) is output into the given
  file.
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:open file="$module.cpp">
    ...
  </admst:open>
  \end{lstlisting}
  
  \item
  Output text: Special characters must be encoded (e.g. \verb+"+ $\rightarrow$
  \verb+&quot;+ \verb+<+ $\rightarrow$ \verb+&lt;+ \verb+>+
  $\rightarrow$ \verb+&gt+; and \verb+\n+ $\rightarrow$ \verb+\\n+).
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:text format="This is a text."/>
  \end{lstlisting}
  
  \item
  Definition of a function:  Functions in \textbf{admst} are called templates.
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:template match="name_of_function">
    ...
  </admst:template>
  \end{lstlisting}
  
  \item
  Running a function: Templates are applied to parts of the internal
  data tree.
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <admst:apply-templates select="date_tree_root_for_function"
                          match="name_of_function"/>
  \end{lstlisting}
  
  \item Comments:
  \begin{lstlisting}[
    language=XML,
    xleftmargin=12pt,
    morekeywords={admst}]
  <!-- this is a comment -->
  \end{lstlisting}
  
  \end{itemize}
  
  \tutsubsection{Analogue simulator script}
  
  The analogue simulator implementation consists of several parts.  For
  each type of simulation appropriate functions must be implemented.
  \begin{itemize}
  \item DC simulation\\
  \verb+module::initDC (void)+,\\
  \verb+module::restartDC (void)+ and\\
  \verb+module::calcDC (void)+
  \item AC simulation\\
  \verb+module::initAC (void)+ and\\
  \verb+module::calcAC (nr_double_t)+
  \item S-parameter simulation\\
  \verb+module::initSP (void)+ and\\
  \verb+module::calcSP (nr_double_t)+
  \item Transient simulation\\
  \verb+module::initTR (void)+ and\\
  \verb+module::calcTR (nr_double_t)+
  \item AC noise simulation\\
  \verb+module::initNoiseAC (void)+ and\\
  \verb+module::calcNoiseAC (nr_double_t)+
  \item S-parameter noise simulation\\
  \verb+module::initNoiseSP (void)+ and\\
  \verb+module::calcNoiseSP (nr_double_t)+
  \item Harmonic simulation\\
  \verb+module::initHB (int)+ and\\
  \verb+module::calcHB (int)+
  \end{itemize}
  
  These functions go into the \verb+module.core.cpp+ file.  An
  appropriate \verb+module.core.h+ header file is also created.
  
  \addvspace{12pt}
  
  In case the Verilog-AMS source file contains analog functions in the
  module definition, e.g.
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  analog function real name;
    input x;
    real x;
    begin
      name = x * x;
    end
  endfunction
  \end{lstlisting}
  
  the \verb+analogfunction.xml+ script produces the appropriate C/C++
  and header files
  \begin{itemize}
  \item \verb+module.analogfunction.cpp+
  \item \verb+module.analogfunction.h+.
  \end{itemize}
  
  The ADMS language transformer is aware of how analogue simlators solve
  a network of linear and non-linear devices.  The general
  Newton-Raphson algorithm for a DC simulation used in SPICE-like
  simulators as well as in Qucs can be expressed as
  \begin{equation}
  \begin{split}
  \label{eq:nonlinearNR}
  J^{(m)}\cdot V^{(m+1)} &= J^{(m)}\cdot V^{(m)} - f\left(V^{(m)}\right)\\
  &= I_{lin}^{(m)} + I_{nl}^{(m)} - J_{nl}^{(m)}\cdot V^{(m)}
  \end{split}
  \end{equation}
  whereas $J$ denotes the Jacobian
  \begin{equation}
  J^{(m)} = \left.\dfrac{\partial f\left(V\right)}{\partial V}\right|_{V^{(m)}}
  \end{equation}
  
  There are basically two types of contributions supported by ADMS:
  currents and charges.  The appropiate Jacobian matrices are
  \begin{equation}
  J^{(m)}
  = J_I^{(m)} + J_Q^{(m)}
  = \underbrace{\left.\dfrac{\partial I\left(V\right)}{\partial V}\right|_{V^{(m)}}}_{\textrm{``static''}} + \underbrace{\left.\dfrac{\partial Q\left(V\right)}{\partial V}\right|_{V^{(m)}}}_{\textrm{``dynamic''}}
  = G + C
  \end{equation}
  consisting of two real valued matrices $G$
  (conductance/transconductance matrix) and $C$
  (capacitance/transcapacitance matrix).
  
  \addvspace{12pt}
  
  In the Verilog-AMS desciptions only the current and charge
  contributions are mentioned.  The appropriate derivatives are meant to
  be automatically formed by the language translator ADMS.
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
    I(ci,ei) <+ it;       // current contribution
    I(si,ci) <+ ddt(Qjs); // charge contribution
  \end{lstlisting}
  
  The right-hand side of eq.~\eqref{eq:nonlinearNR} consists of the
  linear and non-linear currents of the network as well as the Jacobian
  matrix multiplied by the voltage vector.  Since devices are usually
  uncorrelated both parts can be computed directly on a per device
  basis.
  
  \tutsubsection{Current limitations of ADMS}
  
  The following section contains some simple examples demonstrating
  which Verilog-AMS statements can be successfully handled by ADMS and
  which not.
  
  \tutsubsubsection{Example 1}
  
  There was a bug in the \textbf{admst} scripts.  They failed to place
  the function calls of analogue functions correctly.  This has been
  fixed.
  
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  module diode(a, c);  
    inout a, c;
    electrical a, c;
  
    analog function real current;
      input is, v;
      begin
        current = is * (exp (v / 26e-3) - 1);
      end
    endfunction
  
    real Vd;
    real Id;
  
    analog begin
      Vd = V(a, c);
      Id = current (1e-15, Vd);
      I(a, c) <+ Id;
    end
  
  endmodule
  \end{lstlisting}
  
  \tutsubsubsection{Example 2}
  
  It is not allowed to mix current and charge contributions in
  assignments.  Mixing both emits wrong C/C++ code.  It accounts the
  current to be a charge in this case.
  
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  module diode(a, c);  
    inout a, c;
    electrical a, c;
  
    real Vd, Id, Is, Cp;
  
    analog begin
      Is = 1e-15;
      Cp = 1e-12;
      Vd = V(a, c);
      Id = Is * (exp (Vd / 26e-3) - 1);
  
      // not allowed in ADMS
      I(a, c) <+ Id + ddt(Cp*V(a,c));
  
      // allowed in ADMS
      I(a, c) <+ Id;
      I(a, c) <+ ddt(Cp*V(a,c));
    end
  
  endmodule
  \end{lstlisting}
  
  \tutsubsubsection{Example 3}
  
  The following example is rejected by the \textbf{admst} scripts with
  this error message.
  
  \begin{Verbatim}[fontsize=\small]
    [info] admsXml-2.2.4 Oct 18 2006 19:50:46
    [fatal] qucsVersion.xml:1497:admst:if[lhs]: missing node source/insource
  \end{Verbatim}
  
  An immediate potential on the right hand side is not allowed embedded
  in a function.
  
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  module diode(a, c);  
    inout a, c;
    electrical a, c;
  
    real Id, Is;
  
    analog begin
      Is = 1e-15;
      Id = Is * (exp (V(a, c) / 26e-3) - 1);
  
      // not allowed in ADMS
      I(a, c) <+ Is * (exp (V(a, c) / 26e-3) - 1);
  
      // allowed in ADMS
      I(a, c) <+ Id;
    end
  
  endmodule
  \end{lstlisting}
  
  \tutsubsubsection{Example 4}
  
  Potentials on the left-hand side of contribution assignments are not
  allowed.  This kind of assignment emits wrong C/C++ code.
  
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  module diode(a, c);  
    inout a, c;
    electrical a, c;
  
    real Id, Is;
    real Rp;
  
    analog begin
      Rp = 1e9;
      Is = 1e-15;
      Id = Is * (exp (V(a, c) / 26e-3) - 1);
      I(a, c) <+ Id;
  
      // allowed in ADMS
      I(a, c) <+ V(a, c) / Rp;
  
      // not allowed in ADMS
      V(a, c) <+ I(a, c) * Rp;
    end
  
  endmodule
  \end{lstlisting}
  
  \tutsubsection{Code for the GUI integration}
  
  The \textbf{admst} script for the GUI creates files according to its
  API.  Basically it produces the list of parameters as well their
  descriptions (if available) in a property list.  Additionally the
  symbol drawing code is emitted which should be adapted to the devices
  requirements.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.9\linewidth]{componentdialog}
  \end{center}
  \caption{component property dialog in the GUI}
  \label{fig:componentdialog}
  \end{figure}
  \FloatBarrier
  
  In fig.~\ref{fig:componentdialog} the component property dialog of an
  implemented device is shown.  In the schematic in
  fig.~\ref{fig:hicumschematic} the symbol for the HICUM model is
  surrounded with a red circle.  The GUI code is also responsible for
  the icons in the listview on the left hand side of the figure.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=1\linewidth]{hicumschematic}
  \end{center}
  \caption{schematic with the HICUM transistor symbol}
  \label{fig:hicumschematic}
  \end{figure}
  \FloatBarrier
  
  \tutsection{Adding Verilog-AMS devices to Qucs}
  
  The section gives an overview how to add a Verilog-AMS model to Qucs
  in a step-by-step manner.  Be aware that the description is meant for
  advanced users partly familiar with the usual GNU/Linux build system
  and C/C++ programming.
  
  \tutsubsection{The Verilog-AMS source file}
  
  The starting point of a new Verilog-AMS model in Qucs is the
  Verilog-AMS source file which must be aware of the discussed ADMS
  limitations.  The example we are going to discuss is a simple diode
  model shown in the following listing contained in the
  \textbf{diode.va} file.
  
  \begin{lstlisting}[
    language=Verilog,
    xleftmargin=12pt]
  `include "disciplines.vams"
  `include "constants.vams"
  
  // ADMS specific definitions 
  `define attr(txt) (*txt*) 
  
  module diode(a, c);  
    // device terminals
    inout a, c;
    electrical a, c;
  
    // internal node
    electrical ci;
  
    // model parameters
    parameter real Is   = 1E-15 from [0:1]
      `attr(info="saturation current");
    parameter real Cp   = 1E-12 from [0:1]
      `attr(info="parallel capacitance");
    parameter real Rs   = 1.0   from (0:inf)
      `attr(info="series resistance");
    parameter real Temp = 300   from (0:inf)
     `attr(info="temperature");
  
    real Vd, Id, fourkt, twoq, Qp;
  
    analog begin
      Vd = V(a, ci);
      Id = Is * (exp (Vd / 26e-3) - 1);
      Qp = Cp * Vd;
  
      I(a, ci) <+ Id;
      I(a, ci) <+ ddt(Qp);
      I(ci, c) <+ V(ci, c) / Rs;
  
    begin : noise
      fourkt  = 4.0 * `P_K * Temp;
      twoq    = 2.0 * `P_Q;
      I(ci, c) <+ white_noise(fourkt/Rs, "thermal");
      I(a, ci) <+ white_noise(twoq*Id, "shot");
    end // noise
  
    end // analog
  
  endmodule
  \end{lstlisting}
  
  \tutsubsection{Integrating the model into the analogue simulator}
  
  The qucs-core tree of Qucs must be configured using the
  --enable-maintainer-mode option.
  \begin{Verbatim}[fontsize=\small]
    $ ./configure --enable-maintainer-mode --prefix=/tmp
  \end{Verbatim}
  
  The source trees of qucs (GUI) as well as qucs-core (simulator) are
  within the release tarballs available at
  \url{http://qucs.sourceforge.net/download.html}.  During development
  of new Verilog-A models it is recommended to use CVS.  Latest CVS
  trees of qucs and qucs-core can be obtained using the following
  command lines.
  \begin{Verbatim}[fontsize=\small]
      $ cvs -z3 -d:pserver:anonymous@qucs.cvs.sourceforge.net:/cvsroot/qucs \
        co qucs-core
      $ cvs -z3 -d:pserver:anonymous@qucs.cvs.sourceforge.net:/cvsroot/qucs \
        co qucs
  \end{Verbatim}
  
  Also the software \textbf{adms} must be installed.  It is available at
  \url{http://sourceforge.net/projects/mot-adms}.
  
  \addvspace{12pt}
  
  The file \textbf{diode.va} must be copied into the source tree.
  \begin{Verbatim}[fontsize=\small]
    $ cp diode.va qucs-core/src/components/verilog/
  \end{Verbatim}
  
  In this directory (qucs-core/src/components/verilog/) the Verilog
  model can be checked if it can be translated successfully using the
  following command lines.
  \begin{Verbatim}[fontsize=\small]
    $ admsXml diode.va -e qucsVersion.xml -e qucsMODULEcore.xml
    [info] admsXml-2.2.4 Oct 18 2006 19:50:46
    [info] diode.core.cpp and diode.core.h: files created
    [info] elapsed time: 0.0339946
    [info] admst iterations: 4146 (4146 freed)
    $ admsXml diode.va -e analogfunction.xml
    [info] admsXml-2.2.4 Oct 18 2006 19:50:46
    [info] diode.analogfunction.h created
    [info] diode.analogfunction.cpp created
    [info] elapsed time: 0.0262961
    [info] admst iterations: 3919 (3919 freed)
  \end{Verbatim}
  
  These command lines create the files for the model evaluation code.
  The file names (diode.*) are due to the name of the module contained
  in the Verilog-AMS source file.
  
  \addvspace{12pt}
  
  Additionally the source code must be changed in some more locations.
  \begin{itemize}
  \item \Verb+src/components/component.h+\\
  In this file it is necessary to add the line
  \begin{Verbatim}[fontsize=\small]
    #include "verilog/diode.core.h"
  \end{Verbatim}
  \item \Verb+src/components/component_id.h+\\
  The file contains unique component identifiers.  It is necessary to
  add the Verilog modules name.
  \begin{Verbatim}[fontsize=\small]
    enum circuit_type {
      CIR_UNKNOWN = -1,
      ...
      // verilog devices
      CIR_diode,
      ...
    };
  \end{Verbatim}
  \item \Verb+src/input.cpp+\\
  In order to be able to instantiate the new model the file must be
  modified as follows.
  \begin{Verbatim}[fontsize=\small]
    // The function creates components specified by the type of component. 
    circuit * input::createCircuit (char * type) {
      if (!strcmp (type, "Pac"))
        return new pac ();
      ...
      else if (!strcmp (type, "diode"))
        return new diode ();
  
      logprint (LOG_ERROR, "no such circuit type `%s'\n", type);
      return NULL;
    }
  \end{Verbatim}
  \item \Verb+src/qucsdefs.h+\\
  Finally the properties including their range definitions must be added
  to this file.  The appropiate file can be obtained using the following
  command line.
  \begin{Verbatim}[fontsize=\small]
    $ admsXml diode.va -e qucsVersion.xml -e qucsMODULEdefs.xml
    [info] admsXml-2.2.4 Oct 18 2006 19:50:46
    [info] diode.defs.h: file created
    [info] elapsed time: 0.0335337
    [info] admst iterations: 4294 (4294 freed)
  \end{Verbatim}
  The emitted file \textbf{diode.defs.h} looks like
  \begin{Verbatim}[fontsize=\small]
    /* diode verilog device */
    { "diode", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_NONLINEAR,
      {
        { "Is", PROP_REAL, { 1E-15, PROP_NO_STR }, { '[', 0, 1, ']' } },
        { "Cp", PROP_REAL, { 1E-12, PROP_NO_STR }, { '[', 0, 1, ']' } },
        { "Rs", PROP_REAL, { 1.0, PROP_NO_STR }, { ']', 0, 0, '.' } },
        { "Temp", PROP_REAL, { 300, PROP_NO_STR }, { ']', 0, 0, '.' } },
        PROP_NO_PROP },
      { PROP_NO_PROP }
    },
  \end{Verbatim}
  representing the parameters defined in the original Verilog-AMS file.
  This excerpt must be included in the \textbf{src/qucsdefs.h} file into
  this structure:
  \begin{Verbatim}[fontsize=\small]
    // List of available components.
    struct define_t qucs_definition_available[] =
    {
      ...
      /* end of list */
      { NULL, 0, 0, 0, 0, { PROP_NO_PROP }, { PROP_NO_PROP } }
    };
  \end{Verbatim}
  \end{itemize}
  
  Finally the \textbf{Makefile.am} in the
  \textbf{src/components/verilog/} directory must be adjusted to make
  the build-system aware of the new component.  There must be added
  \begin{Verbatim}[fontsize=\small]
    libverilog_a_SOURCES = ... \
            diode.analogfuncction.cpp diode.core.cpp
  
    noinst_HEADERS = ... \
            diode.analogfuncction.h diode.core.h
  
    VERILOG_FILES = ... diode.va
  
    if MAINTAINER_MODE
    ...
    diode.analogfunction.cpp: analogfunction.xml
    diode.analogfunction.cpp: diode.va
            $(ADMSXML) $< -e analogfunction.xml
    diode.core.cpp: qucsVersion.xml qucsMODULEcore.xml
    diode.core.cpp: diode.va
            $(ADMSXML) $< -e qucsVersion.xml -e qucsMODULEcore.xml
    diode.defs.h: qucsVersion.xml qucsMODULEdefs.xml
    diode.defs.h: diode.va
            $(ADMSXML) $< -e qucsVersion.xml -e qucsMODULEdefs.xml
    diode.gui.cpp: qucsVersion.xml qucsMODULEgui.xml
    diode.gui.cpp: diode.va
            $(ADMSXML) $< -e qucsVersion.xml -e qucsMODULEgui.xml
    ...
    else
  \end{Verbatim}
  in order to create the correct build rules.
  
  \addvspace{12pt}
  
  If everything worked fine then the new Verilog-AMS model is now
  completely integrated into the analogue simulator.
  
  \tutsubsection{Integrating the model into the GUI}
  
  Very likely as the qucs-core tree in the previous section also the
  qucs source tree must be configured using the --enable-maintainer-mode
  option.
  \begin{Verbatim}[fontsize=\small]
    $ ./configure --enable-maintainer-mode --prefix=/tmp
  \end{Verbatim}
  
  Still in the \textbf{qucs-core/src/components/verilog} directory it is
  now necessary to create the C++ code for the GUI using the following
  command line.
  
  \begin{Verbatim}[fontsize=\small]
    $ admsXml diode.va -e qucsVersion.xml -e qucsMODULEgui.xml
    [info] admsXml-2.2.4 Oct 18 2006 19:50:46
    [info] diode.gui.cpp and diode.gui.h: files created
    [info] elapsed time: 0.0345217
    [info] admst iterations: 4146 (4146 freed)
  \end{Verbatim}
  
  Both the created files \textbf{diode.gui.cpp} and \textbf{diode.gui.h}
  should be copied to the \textbf{qucs/qucs/components} directory.
  
  \addvspace{12pt}
  
  Depending on the type of device several changes must be applied to
  these files.  The constructor will basically contain the properties of
  the device as they are going to occur in the component property dialog
  as depicted in fig.~\ref{fig:componentdialog}.  Check these if they
  are complete or if some can be left.
  \begin{lstlisting}[
    language=C++,
    basicstyle=\small,
    xleftmargin=12pt]
  diode::diode()
  {
    Description = QObject::tr ("diode verilog device");
  
    Props.append (new Property ("Is", "1E-15", false,
      QObject::tr ("saturation current")));
    Props.append (new Property ("Cp", "1E-12", false,
      QObject::tr ("parallel capacitance")));
    Props.append (new Property ("Rs", "1.0", false,
      QObject::tr ("series resistance")));
    Props.append (new Property ("Temp", "300", false,
      QObject::tr ("temperature")));
    ...
  }
  \end{lstlisting}
  
  The \textbf{diode::info} function should be adapted to meet the
  devices requirements.  The \textbf{BitmapFile} should be changed to
  represent a correct PNG file in the \textbf{qucs/bitmaps} directory.
  Both the \textbf{Name} and the bitmap are going to appear in the
  left-hand component tab as shown in fig.~\ref{fig:hicumschematic}.
  
  \begin{lstlisting}[
    language=C++,
    basicstyle=\small,
    xleftmargin=12pt]
  Element * diode::info(QString& Name, char * &BitmapFile,
                        bool getNewOne)
  {
    Name = QObject::tr("Diode");
    BitmapFile = "diode";
  
    if(getNewOne) return new diode();
    return 0;
  }
  \end{lstlisting}
  
  The \textbf{diode::info\_pnp()} method can be completely deleted.  It
  can be necessary for bipolar transistors where two types of devices
  could be displayed (npn and pnp type).  The method must also be
  deleted from the header file.  Also, in this case, the new diode class
  inherits \textbf{Component} instead of \textbf{MultiViewComponent}.
  
  \addvspace{12pt}
  
  The \textbf{diode::createSymbol()} method must be adapted to represent
  a valid schematic symbol.  Anyway, the default code can be used as a
  template.
  \begin{lstlisting}[
    language=C++,
    basicstyle=\small,
    xleftmargin=12pt]
  void diode::createSymbol()
  {
    // normal bipolar
    Lines.append(new Line(-10,-15,-10, 15,QPen(QPen::darkBlue,3)));
    Lines.append(new Line(-30,  0,-10,  0,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(-10, -5,  0,-15,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(  0,-15,  0,-30,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(-10,  5,  0, 15,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(  0, 15,  0, 30,QPen(QPen::darkBlue,2)));
  
    // substrate node
    Lines.append(new Line(  9,  0, 30,  0,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(  9, -7,  9,  7,QPen(QPen::darkBlue,3)));
  
    // thermal node
    Lines.append(new Line(-30, 20,-20, 20,QPen(QPen::darkBlue,2)));
    Lines.append(new Line(-20, 17,-20, 23,QPen(QPen::darkBlue,2)));  
  
    // arrow
    if(Props.getFirst()->Value == "npn") {
      Lines.append(new Line( -6, 15,  0, 15,QPen(QPen::darkBlue,2)));
      Lines.append(new Line(  0,  9,  0, 15,QPen(QPen::darkBlue,2)));
    } else {
      Lines.append(new Line( -5, 10, -5, 16,QPen(QPen::darkBlue,2)));
      Lines.append(new Line( -5, 10,  1, 10,QPen(QPen::darkBlue,2)));
    }
  
    // terminal definitions
    Ports.append(new Port(  0,-30)); // collector
    Ports.append(new Port(-30,  0)); // base
    Ports.append(new Port(  0, 30)); // emitter
    Ports.append(new Port( 30,  0)); // substrate
    Ports.append(new Port(-30, 20)); // thermal node
  
    // relative boundings
    x1 = -30; y1 = -30;
    x2 =  30; y2 =  30;
  }
  \end{lstlisting}
  
  In order to test the component in the GUI it is necessary to modify
  some more source code files.
  \begin{itemize}
  \item \Verb+qucs/qucs.cpp+\\
  In this file the new Verilog device will be made available to the
  component tab.  If a new non-linear device is added then place it here:
  \begin{Verbatim}[fontsize=\small]
    pInfoFunc nonlinearComps[] =
      { ... &diode::info, 0};
  \end{Verbatim}
  \item \Verb+qucs/components/component.cpp+\\
  The new verilog device must be loadable in the GUI.  So in the function
  \textbf{getComponentFromName()} add this:
  \begin{Verbatim}[fontsize=\small]
    Component* getComponentFromName(QString& Line)
    {
      ...
      case 'd' : if(cstr == "iode") c = new diode();
            break;
      ...
      return c;
    }
  \end{Verbatim}
  \item \Verb+qucs/components/components.h+\\
  In the component header file it is necessary to add:
  \begin{Verbatim}[fontsize=\small]
    #include "diode.h"
  \end{Verbatim}
  \end{itemize}
  
  In order to make the build-sytem aware of the new Verilog model the
  file \textbf{qucs/components/Makefile.am} must be modified in the
  following way.
  \begin{Verbatim}[fontsize=\small]
    libcomponents_a_SOURCES = ... \
      diode.gui.cpp
  
    noinst_HEADERS = ... \
      diode.gui.h
  \end{Verbatim}
  
  With these steps the component is now fully integrated into the GUI.  
  
  \tutsection{Implemented devices}
  
  The following sections presents the models already added in Qucs
  including some test schematics and simulation results.
  
  \tutsubsection{HICUM/L2 v2.11 model}
  
  The name HICUM was derived from HIgh-CUrrent Model, indicating that
  HICUM initially was developed with special emphasis on modelling the
  operating region at high current densities which is very important for
  certain high-speed applications.
  
  \addvspace{12pt}
  
  The Verilog-AMS source code can be obtained from
  \url{http://www.iee.et.tu-dresden.de/iee/eb/hic_new/hic_source.html}.
  The model used in Qucs was a bit modified due to some ADMS
  limitations.
  
  \addvspace{12pt}
  
  Some schematics have been setup to verify that the model emits
  basically the correct output values and the source code translations
  worked properly.
  
  \tutsubsubsection{DC simulation}
  
  The setup for the forward Gummel plot is depicted in
  fig.~\ref{fig:fgummel}.  The base-emitter voltage is swept ($V_{BE} =
  0.2\dots 1.2$) with a constant voltage across the second diode $V_{BC}
  = 0$.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.7\linewidth]{fgummel}
  \end{center}
  \caption{forward Gummel plot schematic for HICUM/L2 v2.11 model}
  \label{fig:fgummel}
  \end{figure}
  \FloatBarrier
  
  In fig.~\ref{fig:fgummel_dpl} the logarithmic Gummel plot is shown
  including the ratio between the base current and collector current on
  the secondary axis.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.8\linewidth]{fgummel_dpl}
  \end{center}
  \caption{forward Gummel plot for HICUM/L2 v2.11 model}
  \label{fig:fgummel_dpl}
  \end{figure}
  \FloatBarrier
  
  \tutsubsubsection{DC simulation}
  
  In fig.~\ref{fig:charac_sch} the schematic for the output
  characteristics of the HICUM model is shown.  The 2-dimensional sweep
  describes the function
  \begin{equation}
  I_C = f\left(V_{CE}, V_{BE}\right)
  \end{equation}
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.7\linewidth]{charac_sch}
  \end{center}
  \caption{output characteristics schematic for HICUM/L2 v2.11 model}
  \label{fig:charac_sch}
  \end{figure}
  \FloatBarrier
  
  Figure~\ref{fig:charac_dpl} shows the results of the DC simulations
  for the output characteristics of the bipolar transistor.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.6\linewidth]{charac_dpl}
  \end{center}
  \caption{output characteristics plot for HICUM/L2 v2.11 model}
  \label{fig:charac_dpl}
  \end{figure}
  \FloatBarrier
  
  \tutsubsubsection{AC simulation}
  
  Figures~\ref{fig:acgain_sch} and \ref{fig:acgain_dpl} depict the
  schematic and diagrams for an AC simulation in a given bias point.
  The current gains magnitude and phase are shown as well as the
  characteristics of the small signal base and collector current in the
  complex plane (polar plot).
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.7\linewidth]{acgain_sch}
  \end{center}
  \caption{AC simulation schematic for HICUM/L2 v2.11 model}
  \label{fig:acgain_sch}
  \end{figure}
  \FloatBarrier
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=1\linewidth]{acgain_dpl}
  \end{center}
  \caption{AC simulation plot for HICUM/L2 v2.11 model}
  \label{fig:acgain_dpl}
  \end{figure}
  \FloatBarrier
  
  \tutsubsubsection{S-parameter simulation}
  
  In the figures~\ref{fig:sparam_sch} and \ref{fig:sparam_dpl} a
  two-port S-parameter simulation schematic (including noise) as well as
  the results are shown.  The four S-parameters are displayed in two
  Polar-Smith combi diagrams.  The noise figure as well as the minimal
  noise figure are displayed in a logarithmic Cartesian diagram.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.7\linewidth]{sparam_sch}
  \end{center}
  \caption{S-parameter simulation schematic for HICUM/L2 v2.11 model}
  \label{fig:sparam_sch}
  \end{figure}
  \FloatBarrier
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.8\linewidth]{sparam_dpl}
  \end{center}
  \caption{S-parameter simulation plot for HICUM/L2 v2.11 model}
  \label{fig:sparam_dpl}
  \end{figure}
  \FloatBarrier
  
  \tutsubsubsection{Transient simulation}
  
  In the schematic in fig.~\ref{fig:transient_sch} a current pulse is
  fed into the base of the transistor.  Varying the input capacitance
  changes the response in the collector current as shown in
  fig.~\ref{fig:transient_dpl}.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.6\linewidth]{transient_sch}
  \end{center}
  \caption{Transient simulation schematic for HICUM/L2 v2.11 model}
  \label{fig:transient_sch}
  \end{figure}
  \FloatBarrier
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.8\linewidth]{transient_dpl}
  \end{center}
  \caption{Transient simulation plot for HICUM/L2 v2.11 model}
  \label{fig:transient_dpl}
  \end{figure}
  \FloatBarrier
  
  \tutsubsection{FBH-HBT model version 2.1}
  
  The HBT (Hetero Bipolar Transistor) model developed by Matthias
  Rudolph at the FBH (Ferdinand-Braun-Institut f\"ur Hochfrequenztechnik)
  is available in the Internet at
  \url{http://www.designers-guide.org/VerilogAMS}.
  
  \tutsubsubsection{DC simulation}
  
  Forward Gummel plot.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.9\linewidth]{fbh_fgummel}
  \end{center}
  \caption{forward Gummel plot schematic for HBT model}
  \label{fig:fbh_fgummel}
  \end{figure}
  \FloatBarrier
  
  \tutsubsubsection{DC simulation}
  
  Output characteristics.
  
  \begin{figure}[ht]
  \begin{center}
  \includegraphics[width=0.7\linewidth]{fbh_charac}
  \end{center}
  \caption{output characteristics schematic for HBT model}
  \label{fig:fbh_charac}
  \end{figure}
  \FloatBarrier
  
  \tutsection{End Note}
  
  The preferred way to add a new Verilog model to Qucs is certainly to
  prepare a model, check if it is accepted by ADMS and finally ask the
  maintainers to integrate it.  Until there is no possibility to load
  device modules dynamically (which is on the TODO list) too many
  hand-made changes have to be done to automate this process.  The
  dynamic modules require changes in the simulator API as well in the
  GUI code.
  
  \addvspace{12pt}
  
  Furthermore work is going to be continued on ADMS itself as well as on
  the \textbf{admst} scripts.
  
  \addvspace{12pt}
  
  The authors would like to thank H\'el\`ene Parruitte for the initial
  implementation of the Verilog-AMS interface in Qucs.  Also thanks go
  to the company Xmod Technologies (see \url{http://www.xmodtech.com})
  allowing her to work on such an interface and finally to share the
  outcome of her internship under the GPL.
  