/* $Id: d_mos123.model,v 26.133 2009/11/26 04:58:04 al Exp $ -*- C++ -*-
 * Copyright (C) 2001 Albert Davis
 * Author: Albert Davis <aldavis@gnu.org>
 *
 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
 *
 * This program 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 3, or (at your option)
 * any later version.
 *
 * This program 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 this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *------------------------------------------------------------------
 * MOS model - base for levels 1,2,3,6
 */
/* This file is automatically generated. DO NOT EDIT */

#include "globals.h"
#include "e_elemnt.h"
#include "d_mos123.h"
/*--------------------------------------------------------------------------*/
const double NA(NOT_INPUT);
const double INF(BIGBIG);
/*--------------------------------------------------------------------------*/
int MODEL_BUILT_IN_MOS123::_count = 0;
/*--------------------------------------------------------------------------*/
void SDP_BUILT_IN_MOS123::init(const COMMON_COMPONENT* cc)
{
  assert(cc);
  SDP_BUILT_IN_MOS_BASE::init(cc);
  const COMMON_BUILT_IN_MOS* c = prechecked_cast<const COMMON_BUILT_IN_MOS*>(cc);
  assert(c);
  const MODEL_BUILT_IN_MOS123* m = prechecked_cast<const MODEL_BUILT_IN_MOS123*>(c->model());
  assert(m);
  const CARD_LIST* par_scope = m->scope();
  assert(par_scope);
  // adjust: override
    this->cgate = m->cox * w_eff * l_eff;
    this->phi = m->phi;
  // adjust: raw
  // adjust: calculated
  // code_post
}
/*--------------------------------------------------------------------------*/
TDP_BUILT_IN_MOS123::TDP_BUILT_IN_MOS123(const DEV_BUILT_IN_MOS* d)
  :TDP_BUILT_IN_MOS_BASE(d)
{
}
/*--------------------------------------------------------------------------*/
MODEL_BUILT_IN_MOS123::MODEL_BUILT_IN_MOS123(const BASE_SUBCKT* p)
  :MODEL_BUILT_IN_MOS_BASE(p),
   vto_raw(NA),
   gamma(NA),
   phi(NA),
   lambda(NA),
   tox(NA),
   nsub_cm(NA),
   nss_cm(0.0),
   xj(NA),
   uo_cm(600.),
   tpg(int(gtOPP)),
   nsub(NA),
   nss(NA),
   uo(NA),
   vto(NA),
   cox(NA),
   calc_vto(false),
   calc_gamma(false),
   calc_phi(false)
{
  if (ENV::run_mode != rPRE_MAIN) {
    ++_count;
  }else{
  }
  set_default(&cjo, 0.);
  set_default(&pb, 0.8);
  set_default(&pbsw, NA);
}
/*--------------------------------------------------------------------------*/
MODEL_BUILT_IN_MOS123::MODEL_BUILT_IN_MOS123(const MODEL_BUILT_IN_MOS123& p)
  :MODEL_BUILT_IN_MOS_BASE(p),
   vto_raw(p.vto_raw),
   gamma(p.gamma),
   phi(p.phi),
   lambda(p.lambda),
   tox(p.tox),
   nsub_cm(p.nsub_cm),
   nss_cm(p.nss_cm),
   xj(p.xj),
   uo_cm(p.uo_cm),
   tpg(p.tpg),
   nsub(p.nsub),
   nss(p.nss),
   uo(p.uo),
   vto(p.vto),
   cox(p.cox),
   calc_vto(p.calc_vto),
   calc_gamma(p.calc_gamma),
   calc_phi(p.calc_phi)
{
  if (ENV::run_mode != rPRE_MAIN) {
    ++_count;
  }else{untested();//194
  }
}
/*--------------------------------------------------------------------------*/
std::string MODEL_BUILT_IN_MOS123::dev_type()const
{untested();//240
  return MODEL_BUILT_IN_MOS_BASE::dev_type();
}
/*--------------------------------------------------------------------------*/
void MODEL_BUILT_IN_MOS123::set_dev_type(const std::string& new_type)
{
  {
    MODEL_BUILT_IN_MOS_BASE::set_dev_type(new_type);
  }
}
/*--------------------------------------------------------------------------*/
void MODEL_BUILT_IN_MOS123::precalc_first()
{
    const CARD_LIST* par_scope = scope();
    assert(par_scope);
    MODEL_BUILT_IN_MOS_BASE::precalc_first();
    e_val(&(this->vto_raw), NA, par_scope);
    e_val(&(this->gamma), NA, par_scope);
    e_val(&(this->phi), NA, par_scope);
    e_val(&(this->lambda), NA, par_scope);
    e_val(&(this->tox), NA, par_scope);
    e_val(&(this->nsub_cm), NA, par_scope);
    e_val(&(this->nss_cm), 0.0, par_scope);
    e_val(&(this->xj), NA, par_scope);
    e_val(&(this->uo_cm), 600., par_scope);
    e_val(&(this->tpg), int(gtOPP), par_scope);
    // final adjust: code_pre
    // final adjust: override
    if (pbsw == NA) {
      pbsw = pb;
    }else{
    }
    cmodel = ((!cmodel)?3:cmodel);
    // final adjust: raw
    e_val(&(this->vto_raw), NA, par_scope);
    e_val(&(this->gamma), NA, par_scope);
    e_val(&(this->phi), NA, par_scope);
    e_val(&(this->lambda), NA, par_scope);
    e_val(&(this->tox), NA, par_scope);
    e_val(&(this->nsub_cm), NA, par_scope);
    e_val(&(this->nss_cm), 0.0, par_scope);
    e_val(&(this->xj), NA, par_scope);
    e_val(&(this->uo_cm), 600., par_scope);
    e_val(&(this->tpg), int(gtOPP), par_scope);
    // final adjust: mid
    // final adjust: calculated
    nsub = ((nsub_cm.has_hard_value()) ? nsub_cm*ICM2M3 : NA);
    nss = nss_cm*ICM2M2;
    uo = uo_cm*CM2M2;
    vto = ((vto_raw.has_hard_value()) ? vto_raw * polarity : NA);
    // final adjust: post

      if (tpg < 0) {		// coerce tpg to a proper value
	tpg = gtSAME;		
      }else if (tpg > 0) {
	tpg = gtOPP;
      }else{
	assert(tpg == gtMETAL);
      }
      if (has_hard_value(tox) && tox <= 0) {
        untested();
        set_default(&tox, NA);
	error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)),
	      long_label()+": tox <= 0, treating as if not input\n");
      }
      if (has_hard_value(nsub_cm) && nsub < NI) {
        untested();
        nsub = NA;
	error(((!_sim->is_first_expand()) ? (bDEBUG) : (bWARNING)),
	      long_label()+": nsub < ni, treating as if not input\n");
      }
    // final adjust: done
}
/*--------------------------------------------------------------------------*/
void MODEL_BUILT_IN_MOS123::precalc_last()
{
    MODEL_BUILT_IN_MOS_BASE::precalc_last();
}
/*--------------------------------------------------------------------------*/
SDP_CARD* MODEL_BUILT_IN_MOS123::new_sdp(COMMON_COMPONENT* c)const
{
  assert(c);
  if (COMMON_BUILT_IN_MOS* cc = dynamic_cast<COMMON_BUILT_IN_MOS*>(c)) {
    if (cc->_sdp) {
      cc->_sdp->init(cc);
      return cc->_sdp;
    }else{
      delete cc->_sdp;
      return new SDP_BUILT_IN_MOS123(c);
    }
  }else{
    return MODEL_BUILT_IN_MOS_BASE::new_sdp(c);
  }
}
/*--------------------------------------------------------------------------*/
void MODEL_BUILT_IN_MOS123::set_param_by_index(int i, std::string& value, int offset)
{
  switch (MODEL_BUILT_IN_MOS123::param_count() - 1 - i) {
  case 0: untested(); break;
  case 1: unreachable(); break;
  case 2: unreachable(); break;
  case 3: unreachable(); break;
  case 4: unreachable(); break;
  case 5: vto_raw = value; break;
  case 6: gamma = value; break;
  case 7: phi = value; break;
  case 8: lambda = value; break;
  case 9: tox = value; break;
  case 10: nsub_cm = value; break;
  case 11: nss_cm = value; break;
  case 12: xj = value; break;
  case 13: uo_cm = value; break;
  case 14: tpg = value; break;
  default: MODEL_BUILT_IN_MOS_BASE::set_param_by_index(i, value, offset); break;
  }
}
/*--------------------------------------------------------------------------*/
bool MODEL_BUILT_IN_MOS123::param_is_printable(int i)const
{
  switch (MODEL_BUILT_IN_MOS123::param_count() - 1 - i) {
  case 0:  return (false);
  case 1:  return (false);
  case 2:  return (false);
  case 3:  return (false);
  case 4:  return (false);
  case 5:  return (!calc_vto);
  case 6:  return (!calc_gamma);
  case 7:  return (!calc_phi);
  case 8:  return (lambda.has_hard_value());
  case 9:  return (tox.has_hard_value());
  case 10:  return (nsub_cm.has_hard_value());
  case 11:  return (nss_cm != 0.0 || has_hard_value(nsub_cm));
  case 12:  return (xj.has_hard_value());
  case 13:  return (true);
  case 14:  return (true);
  default: return MODEL_BUILT_IN_MOS_BASE::param_is_printable(i);
  }
}
/*--------------------------------------------------------------------------*/
std::string MODEL_BUILT_IN_MOS123::param_name(int i)const
{
  switch (MODEL_BUILT_IN_MOS123::param_count() - 1 - i) {
  case 0:  return "=====";
  case 1:  return "=====";
  case 2:  return "=====";
  case 3:  return "=====";
  case 4:  return "=====";
  case 5:  return "vto";
  case 6:  return "gamma";
  case 7:  return "phi";
  case 8:  return "lambda";
  case 9:  return "tox";
  case 10:  return "nsub";
  case 11:  return "nss";
  case 12:  return "xj";
  case 13:  return "uo";
  case 14:  return "tpg";
  default: return MODEL_BUILT_IN_MOS_BASE::param_name(i);
  }
}
/*--------------------------------------------------------------------------*/
std::string MODEL_BUILT_IN_MOS123::param_name(int i, int j)const
{
  if (j == 0) {
    return param_name(i);
  }else if (j == 1) {
    switch (MODEL_BUILT_IN_MOS123::param_count() - 1 - i) {
    case 0:  return "";
    case 1:  return "";
    case 2:  return "";
    case 3:  return "";
    case 4:  return "";
    case 5:  return "";
    case 6:  return "";
    case 7:  return "";
    case 8:  return "";
    case 9:  return "";
    case 10:  return "";
    case 11:  return "";
    case 12:  return "";
    case 13:  return "u0";
    case 14:  return "";
    default: return MODEL_BUILT_IN_MOS_BASE::param_name(i, j);
    }
  }else if (i < 15) {
    return "";
  }else{
    return MODEL_BUILT_IN_MOS_BASE::param_name(i, j);
  }
}
/*--------------------------------------------------------------------------*/
std::string MODEL_BUILT_IN_MOS123::param_value(int i)const
{
  switch (MODEL_BUILT_IN_MOS123::param_count() - 1 - i) {
  case 0:  unreachable(); return "";
  case 1:  unreachable(); return "";
  case 2:  unreachable(); return "";
  case 3:  unreachable(); return "";
  case 4:  unreachable(); return "";
  case 5:  return vto_raw.string();
  case 6:  return gamma.string();
  case 7:  return phi.string();
  case 8:  return lambda.string();
  case 9:  return tox.string();
  case 10:  return nsub_cm.string();
  case 11:  return nss_cm.string();
  case 12:  return xj.string();
  case 13:  return uo_cm.string();
  case 14:  return tpg.string();
  default: return MODEL_BUILT_IN_MOS_BASE::param_value(i);
  }
}
/*--------------------------------------------------------------------------*/
bool MODEL_BUILT_IN_MOS123::is_valid(const COMPONENT* d)const
{
  assert(d);
  return MODEL_BUILT_IN_MOS_BASE::is_valid(d);
}
/*--------------------------------------------------------------------------*/
void MODEL_BUILT_IN_MOS123::tr_eval(COMPONENT*)const
{untested();//425
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
