Xyce  6.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
N_DEV_ADMSHBT_X.h
Go to the documentation of this file.
1 
2 // -*-c++-*-
3 //-----------------------------------------------------------------------------
4 // Copyright Notice
5 //
6 // Copyright 2002 Sandia Corporation. Under the terms
7 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S.
8 // Government retains certain rights in this software.
9 //
10 // Xyce(TM) Parallel Electrical Simulator
11 // Copyright (C) 2002-2014 Sandia Corporation
12 //
13 // This program is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // This program is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //-----------------------------------------------------------------------------
26 
27 //-----------------------------------------------------------------------------
28 // Filename : $RCSfile: N_DEV_ADMSHBT_X.h,v $
29 //
30 // Purpose :
31 //
32 // Special Notes : Generated from verilog file fbhhbt-2.1_nonoise_limited_inductors_typed.va with ADMS
33 // interface for Xyce 6.1.0
34 // DO NOT EDIT THIS FILE DIRECTLY! It may be overwritten!
35 //
36 // Creator : admsXml-2.3.0
37 //
38 // Creation Date : Mon, 02 Jun 2014 11:31:01
39 //
40 // Revision Information:
41 // ---------------------
42 //
43 // Revision Number: $Revision: 1.40 $
44 //
45 // Revision Date : $Date: 2014/06/02 17:46:46 $
46 //
47 // Current Owner : $Author: tvrusso $
48 //-----------------------------------------------------------------------------
49 #ifndef Xyce_N_DEV_ADMSHBT_X_h
50 #define Xyce_N_DEV_ADMSHBT_X_h
51 
52 
53 #include <Sacado.hpp>
54 
55 #include <N_DEV_Configuration.h>
56 #include <N_DEV_Const.h>
57 #include <N_DEV_DeviceBlock.h>
58 #include <N_DEV_DeviceInstance.h>
59 #include <N_DEV_DeviceModel.h>
60 #include <N_DEV_BJT.h>
61 
62 
63 namespace Xyce {
64 namespace Device {
65 namespace ADMSHBT_X {
66 
67 class Model;
68 class Instance;
69 
70 struct Traits: public DeviceTraits<Model, Instance, BJT::Traits>
71 {
72  static const char *name() {return "FBH HBT_X v2.1";}
73  static const char *deviceTypeName() {return "q level 23";}
74 
75  static int numNodes() {return 4;}
76  static bool modelRequired() {return true;}
77  static bool isLinearDevice() {return false;}
78 
79  static Device *factory(const Configuration &configuration, const FactoryBlock &factory_block);
80  static void loadModelParameters(ParametricData<Model> &model_parameters);
81  static void loadInstanceParameters(ParametricData<Instance> &instance_parameters);
82 };
83 
84 //-----------------------------------------------------------------------------
85 // Class : Instance
86 
87 //
88 // Purpose : This class represents a single instance of the
89 // device. It mainly contains indices and pointers into
90 // the matrix equation (see the resistor instance class for
91 // more details).
92 //
93 // Special Notes :
94 // Creator :
95 // Creation Date :
96 //-----------------------------------------------------------------------------
97 class Instance : public DeviceInstance
98 {
99  friend class ParametricData<Instance>;
100  friend class Model;
101  friend class Traits;
102 
103  // This typedef is for our automatic differentiation:
104  typedef Sacado::Fad::SFad<double,19> AdmsFadType;
105 
106 public:
107  Instance(
108  const Configuration & configuration,
109  const InstanceBlock & instance_block,
110  Model & model,
111  const FactoryBlock & factory_block);
112 
113  ~Instance();
114 
115 private:
116  Instance(const Instance &);
117  Instance &operator=(const Instance &);
118 
119 public:
120  void registerLIDs( const std::vector<int> & intLIDVecRef,
121  const std::vector<int> & extLIDVecRef );
122  void registerStateLIDs( const std::vector<int> & staLIDVecRef );
123  void setupPointers();
124 
125  std::map<int,std::string> & getIntNameMap ();
126 
127  const std::vector< std::vector<int> > & jacobianStamp() const;
128  void registerJacLIDs( const std::vector< std::vector<int> > & jacLIDVec );
129 
130  bool processParams();
131  bool updateTemperature ( const double & temp = -999.0 );
132  bool updateIntermediateVars ();
133  bool updatePrimaryState ();
134  bool updateSecondaryState ();
135 
136  // load functions, residual:
137  bool loadDAEQVector ();
138  bool loadDAEFVector ();
139 
140  // load functions, Jacobian:
141  bool loadDAEdQdx ();
142  bool loadDAEdFdx ();
143 
144  // thermal voltage at kelvin temperature temp)
145  template <typename T> static inline T adms_vt(T temp) {return(CONSTKoverQ*temp);};
146 
147 private:
148  // Limited exponential --- NOT what verilog LRM says, but what qucs,
149  // ng-spice, and zspice do.
150 
151  template <typename T>
152  T limexp(const T &x)
153  {
154  if ((x) < 80.0)
155  return (exp(x));
156  else
157  return (exp(80.0)*(x-79.0));
158  }
159 
160 
161 public:
162  // iterator reference to the HBT_X model which owns this instance.
163  // Getters and setters
165  {
166  return model_;
167  }
168 
169 private:
170 
171  Model & model_; //< Owning Model
172  // Begin verilog Instance Variables
173  // Instance Parameters
174  double Temp;
175  int N;
176  double L;
177  double W;
178  // Variables of global_instance scope
179  // end verilog Instance Variables=====
180  // Nodal LID Variables
181  int li_c;
182  int li_b;
183  int li_e;
184  int li_t;
185  int li_ei;
186  int li_bi;
187  int li_bii;
188  int li_ci;
189  int li_ti;
190  int li_ex;
191  int li_exx;
192  int li_cx;
193  // end Nodal LID Variables
194  // Branch LID Variables
198  // end Branch LID Variables
199  // Jacobian pointers
326  // end of Jacobian and pointers
327  // node numbers
328  static const int admsNodeID_c = 0;
329  static const int admsNodeID_b = 1;
330  static const int admsNodeID_e = 2;
331  static const int admsNodeID_t = 3;
332  static const int admsNodeID_ei = 4;
333  static const int admsNodeID_bi = 5;
334  static const int admsNodeID_bii = 6;
335  static const int admsNodeID_ci = 7;
336  static const int admsNodeID_ti = 8;
337  static const int admsNodeID_ex = 9;
338  static const int admsNodeID_exx = 10;
339  static const int admsNodeID_cx = 11;
340  // end node numbers
341  // Additional IDs for branch equations
342  static const int admsBRA_ID_b_bi = 12;
343  static const int admsBRA_ID_e_ei = 13;
344  static const int admsBRA_ID_c_ci = 14;
345  // end branch numbers
346  // Probe numbers
347  static const int admsProbeID_V_t_ti = 0;
348  static const int admsProbeID_V_b_c = 1;
349  static const int admsProbeID_V_c_GND = 2;
350  static const int admsProbeID_V_b_GND = 3;
351  static const int admsProbeID_V_cx_bii = 4;
352  static const int admsProbeID_V_exx_bii = 5;
353  static const int admsProbeID_V_ex_bii = 6;
354  static const int admsProbeID_V_bii_bi = 7;
355  static const int admsProbeID_I_c_ci = 8;
356  static const int admsProbeID_I_e_ei = 9;
357  static const int admsProbeID_I_b_bi = 10;
358  static const int admsProbeID_V_ti_GND = 11;
359  static const int admsProbeID_V_ci_ei = 12;
360  static const int admsProbeID_V_exx_ei = 13;
361  static const int admsProbeID_V_cx_ci = 14;
362  static const int admsProbeID_V_ex_ei = 15;
363  static const int admsProbeID_V_bii_ei = 16;
364  static const int admsProbeID_V_bii_ci = 17;
365  static const int admsProbeID_V_bi_ci = 18;
366  // end probe numbers
367  // State LIDs
371  // end state LIDs
372  // Arrays to hold probes
373  std::vector < AdmsFadType > probeVars;
374  // Arrays to hold contributions
375  // dynamic contributions are differentiated w.r.t time
376  std::vector < AdmsFadType > staticContributions;
377  std::vector < AdmsFadType > dynamicContributions;
378 
379  // This array stores the differences between original and limited variables.
380  std::vector<double> probeDiffs;
381  // These store the Jdxp's for F and Q, respectively
382  std::vector<double> Jdxp_static;
383  std::vector<double> Jdxp_dynamic;
384 
385  // this is what we'll use when any model uses $temperature. We'll
386  // set it in updateTemperature, and initialize it to whatever
387  // is in devOptions when the instance is constructed.
389 
390  // vt at $temperature;
391  double adms_vt_nom;
392 
393 
394  // This one is for the annoying bogus "XyceADMSInstTemp" parameter
395  // that we need so we can set it from the device manager when there's no
396  // "TEMP" parameter to use
397  double admsInstTemp;
398 
399  static std::vector< std::vector<int> > jacStamp;
400  static std::vector<int> jacMap;
401  static std::vector< std::vector<int> > jacMap2;
402 };
403 
404 
405 // Class AnalogFunctions
406 
408 {
409 public:
410 
411  // Analog Function exp_soft
412  template<typename ScalarT> ScalarT exp_soft(ScalarT x)
413  {
414 
415 
416  ScalarT exp_soft;
417  ScalarT maxexp;
418  ScalarT maxarg;
419  {
420  maxexp = 1.0e25;
421  maxarg = log(maxexp);
422  if ((x<maxarg))
423  {
424  exp_soft = exp(x);
425  }
426  else
427  {
428  exp_soft = (((x+1.0)-maxarg)*maxexp);
429  }
430  }
431  return(exp_soft);
432  }
433 
434 
435  // Analog Function Vt
436  template<typename RetScalarT,typename Arg1ScalarT, typename Arg2ScalarT> RetScalarT Vt(Arg1ScalarT U, Arg2ScalarT Ud)
437  {
438 
439 
440  RetScalarT Vt;
441  Arg2ScalarT Vch;
442  Arg2ScalarT VF;
443  RetScalarT exparg;
444  {
445  Vch = (0.1*Ud);
446  VF = (0.9*Ud);
447  if ((U<VF))
448  {
449  exparg=((U-VF)/Vch);
450  Vt = (U-(Vch*log((1.0+exp(exparg)))));
451  }
452  else
453  {
454  exparg=((VF-U)/Vch);
455  Vt = (VF-(Vch*log((1.0+exp(exparg)))));
456  }
457  }
458  return(Vt);
459  }
460 
461 
462  // Analog Function diode
463  template<typename RetScalarT,typename Arg1ScalarT,typename Arg3ScalarT,typename Arg4ScalarT,typename Arg6ScalarT>
464  RetScalarT diode(Arg1ScalarT U, double Is, Arg3ScalarT Ug, Arg4ScalarT N, double AREA, Arg6ScalarT TJ, double TNOM)
465  {
466 
467 
468  RetScalarT diode;
469  RetScalarT exparg1;
470  RetScalarT exparg2;
471  RetScalarT VTH0;
472  Arg6ScalarT VTHJ;
473  double VTHNOM;
474  double maxi;
475  Arg3ScalarT Tmax;
476  Arg6ScalarT TJM;
477  Arg6ScalarT TJM_arg1;
478  double KDURCHQ;
479  double lnIs;
480  {
481  VTH0 = Instance::adms_vt((20.0+273.15));
482  VTHNOM = Instance::adms_vt((TNOM+273.15));
483  KDURCHQ = 0.861708692e-4;
484  lnIs = log((Is*AREA));
485  maxi = log(1e6);
486  if (((maxi<(Ug/VTHNOM))&&(U<0.0)))
487  {
488  Tmax = (((Ug*VTHNOM)/((Ug-(maxi*VTHNOM))*KDURCHQ))-273.15);
489  TJM = Vt<Arg6ScalarT>(TJ,Tmax);
490  }
491  else
492  {
493  TJM = TJ;
494  }
495  TJM_arg1=TJM+273.15;
496  VTHJ = Instance::adms_vt((TJM_arg1));
497  if ((Ug>0.0))
498  {
499  exparg1=((((U/(N*VTHJ))+(Ug/VTHNOM))-(Ug/VTHJ))+lnIs);
500  exparg2=(((Ug/VTHNOM)-(Ug/VTHJ))+lnIs);
501  diode = (exp_soft(exparg1)-exp_soft(exparg2));
502  }
503  else
504  {
505  exparg1=((U/(N*VTH0))+lnIs);
506  diode = (exp_soft(exparg1)-(Is*AREA));
507  }
508  }
509  return(diode);
510  }
511 
512 
513  // Analog Function MM
514  template<typename ScalarT> ScalarT MM(ScalarT VBCI, ScalarT VCBO, ScalarT MC, ScalarT VCBLIN, ScalarT BF, ScalarT KC)
515  {
516 
517 
518  ScalarT MM;
519  ScalarT FBD;
520  ScalarT vcbi;
521  {
522  if ((((KC>0.0)&&(MC>0.0))&&(VCBO>0.0)))
523  {
524  vcbi = VBCI;
525  FBD = (VCBLIN/VCBO);
526  if ((VBCI>0.0))
527  {
528  MM = 1.0;
529  }
530  else
531  {
532  if ((VBCI>(-VCBLIN)))
533  {
534  if ((MC==1))
535  {
536  MM = (1.0/(1.0-(vcbi/(-VCBO))));
537  }
538  else
539  {
540  MM = (1.0/(1.0-pow((vcbi/(-VCBO)),MC)));
541  }
542  }
543  else
544  {
545  if ((VBCI<=(-VCBLIN)))
546  {
547  if ((MC==1))
548  {
549  MM = ((1.0/(1.0-FBD))-((((1.0/VCBO)*1.0)/pow((1.0-FBD),2.0))*(vcbi+(FBD*VCBO))));
550  }
551  else
552  {
553  MM = ((1.0/(1.0-pow(FBD,MC)))-((((MC/VCBO)*pow(FBD,(MC-1.0)))/pow((1.0-pow(FBD,MC)),2.0))*(vcbi+(FBD*VCBO))));
554  }
555  }
556  }
557  }
558  }
559  else
560  {
561  MM = 1.0;
562  }
563  }
564  return(MM);
565  }
566 
567 
568  // Analog Function charge
569  template< typename RetScalarT> RetScalarT charge(RetScalarT U, double C0, double Ud, double m, double Area)
570  {
571 
572 
573  RetScalarT charge;
574  RetScalarT Vj;
575  double Vjo;
576  double VF;
577  {
578  Vj = Vt<RetScalarT>(U,Ud);
579  Vjo = Vt<double>(0.0,Ud);
580  VF = (0.9*Ud);
581  if ((m==1.0))
582  {
583  charge = ((Area*C0)*((Ud*(log((1.0-(Vjo/Ud)))-log((1.0-(Vj/Ud)))))+((1.0/(1.0-(VF/Ud)))*((U-Vj)+Vjo))));
584  }
585  else
586  {
587  charge = ((Area*C0)*((((Ud/(1.0-m))*(pow((1.0-(Vjo/Ud)),(1.0-m))-pow((1.0-(Vj/Ud)),(1.0-m))))+(pow((1.0-(VF/Ud)),(-m))*((U-Vj)+Vjo)))-(Ud*(1.0/(1.0-m)))));
588  }
589  }
590  return(charge);
591  }
592 
593 
594  // Analog Function Vceff
595  template<typename ScalarT> ScalarT Vceff(ScalarT U, ScalarT VCES)
596  {
597 
598 
599  ScalarT Vceff;
600  ScalarT Vth0;
601  {
602  Vth0 = 0.025;
603  if ((U<VCES))
604  {
605  Vceff = (Vth0+(Vth0*log((1.0+exp((((U-VCES)/Vth0)-1.0))))));
606  }
607  else
608  {
609  Vceff = ((U-VCES)+(Vth0*log((1.0+exp((1.0-((U-VCES)/Vth0)))))));
610  }
611  }
612  return(Vceff);
613  }
614 
615 
616  // Analog Function ICK
617  template<typename ScalarT> ScalarT ICK(ScalarT U, ScalarT RCI0, ScalarT VLIM, ScalarT InvVPT, ScalarT VCES)
618  {
619 
620 
621  ScalarT ICK;
622  ScalarT VC;
623  ScalarT x;
624  {
625  VC = Vceff(U,VCES);
626  x = ((VC-VLIM)*InvVPT);
627  ICK = (((VC/RCI0)*(1.0/sqrt((1.0+((VC/VLIM)*(VC/VLIM))))))*(1.0+((x+sqrt(((x*x)+0.001)))/2.0)));
628  }
629  return(ICK);
630  }
631 
632 };
633 
634 
635 //-----------------------------------------------------------------------------
636 // Class : Model
637 
638 // Purpose :
639 // Special Notes :
640 // Creator :
641 // Creation Date :
642 //-----------------------------------------------------------------------------
643 class Model : public DeviceModel
644 {
645  typedef std::vector<Instance *> InstanceVector;
646 
647  friend class ParametricData<Model>;
648  friend class Instance;
649  friend class Traits;
650 
651  typedef Sacado::Fad::SFad<double,19> AdmsFadType;
652 
653 public:
654  Model(
655  const Configuration & configuration,
656  const ModelBlock & model_block,
657  const FactoryBlock & factory_block);
658 
659  ~Model();
660 
661 private:
662  Model(const Model &);
663  Model &operator=(const Model &);
664 
665 public:
666  virtual void forEachInstance(DeviceInstanceOp &op) const /* override */;
667  virtual std::ostream &printOutInstances(std::ostream &os) const;
668  bool processParams();
669  bool processInstanceParams();
670 
671 private:
673 
674 public:
675  void addInstance(Instance *instance)
676  {
677  instanceContainer.push_back(instance);
678  }
679 
680 private:
681  std::vector<Instance*> instanceContainer;
682 
683 private:
684 
685  // This one is for the annoying bogus "XyceADMSInstTemp" parameter
686  // that we need so we can set it from the device manager when there's no
687  // "TEMP" model parameter to use
688  double admsModTemp;
689  // Begin verilog Model Variables
690  // Model Parameters
691  int Mode;
692  int Noise;
693  int Debug;
695  double Rth;
696  double Cth;
697  double Jsf;
698  double nf;
699  double Vg;
700  double Jse;
701  double ne;
702  double Rbxx;
703  double Vgb;
704  double Jsee;
705  double nee;
706  double Rbbxx;
707  double Vgbb;
708  double Jsr;
709  double nr;
710  double Vgr;
711  double XCjc;
712  double Jsc;
713  double nc;
714  double Rcxx;
715  double Vgc;
716  double Bf;
717  double kBeta;
718  double Br;
719  double VAF;
720  double VAR;
721  double IKF;
722  double IKR;
723  double Mc;
724  double BVceo;
725  double kc;
726  double BVebo;
727  double Tr;
728  double Trx;
729  double Tf;
730  double Tft;
731  double Thcs;
732  double Ahc;
733  double Cje;
734  double mje;
735  double Vje;
736  double Cjc;
737  double mjc;
738  double Vjc;
739  double kjc;
740  double Cmin;
741  double J0;
742  double XJ0;
743  double Rci0;
744  double Jk;
745  double RJk;
746  double Vces;
747  double Rc;
748  double Re;
749  double Rb;
750  double Rb2;
751  double Lc;
752  double Le;
753  double Lb;
754  double Cq;
755  double Cpb;
756  double Cpc;
757  double Tnom;
758  int dtype;
759  // Variables of global_model scope
760  // end verilog model variables=====
761 };
762 
763 void registerDevice();
764 
765 } // namespace ADMSHBT_X
766 } // namespace Device
767 } // namespace Xyce
768 #endif //Xyce_N_DEV_ADMSHBT_X_h