You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
194 lines
6.0 KiB
194 lines
6.0 KiB
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1985 S. Hwang
|
|
Modified: 2000 AlansFixes
|
|
**********/
|
|
|
|
#include "ngspice.h"
|
|
#include <stdio.h>
|
|
#include "smpdefs.h"
|
|
#include "cktdefs.h"
|
|
#include "mesdefs.h"
|
|
#include "const.h"
|
|
#include "sperror.h"
|
|
#include "suffix.h"
|
|
|
|
int
|
|
MESsetup(matrix,inModel,ckt,states)
|
|
SMPmatrix *matrix;
|
|
GENmodel *inModel;
|
|
CKTcircuit *ckt;
|
|
int *states;
|
|
/* load the diode structure with those pointers needed later
|
|
* for fast matrix loading
|
|
*/
|
|
{
|
|
MESmodel *model = (MESmodel*)inModel;
|
|
MESinstance *here;
|
|
int error;
|
|
CKTnode *tmp;
|
|
|
|
/* loop through all the diode models */
|
|
for( ; model != NULL; model = model->MESnextModel ) {
|
|
|
|
if( (model->MEStype != NMF) && (model->MEStype != PMF) ) {
|
|
model->MEStype = NMF;
|
|
}
|
|
if(!model->MESthresholdGiven) {
|
|
model->MESthreshold = -2;
|
|
}
|
|
if(!model->MESbetaGiven) {
|
|
model->MESbeta = 2.5e-3;
|
|
}
|
|
if(!model->MESbGiven) {
|
|
model->MESb = 0.3;
|
|
}
|
|
if(!model->MESalphaGiven) {
|
|
model->MESalpha = 2;
|
|
}
|
|
if(!model->MESlModulationGiven) {
|
|
model->MESlModulation = 0;
|
|
}
|
|
if(!model->MESdrainResistGiven) {
|
|
model->MESdrainResist = 0;
|
|
}
|
|
if(!model->MESsourceResistGiven) {
|
|
model->MESsourceResist = 0;
|
|
}
|
|
if(!model->MEScapGSGiven) {
|
|
model->MEScapGS = 0;
|
|
}
|
|
if(!model->MEScapGDGiven) {
|
|
model->MEScapGD = 0;
|
|
}
|
|
if(!model->MESgatePotentialGiven) {
|
|
model->MESgatePotential = 1;
|
|
}
|
|
if(!model->MESgateSatCurrentGiven) {
|
|
model->MESgateSatCurrent = 1e-14;
|
|
}
|
|
if(!model->MESdepletionCapCoeffGiven) {
|
|
model->MESdepletionCapCoeff = .5;
|
|
}
|
|
if(!model->MESfNcoefGiven) {
|
|
model->MESfNcoef = 0;
|
|
}
|
|
if(!model->MESfNexpGiven) {
|
|
model->MESfNexp = 1;
|
|
}
|
|
|
|
/* loop through all the instances of the model */
|
|
for (here = model->MESinstances; here != NULL ;
|
|
here=here->MESnextInstance) {
|
|
if (here->MESowner != ARCHme) goto matrixpointers;
|
|
|
|
if(!here->MESareaGiven) {
|
|
here->MESarea = 1;
|
|
}
|
|
here->MESstate = *states;
|
|
*states += MESnumStates;
|
|
|
|
matrixpointers:
|
|
if(model->MESsourceResist != 0 && here->MESsourcePrimeNode==0) {
|
|
error = CKTmkVolt(ckt,&tmp,here->MESname,"source");
|
|
if(error) return(error);
|
|
here->MESsourcePrimeNode = tmp->number;
|
|
|
|
if (ckt->CKTcopyNodesets) {
|
|
CKTnode *tmpNode;
|
|
IFuid tmpName;
|
|
|
|
if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
|
|
if (tmpNode->nsGiven) {
|
|
tmp->nodeset=tmpNode->nodeset;
|
|
tmp->nsGiven=tmpNode->nsGiven;
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
here->MESsourcePrimeNode = here->MESsourceNode;
|
|
}
|
|
if(model->MESdrainResist != 0 && here->MESdrainPrimeNode==0) {
|
|
error = CKTmkVolt(ckt,&tmp,here->MESname,"drain");
|
|
if(error) return(error);
|
|
here->MESdrainPrimeNode = tmp->number;
|
|
|
|
if (ckt->CKTcopyNodesets) {
|
|
CKTnode *tmpNode;
|
|
IFuid tmpName;
|
|
|
|
if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
|
|
if (tmpNode->nsGiven) {
|
|
tmp->nodeset=tmpNode->nodeset;
|
|
tmp->nsGiven=tmpNode->nsGiven;
|
|
}
|
|
}
|
|
}
|
|
|
|
} else {
|
|
here->MESdrainPrimeNode = here->MESdrainNode;
|
|
}
|
|
|
|
/* macro to make elements with built in test for out of memory */
|
|
#define TSTALLOC(ptr,first,second) \
|
|
if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NULL){\
|
|
return(E_NOMEM);\
|
|
}
|
|
|
|
TSTALLOC(MESdrainDrainPrimePtr,MESdrainNode,MESdrainPrimeNode)
|
|
TSTALLOC(MESgateDrainPrimePtr,MESgateNode,MESdrainPrimeNode)
|
|
TSTALLOC(MESgateSourcePrimePtr,MESgateNode,MESsourcePrimeNode)
|
|
TSTALLOC(MESsourceSourcePrimePtr,MESsourceNode,
|
|
MESsourcePrimeNode)
|
|
TSTALLOC(MESdrainPrimeDrainPtr,MESdrainPrimeNode,MESdrainNode)
|
|
TSTALLOC(MESdrainPrimeGatePtr,MESdrainPrimeNode,MESgateNode)
|
|
TSTALLOC(MESdrainPrimeSourcePrimePtr,MESdrainPrimeNode,
|
|
MESsourcePrimeNode)
|
|
TSTALLOC(MESsourcePrimeGatePtr,MESsourcePrimeNode,MESgateNode)
|
|
TSTALLOC(MESsourcePrimeSourcePtr,MESsourcePrimeNode,
|
|
MESsourceNode)
|
|
TSTALLOC(MESsourcePrimeDrainPrimePtr,MESsourcePrimeNode,
|
|
MESdrainPrimeNode)
|
|
TSTALLOC(MESdrainDrainPtr,MESdrainNode,MESdrainNode)
|
|
TSTALLOC(MESgateGatePtr,MESgateNode,MESgateNode)
|
|
TSTALLOC(MESsourceSourcePtr,MESsourceNode,MESsourceNode)
|
|
TSTALLOC(MESdrainPrimeDrainPrimePtr,MESdrainPrimeNode,
|
|
MESdrainPrimeNode)
|
|
TSTALLOC(MESsourcePrimeSourcePrimePtr,MESsourcePrimeNode,
|
|
MESsourcePrimeNode)
|
|
}
|
|
}
|
|
return(OK);
|
|
}
|
|
|
|
int
|
|
MESunsetup(inModel,ckt)
|
|
GENmodel *inModel;
|
|
CKTcircuit *ckt;
|
|
{
|
|
MESmodel *model;
|
|
MESinstance *here;
|
|
|
|
for (model = (MESmodel *)inModel; model != NULL;
|
|
model = model->MESnextModel)
|
|
{
|
|
for (here = model->MESinstances; here != NULL;
|
|
here=here->MESnextInstance)
|
|
{
|
|
if (here->MESsourcePrimeNode
|
|
&& here->MESsourcePrimeNode != here->MESsourceNode)
|
|
{
|
|
CKTdltNNum(ckt, here->MESsourcePrimeNode);
|
|
here->MESsourcePrimeNode = 0;
|
|
}
|
|
if (here->MESdrainPrimeNode
|
|
&& here->MESdrainPrimeNode != here->MESdrainNode)
|
|
{
|
|
CKTdltNNum(ckt, here->MESdrainPrimeNode);
|
|
here->MESdrainPrimeNode = 0;
|
|
}
|
|
}
|
|
}
|
|
return OK;
|
|
}
|