LCOV - code coverage report
Current view: top level - src/components/microstrip - bondwire.cpp (source / functions) Hit Total Coverage
Test: qucs-core-0.0.19 Code Coverage Lines: 0 123 0.0 %
Date: 2015-01-05 16:01:02 Functions: 0 17 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 71 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * bondwire.cpp - bondwire class implementation
       3                 :            :  *
       4                 :            :  * Copyright (C) 2006 Bastien Roucaries <roucaries.bastien@gmail.com>
       5                 :            :  * Copyright (C) 2007, 2008 Stefan Jahn <stefan@lkcc.org>
       6                 :            :  *
       7                 :            :  * This is free software; you can redistribute it and/or modify
       8                 :            :  * it under the terms of the GNU General Public License as published by
       9                 :            :  * the Free Software Foundation; either version 2, or (at your option)
      10                 :            :  * any later version.
      11                 :            :  *
      12                 :            :  * This software is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this package; see the file COPYING.  If not, write to
      19                 :            :  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
      20                 :            :  * Boston, MA 02110-1301, USA.
      21                 :            :  *
      22                 :            :  * $Id$
      23                 :            :  *
      24                 :            :  */
      25                 :            : 
      26                 :            : /*!\file bondwire.cpp
      27                 :            :    \brief Implement a bondwire model
      28                 :            : 
      29                 :            :    Bibliography:
      30                 :            : 
      31                 :            :    [1] Microwave Solid State Circuit Design,
      32                 :            :        Inder Bahl and Prakash Barthia  -- 2nd edition
      33                 :            :        2003 - Wiley interscience
      34                 :            :        ISBN 9-471-20755-1
      35                 :            : 
      36                 :            :    [2] Wikibook Electronics/Inductors
      37                 :            :        http://en.wikibooks.org/w/index.php?title=Electronics/Inductors&oldid=497883
      38                 :            :        online 2006/11/02
      39                 :            : 
      40                 :            :    [3] Physical and electrical modeling of bonding wires up to 110 GHz,
      41                 :            :        Descharles, C.   Algani, C.   Mercier, B.   Alquie, G.
      42                 :            :        Microwave Conference, 2003. 33rd European
      43                 :            :        Volume: 2,  On page(s): 639- 642 vol.2
      44                 :            :        ISBN: 1-58053-834-7
      45                 :            :        INSPEC Accession Number: 1262971
      46                 :            : */
      47                 :            : 
      48                 :            : 
      49                 :            : #if HAVE_CONFIG_H
      50                 :            : # include <config.h>
      51                 :            : #endif
      52                 :            : 
      53                 :            : #include "component.h"
      54                 :            : #include "substrate.h"
      55                 :            : #include "bondwire.h"
      56                 :            : 
      57                 :            : using namespace qucs;
      58                 :            : 
      59                 :          0 : bondwire::bondwire () : circuit (2) {
      60                 :          0 :   type = CIR_BONDWIRE;
      61                 :          0 : }
      62                 :            : 
      63                 :            : 
      64                 :            : /*! create a matching table between model number and string */
      65                 :            : #define TABLE(x) { #x, x }
      66                 :            : /*! array size */
      67                 :            : #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
      68                 :            : 
      69                 :            : /*! bondwire model number */
      70                 :            : enum bondwiremodel {
      71                 :            :   FREESPACE,       /*!< fresspace model */
      72                 :            :   MIRROR,          /*!< mirror plane model */
      73                 :            :   DESCHARLES       /*!< Descharles Algani Mercier Alquie model */
      74                 :            : };
      75                 :            : 
      76                 :            : /*! model number to string matching table definition */
      77                 :            : struct modeltable_t {
      78                 :            :   const char * name;
      79                 :            :   int model;
      80                 :            : };
      81                 :            : 
      82                 :            : /*! model number to string matching table implementation */
      83                 :            : static const modeltable_t modeltable[] = {
      84                 :            :   TABLE(FREESPACE),
      85                 :            :   TABLE(MIRROR),
      86                 :            : };
      87                 :            : 
      88                 :            : 
      89                 :            : /*!\brief Get properties from model.
      90                 :            :  * Get properties and fill the class.
      91                 :            :  *
      92                 :            :  *  \todo check values
      93                 :            :  */
      94                 :          0 : void bondwire::getProperties (void) {
      95                 :            :   unsigned int i;
      96                 :            : 
      97                 :          0 :   R = 0;
      98                 :          0 :   l = getPropertyDouble ("L");
      99                 :          0 :   d = getPropertyDouble ("D");
     100                 :          0 :   h = getPropertyDouble ("H");
     101                 :          0 :   rho = getPropertyDouble ("rho");
     102                 :          0 :   mur = getPropertyDouble ("mur");
     103                 :            : 
     104                 :            :   /* model used */
     105                 :          0 :   const char * Model  = getPropertyString ("Model");
     106         [ #  # ]:          0 :   if (Model == NULL) {
     107                 :          0 :     model = FREESPACE;
     108                 :          0 :     logprint (LOG_STATUS, "Model is not specified force FREESPACE\n");
     109                 :            :   } else {
     110                 :          0 :     model = (enum bondwiremodel) -1;
     111         [ #  # ]:          0 :     for (i = 0 ; i < ARRAY_SIZE (modeltable); i++) {
     112         [ #  # ]:          0 :       if (!strcasecmp (modeltable[i].name, Model))
     113                 :          0 :         model = modeltable[i].model;
     114                 :            :     }
     115                 :            : 
     116         [ #  # ]:          0 :     if (model == -1)
     117                 :            :       /* XXXX: how to abort ? */
     118                 :          0 :       logprint (LOG_ERROR, "Model %s not defined\n", Model);
     119                 :            :   }
     120                 :            : 
     121                 :            :   /* For noise */
     122                 :          0 :   temp = getPropertyDouble ("Temp");
     123                 :            : 
     124                 :            :   /* how to get properties of the substrate, e.g. Er, H */
     125                 :          0 :   substrate * subst = getSubstrate ();
     126                 :          0 :   nr_double_t er    = subst->getPropertyDouble ("er");
     127                 :          0 :   nr_double_t h     = subst->getPropertyDouble ("h");
     128                 :          0 :   nr_double_t t     = subst->getPropertyDouble ("t");
     129                 :            : 
     130                 :            :   /* Not yet used */
     131                 :            :   (void) er;
     132                 :            :   (void) h;
     133                 :            :   (void) t;
     134                 :          0 : }
     135                 :            : 
     136                 :            : /*! Compute skin depth.
     137                 :            :  * \todo Factorize the compution of skin depth in a header file.
     138                 :            :  *
     139                 :            :  * \param f frequency
     140                 :            :  * \param rho bond wire resistivity
     141                 :            :  * \param mur relative magnetic permeabillity
     142                 :            :  */
     143                 :          0 : static nr_double_t skindepth (const nr_double_t f,
     144                 :            :                               const nr_double_t rho, const nr_double_t mur) {
     145                 :          0 :   return std::sqrt (rho / (M_PI * f * MU0 * mur));
     146                 :            : }
     147                 :            : 
     148                 :            : /*! Compute resitance of the wire.
     149                 :            :  * Resitance of the wire is computed using classical
     150                 :            :  * tube model enhanced for case where tube is greater
     151                 :            :  * than conductor (i.e. low frequency case).
     152                 :            :  *
     153                 :            :  * \todo Offer other resistance model for
     154                 :            :  *       instance exponential decay and bessel function exact
     155                 :            :  *       computation.  But I do not know it is worth the effort.
     156                 :            :  *
     157                 :            :  * \todo Factorise the resistance model.
     158                 :            :  */
     159                 :          0 : nr_double_t bondwire::resistance (const nr_double_t f) const {
     160                 :            :   nr_double_t delta, rout, rin;
     161                 :          0 :   rout = d / 2;
     162         [ #  # ]:          0 :   if (f > 0.0) {
     163                 :          0 :     delta = skindepth (f, rho, mur);
     164                 :          0 :     rin = rout - delta;
     165         [ #  # ]:          0 :     if (rin < 0.0)
     166                 :          0 :       rin = 0.0;
     167                 :            :   }
     168                 :            :   else
     169                 :          0 :     rin = 0.0;
     170                 :            : 
     171                 :          0 :   return (rho * M_1_PI * l) / (rout * rout - rin * rin);
     172                 :            : }
     173                 :            : 
     174                 :            : 
     175                 :            : /*! Compute correction factor.
     176                 :            :  *  According to [1] pp63 (2.30a-b) correction factor
     177                 :            :  *  is such as:
     178                 :            :  *  \f[
     179                 :            :  *   C = 0.25 \tanh \frac{4\delta}{d}
     180                 :            :  *  \f]
     181                 :            :  *  where \f$\delta\f$ is the well known skin depth.
     182                 :            :  *
     183                 :            :  *  \param f frequency
     184                 :            :  *  \param d bond wire diameter
     185                 :            :  *  \param rho bond wire resistivity
     186                 :            :  *  \param mur relative magnetic permeabillity
     187                 :            :  *
     188                 :            :  * However according to [2] it seems that the author of [1] do the
     189                 :            :  * assumption of \f$\mu_r=1\f$ therefore rewrite the equation such as:
     190                 :            :  *
     191                 :            :  *  \f[
     192                 :            :  *   C = \frac{\mu_r}{4} \tanh \frac{4\delta}{d}
     193                 :            :  *  \f]
     194                 :            :  *
     195                 :            :  *  \return mur/4 if rho is zero, otherwise C
     196                 :            :  *  \todo Check domain validity for round C factor.
     197                 :            :  */
     198                 :          0 : static nr_double_t correctionfactor (const nr_double_t f,
     199                 :            :                                      const nr_double_t d,
     200                 :            :                                      const nr_double_t rho,
     201                 :            :                                      const nr_double_t mur) {
     202                 :            :   /* skin depth */
     203                 :            :   nr_double_t delta;
     204                 :            : 
     205 [ #  # ][ #  # ]:          0 :   if (f > 0.0 && rho > 0.0) {
     206                 :          0 :     delta = skindepth (f, rho, mur);
     207         [ #  # ]:          0 :     if (delta / d < 1e-2)
     208                 :          0 :       return delta / d;
     209                 :            :     else
     210                 :          0 :       return (mur / 4) * std::tanh ((4 * delta) / d);
     211                 :            :   }
     212                 :          0 :   return mur / 4;
     213                 :            : }
     214                 :            : 
     215                 :            : /*! Compute free space inductance.
     216                 :            :     According to [1] pp63 (2.29) free space inductance (in nH)
     217                 :            :     is such as (\f$l\f$ in micrometers):
     218                 :            : 
     219                 :            :    \f[
     220                 :            :     L = 2\times10^{-4} l \left[
     221                 :            :                \ln\left\{ \frac{2l}{d}
     222                 :            :                           + \sqrt{1 + \left(\frac{2l}{d}\right)^2} \right\}
     223                 :            :                + \frac{d}{2l} - \sqrt{1+\left(\frac{d}{2l}\right)^2}
     224                 :            :                + C \right]
     225                 :            : 
     226                 :            :    \f]
     227                 :            : 
     228                 :            :    According to [2] self inductance is (in H with l in m):
     229                 :            :    \f[
     230                 :            :     L = \frac{\mu_0}{2\pi} l\left[
     231                 :            :                \ln\left\{ \frac{2l}{d}
     232                 :            :                           + \sqrt{1 + \left(\frac{2l}{d}\right)^2} \right\}
     233                 :            :                + \frac{d}{2l} - \sqrt{1+\left(\frac{d}{2l}\right)^2}
     234                 :            :                + \frac{\mu_r}{4} \right]
     235                 :            : 
     236                 :            :    \f]
     237                 :            : 
     238                 :            :    Finally we will use (in H with l in m):
     239                 :            :    \f[
     240                 :            :     L = \frac{\mu_0}{2\pi} l\left[
     241                 :            :                \ln\left\{ \frac{2l}{d}
     242                 :            :                           + \sqrt{1 + \left(\frac{2l}{d}\right)^2} \right\}
     243                 :            :                + \frac{d}{2l} - \sqrt{1+\left(\frac{d}{2l}\right)^2}
     244                 :            :                + C \right]
     245                 :            : 
     246                 :            :    \f]
     247                 :            : 
     248                 :            :    \param f frequency
     249                 :            :    \param d bond wire diameter
     250                 :            :    \param l bond wire length (in meters)
     251                 :            :    \param rho bond wire resistivity
     252                 :            :    \param mur relative magnetic permeabillity
     253                 :            : */
     254                 :          0 : nr_double_t bondwire::Lfreespace (const nr_double_t f) const {
     255                 :          0 :   nr_double_t _2ld = (2.0 * l) / d;
     256                 :          0 :   nr_double_t d2l = d / (2.0 * l);
     257                 :            :   nr_double_t tmp;
     258                 :            : 
     259                 :          0 :   tmp = std::log (_2ld + std::sqrt (1 + _2ld * _2ld));
     260                 :          0 :   tmp += d2l - std::sqrt (1 + d2l * d2l);
     261                 :          0 :   tmp += correctionfactor (f, d, rho, mur);
     262                 :            : 
     263                 :          0 :   return MU0 * (M_1_PI / 2) * l * tmp;
     264                 :            : }
     265                 :            : 
     266                 :            : 
     267                 :            : /*! Compute inductance modeling ground plane effect.
     268                 :            :    According to [1] pp64 (2.32) inductance (in nH)
     269                 :            :    is such as (\f$l\f$ in micrometers):
     270                 :            : 
     271                 :            :    \f[
     272                 :            :     L = 2\times10^{-4} l \left[
     273                 :            :                \ln \frac{4h}{d}
     274                 :            :                + \ln \frac{l+\sqrt{l^2+d^2/4}}{l+\sqrt{l^2+4h^2}}
     275                 :            :                + \sqrt{1+\frac{4h^2}{l^2}} - \sqrt{1+\frac{d^2}{4l^2}}
     276                 :            :                - 2 \frac{h}{l} + \frac{d}{2l}
     277                 :            :                \right]
     278                 :            : 
     279                 :            :    \f]
     280                 :            : 
     281                 :            :    Finally we will use (in H with l in m):
     282                 :            :    \f[
     283                 :            :     L = \frac{\mu_0}{2\pi} l \left[
     284                 :            :                \ln \frac{4h}{d}
     285                 :            :                + \ln \frac{l+\sqrt{l^2+d^2/4}}{l+\sqrt{l^2+4h^2}}
     286                 :            :                + \sqrt{1+\frac{4h^2}{l^2}} - \sqrt{1+\frac{d^2}{4l^2}}
     287                 :            :                - 2 \frac{h}{l} + \frac{d}{2l}
     288                 :            :                \right]
     289                 :            :    \f]
     290                 :            : 
     291                 :            :    \note Mirror is a strange model that is frequency independent.
     292                 :            :         Whereas computations are valid, hypothesis are arguable.
     293                 :            :         Indeed, they did the assumption that the ground plane is
     294                 :            :         perfect that is really a zero order model in the high
     295                 :            :         frequency domain.
     296                 :            : */
     297                 :          0 : nr_double_t bondwire::Lmirror (void) const {
     298                 :            :   nr_double_t tmp;
     299                 :            : 
     300                 :            :   /* compute \$\ln \frac{l+\sqrt{l^2+d^2/4}}{l+\sqrt{l^2+4h^2}}\$ */
     301                 :          0 :   tmp  = std::log ((l + std::sqrt (l * l + d * d / 4)) / (l + std::sqrt (l * l + 4 * h * h)));
     302                 :          0 :   tmp += std::log (4 * h / d);
     303                 :          0 :   tmp += std::sqrt (1 + 4 * h * h / (l * l));
     304                 :          0 :   tmp -= std::sqrt (1 + d * d / (4 * l * l));
     305                 :          0 :   tmp -= 2 * h / l;
     306                 :          0 :   tmp += d / (2 * l);
     307                 :            : 
     308                 :          0 :   return  MU0 * (M_1_PI / 2) * l * tmp;
     309                 :            : }
     310                 :            : 
     311                 :            : 
     312                 :            : /*! Compute Y matrix of bond wire.
     313                 :            :  */
     314                 :          0 : matrix bondwire::calcMatrixY (const nr_double_t f) {
     315                 :            :   nr_double_t Lw;
     316                 :          0 :   L = 0;
     317                 :            : 
     318      [ #  #  # ]:          0 :   switch (model) {
     319                 :            :   case MIRROR:
     320                 :          0 :     L = Lmirror ();
     321                 :          0 :     R = resistance (f);
     322                 :          0 :     break;
     323                 :            :   case FREESPACE:
     324                 :          0 :     L = Lfreespace (f);
     325                 :          0 :     R = resistance (f);
     326                 :          0 :     break;
     327                 :            :   default:
     328                 :          0 :     break;
     329                 :            :   }
     330                 :            : 
     331                 :          0 :   Lw = L * 2 * M_PI * f;
     332                 :            : 
     333                 :            :   /* build Y-parameter matrix */
     334         [ #  # ]:          0 :   nr_complex_t yL = 1.0 / nr_complex_t (R, Lw);
     335                 :            : 
     336         [ #  # ]:          0 :   matrix Y (2);
     337         [ #  # ]:          0 :   Y.set (NODE_1, NODE_1, +yL);
     338         [ #  # ]:          0 :   Y.set (NODE_1, NODE_2, -yL);
     339         [ #  # ]:          0 :   Y.set (NODE_2, NODE_1, -yL);
     340         [ #  # ]:          0 :   Y.set (NODE_2, NODE_2, +yL);
     341                 :          0 :   return Y;
     342                 :            : }
     343                 :            : 
     344                 :            : /*! Initialize S parameter simulation. */
     345                 :          0 : void bondwire::initSP (void) {
     346                 :          0 :   allocMatrixS ();
     347                 :          0 :   getProperties ();
     348                 :          0 : }
     349                 :            : 
     350                 :            : /*! Compute S parameters.
     351                 :            :  *! Reuse computed Y matrix.
     352                 :            :  */
     353                 :          0 : void bondwire::calcSP (const nr_double_t frequency) {
     354 [ #  # ][ #  # ]:          0 :   setMatrixS (ytos (calcMatrixY (frequency)));
         [ #  # ][ #  # ]
                 [ #  # ]
     355                 :          0 : }
     356                 :            : 
     357                 :            : /*! Save self-inductance and resistance. */
     358                 :          0 : void bondwire::saveCharacteristics (nr_double_t) {
     359                 :          0 :   setCharacteristic ("L", L);
     360                 :          0 :   setCharacteristic ("R", R);
     361                 :          0 : }
     362                 :            : 
     363                 :            : /*! DC model initialization.
     364                 :            :  *! DC model of a bondwire is a resistance.
     365                 :            :  */
     366                 :          0 : void bondwire::initDC (void) {
     367                 :            :   nr_double_t g;
     368                 :            : 
     369                 :          0 :   getProperties ();
     370                 :            : 
     371                 :            :   /* for non-zero resistances usual MNA entries */
     372         [ #  # ]:          0 :   if (rho != 0.0) {
     373                 :          0 :     g = 1.0 / resistance (0);
     374                 :          0 :     setVoltageSources (0);
     375                 :          0 :     allocMatrixMNA ();
     376 [ #  # ][ #  # ]:          0 :     setY (NODE_1, NODE_1, +g); setY (NODE_2, NODE_2, +g);
     377 [ #  # ][ #  # ]:          0 :     setY (NODE_1, NODE_2, -g); setY (NODE_2, NODE_1, -g);
     378                 :            :   }
     379                 :            :   /* for zero resistances create a zero voltage source */
     380                 :            :   else {
     381                 :          0 :     setVoltageSources (1);
     382                 :          0 :     setInternalVoltageSource (1);
     383                 :          0 :     allocMatrixMNA ();
     384                 :          0 :     clearY ();
     385                 :          0 :     voltageSource (VSRC_1, NODE_1, NODE_2);
     386                 :            :   }
     387                 :          0 : }
     388                 :            : 
     389                 :            : /*! Initialize AC simulation. */
     390                 :          0 : void bondwire::initAC (void) {
     391                 :          0 :   getProperties ();
     392                 :          0 :   setVoltageSources (0);
     393                 :          0 :   allocMatrixMNA ();
     394                 :          0 : }
     395                 :            : 
     396                 :            : /*! Compute AC model.
     397                 :            :  *! Use serial LR model (Y matrix).
     398                 :            :  */
     399                 :          0 : void bondwire::calcAC (const nr_double_t frequency) {
     400         [ #  # ]:          0 :   setMatrixY (calcMatrixY (frequency));
     401                 :          0 : }
     402                 :            : 
     403                 :          0 : void bondwire::calcNoiseSP (nr_double_t) {
     404                 :            :   // calculate noise correlation matrix
     405                 :          0 :   nr_double_t T = getPropertyDouble ("Temp");
     406                 :          0 :   nr_double_t f = kelvin (T) * 4.0 * R * z0 / norm (4.0 * z0 + R) / T0;
     407 [ #  # ][ #  # ]:          0 :   setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
     408 [ #  # ][ #  # ]:          0 :   setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
     409                 :          0 : }
     410                 :            : 
     411                 :          0 : void bondwire::calcNoiseAC (nr_double_t) {
     412                 :            :   // calculate noise current correlation matrix
     413                 :          0 :   nr_double_t y = 1 / R;
     414                 :          0 :   nr_double_t T = getPropertyDouble ("Temp");
     415                 :          0 :   nr_double_t f = kelvin (T) / T0 * 4.0 * y;
     416 [ #  # ][ #  # ]:          0 :   setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
     417 [ #  # ][ #  # ]:          0 :   setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
     418                 :          0 : }
     419                 :            : 
     420                 :            : // properties
     421                 :            : PROP_REQ [] = {
     422                 :            :   { "D", PROP_REAL, { 25e-6, PROP_NO_STR }, PROP_POS_RANGE },
     423                 :            :   { "L", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
     424                 :            :   { "H", PROP_REAL, { 1e-3, PROP_NO_STR }, PROP_POS_RANGE },
     425                 :            :   { "mur", PROP_REAL, { 1, PROP_NO_STR }, PROP_RNGII (1, 100) },
     426                 :            :   { "rho", PROP_REAL, { 0.022e-6, PROP_NO_STR }, PROP_POS_RANGE },
     427                 :            :   { "Model", PROP_STR, { PROP_NO_VAL, "FREESPACE" },
     428                 :            :     PROP_RNG_STR3 ("FREESPACE", "MIRROR", "DESCHARLES") },
     429                 :            :   { "Subst", PROP_STR, { PROP_NO_VAL, "Subst1" }, PROP_NO_RANGE },
     430                 :            :   PROP_NO_PROP };
     431                 :            : PROP_OPT [] = {
     432                 :            :   { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
     433                 :            :   PROP_NO_PROP };
     434                 :            : struct define_t bondwire::cirdef =
     435                 :            :   { "BOND", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };

Generated by: LCOV version 1.11