Added the possibility to specify the instance names to be considered from the Reliability Analysis
This commit is contained in:
parent
da6b1b588e
commit
b9ebfe2ce6
|
|
@ -9,7 +9,12 @@ Author: 1985 Thomas L. Quarles
|
||||||
#include "ngspice/typedefs.h"
|
#include "ngspice/typedefs.h"
|
||||||
#include "ngspice/ifsim.h"
|
#include "ngspice/ifsim.h"
|
||||||
|
|
||||||
|
#ifdef RELAN
|
||||||
|
typedef struct sGENrelmodelDeviceElem {
|
||||||
|
char *device_name ; /* Name of the device considered by Relmodel */
|
||||||
|
struct sGENrelmodelDeviceElem *next ; /* Pointer to the next device name */
|
||||||
|
} GENrelmodelDeviceElem ;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* definitions used to describe generic devices */
|
/* definitions used to describe generic devices */
|
||||||
|
|
||||||
|
|
@ -43,6 +48,7 @@ struct GENmodel { /* model structure for a resistor */
|
||||||
|
|
||||||
#ifdef RELAN
|
#ifdef RELAN
|
||||||
GENmodel *GENrelmodelModel ; /* Relmodel Companion Model */
|
GENmodel *GENrelmodelModel ; /* Relmodel Companion Model */
|
||||||
|
GENrelmodelDeviceElem *GENrelmodelDeviceList ; /* List of devices to be considered by Relmodel */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -7,196 +7,223 @@ Author: 2015 Francesco Lannutti - July 2015
|
||||||
#include "bsim4def.h"
|
#include "bsim4def.h"
|
||||||
#include "ngspice/sperror.h"
|
#include "ngspice/sperror.h"
|
||||||
|
|
||||||
|
static int
|
||||||
|
BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mode)
|
||||||
|
{
|
||||||
|
BSIM4model *model ;
|
||||||
|
double delta, vds, vgs, von ;
|
||||||
|
int NowIsON, ret ;
|
||||||
|
|
||||||
|
model = here->BSIM4modPtr ;
|
||||||
|
|
||||||
|
// Determine if the transistor is ON or OFF
|
||||||
|
vds = ckt->CKTstate0 [here->BSIM4vds] ;
|
||||||
|
vgs = ckt->CKTstate0 [here->BSIM4vgs] ;
|
||||||
|
von = model->BSIM4type * here->BSIM4von ;
|
||||||
|
if (vds >= 0)
|
||||||
|
{
|
||||||
|
// printf ("VDS >= 0\tBSIM4type: %d\tBSIM4instance: %s\tVgs: %-.9g\tVon: %-.9g\t", model->BSIM4type, here->BSIM4name, vgs, von) ;
|
||||||
|
if (vgs > von)
|
||||||
|
{
|
||||||
|
if (here->BSIM4rgateMod == 3)
|
||||||
|
{
|
||||||
|
double vges, vgms ;
|
||||||
|
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
||||||
|
vgms = ckt->CKTstate0 [here->BSIM4vgms] ;
|
||||||
|
if ((vges > von) && (vgms > von))
|
||||||
|
{
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
} else if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2)) {
|
||||||
|
double vges ;
|
||||||
|
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
||||||
|
if (vges > von)
|
||||||
|
{
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
double vgd ;
|
||||||
|
vgd = vgs - vds ;
|
||||||
|
// printf ("VDS < 0\tBSIM4type: %d\tBSIM4instance: %s\tVgd: %-.9g\tVon: %-.9g\t", model->BSIM4type, here->BSIM4name, vgd, von) ;
|
||||||
|
if (vgd > von)
|
||||||
|
{
|
||||||
|
if (here->BSIM4rgateMod == 3)
|
||||||
|
{
|
||||||
|
double vges, vged, vgms, vgmd ;
|
||||||
|
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
||||||
|
vged = vges - vds ;
|
||||||
|
vgms = ckt->CKTstate0 [here->BSIM4vgms] ;
|
||||||
|
vgmd = vgms - vds ;
|
||||||
|
if ((vged > von) && (vgmd > von))
|
||||||
|
{
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
} else if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2)) {
|
||||||
|
double vges, vged ;
|
||||||
|
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
||||||
|
vged = vges - vds ;
|
||||||
|
if (vged > von)
|
||||||
|
{
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// printf ("Acceso!\n") ;
|
||||||
|
NowIsON = 1 ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// printf ("Spento!\n") ;
|
||||||
|
NowIsON = 0 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it's the first time, initialize 'here->relStruct->IsON'
|
||||||
|
if (here->relStruct->IsON == -1)
|
||||||
|
{
|
||||||
|
here->relStruct->IsON = NowIsON ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode == 0)
|
||||||
|
{
|
||||||
|
if (NowIsON)
|
||||||
|
{
|
||||||
|
if (here->relStruct->IsON == 1)
|
||||||
|
{
|
||||||
|
// Until now, the device was ON - Do NOTHING
|
||||||
|
delta = -1 ;
|
||||||
|
} else if (here->relStruct->IsON == 0) {
|
||||||
|
// Until now, the device was OFF - Calculate recovery
|
||||||
|
delta = ckt->CKTtime - here->relStruct->time ;
|
||||||
|
|
||||||
|
// Calculate Aging - Giogio Liatis' Model
|
||||||
|
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
return (E_INTERN) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update time and flag - Stress begins
|
||||||
|
here->relStruct->time = ckt->CKTtime ;
|
||||||
|
here->relStruct->IsON = 1 ;
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (here->relStruct->IsON == 1)
|
||||||
|
{
|
||||||
|
// Until now, the device was ON - Calculate stress
|
||||||
|
delta = ckt->CKTtime - here->relStruct->time ;
|
||||||
|
|
||||||
|
// Calculate Aging - Giorgio Liatis' Model
|
||||||
|
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
return (E_INTERN) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update time and flag - Recovery begins
|
||||||
|
here->relStruct->time = ckt->CKTtime ;
|
||||||
|
here->relStruct->IsON = 0 ;
|
||||||
|
} else if (here->relStruct->IsON == 0) {
|
||||||
|
// Until now, the device was OFF - Do NOTHING
|
||||||
|
delta = -1 ;
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mode == 1) {
|
||||||
|
// In this mode, it doesn't matter if NOW the device is in stress or in recovery, since it's the last timestep
|
||||||
|
if (here->relStruct->IsON == 1)
|
||||||
|
{
|
||||||
|
// Calculate stress
|
||||||
|
delta = ckt->CKTtime - here->relStruct->time ;
|
||||||
|
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
return (E_INTERN) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update time and flag - Maybe Optional
|
||||||
|
here->relStruct->time = ckt->CKTtime ;
|
||||||
|
here->relStruct->IsON = 1 ;
|
||||||
|
} else if (here->relStruct->IsON == 0) {
|
||||||
|
// Calculate recovery
|
||||||
|
delta = ckt->CKTtime - here->relStruct->time ;
|
||||||
|
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
||||||
|
if (ret == 1)
|
||||||
|
{
|
||||||
|
return (E_INTERN) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update time and flag - Maybe Optional
|
||||||
|
here->relStruct->time = ckt->CKTtime ;
|
||||||
|
here->relStruct->IsON = 0 ;
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||||
|
}
|
||||||
|
printf ("\tTime: %-.9gs\t\t", ckt->CKTtime) ;
|
||||||
|
printf ("DeltaVth: %-.9gmV\t\t", here->relStruct->deltaVth * 1000) ;
|
||||||
|
printf ("Device Name: %s\t\t", here->BSIM4name) ;
|
||||||
|
printf ("Device Type: %s\n\n", model->BSIM4modName) ;
|
||||||
|
} else {
|
||||||
|
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
BSIM4reliability (GENmodel *inModel, CKTcircuit *ckt, unsigned int mode)
|
BSIM4reliability (GENmodel *inModel, CKTcircuit *ckt, unsigned int mode)
|
||||||
{
|
{
|
||||||
BSIM4model *model = (BSIM4model *)inModel ;
|
BSIM4model *model = (BSIM4model *)inModel ;
|
||||||
BSIM4instance *here ;
|
BSIM4instance *here ;
|
||||||
double delta, vds, vgs, von ;
|
GENrelmodelDeviceElem *elem ;
|
||||||
int NowIsON, ret ;
|
|
||||||
|
|
||||||
/* loop through all the BSIM4 device models */
|
/* loop through all the BSIM4 device models */
|
||||||
for ( ; model != NULL ; model = model->BSIM4nextModel)
|
for ( ; model != NULL ; model = model->BSIM4nextModel)
|
||||||
{
|
{
|
||||||
/* loop through all the instances of the model */
|
if (model->BSIM4type == PMOS)
|
||||||
for (here = model->BSIM4instances ; here != NULL ; here=here->BSIM4nextInstance)
|
|
||||||
{
|
{
|
||||||
if (model->BSIM4type == PMOS)
|
if (model->BSIM4relmodelDeviceList != NULL)
|
||||||
{
|
{
|
||||||
// Determine if the transistor is ON or OFF
|
for (elem = model->BSIM4relmodelDeviceList ; elem != NULL ; elem = elem->next)
|
||||||
vds = ckt->CKTstate0 [here->BSIM4vds] ;
|
|
||||||
vgs = ckt->CKTstate0 [here->BSIM4vgs] ;
|
|
||||||
von = model->BSIM4type * here->BSIM4von ;
|
|
||||||
if (vds >= 0)
|
|
||||||
{
|
{
|
||||||
// printf ("VDS >= 0\tBSIM4type: %d\tBSIM4instance: %s\tVgs: %-.9g\tVon: %-.9g\t", model->BSIM4type, here->BSIM4name, vgs, von) ;
|
here = (BSIM4instance *)(CKTfndDev (ckt, elem->device_name)) ;
|
||||||
if (vgs > von)
|
if (!here)
|
||||||
{
|
{
|
||||||
if (here->BSIM4rgateMod == 3)
|
SPfrontEnd->IFerrorf (ERR_WARNING, "Error: Cannot find the %s instance of the %s model", elem->device_name, model->BSIM4modName) ;
|
||||||
{
|
|
||||||
double vges, vgms ;
|
|
||||||
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
|
||||||
vgms = ckt->CKTstate0 [here->BSIM4vgms] ;
|
|
||||||
if ((vges > von) && (vgms > von))
|
|
||||||
{
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
} else {
|
|
||||||
// printf ("Spento!\n") ;
|
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
|
||||||
} else if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2)) {
|
|
||||||
double vges ;
|
|
||||||
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
|
||||||
if (vges > von)
|
|
||||||
{
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
} else {
|
|
||||||
// printf ("Spento!\n") ;
|
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// printf ("Spento!\n") ;
|
BSIM4reliability_internal (here, ckt, mode) ;
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
double vgd ;
|
|
||||||
vgd = vgs - vds ;
|
|
||||||
// printf ("VDS < 0\tBSIM4type: %d\tBSIM4instance: %s\tVgd: %-.9g\tVon: %-.9g\t", model->BSIM4type, here->BSIM4name, vgd, von) ;
|
|
||||||
if (vgd > von)
|
|
||||||
{
|
|
||||||
if (here->BSIM4rgateMod == 3)
|
|
||||||
{
|
|
||||||
double vges, vged, vgms, vgmd ;
|
|
||||||
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
|
||||||
vged = vges - vds ;
|
|
||||||
vgms = ckt->CKTstate0 [here->BSIM4vgms] ;
|
|
||||||
vgmd = vgms - vds ;
|
|
||||||
if ((vged > von) && (vgmd > von))
|
|
||||||
{
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
} else {
|
|
||||||
// printf ("Spento!\n") ;
|
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
|
||||||
} else if ((here->BSIM4rgateMod == 1) || (here->BSIM4rgateMod == 2)) {
|
|
||||||
double vges, vged ;
|
|
||||||
vges = ckt->CKTstate0 [here->BSIM4vges] ;
|
|
||||||
vged = vges - vds ;
|
|
||||||
if (vged > von)
|
|
||||||
{
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
} else {
|
|
||||||
// printf ("Spento!\n") ;
|
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// printf ("Acceso!\n") ;
|
|
||||||
NowIsON = 1 ;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// printf ("Spento!\n") ;
|
|
||||||
NowIsON = 0 ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// If it's the first time, initialize 'here->relStruct->IsON'
|
/* loop through all the instances of the model */
|
||||||
if (here->relStruct->IsON == -1)
|
for (here = model->BSIM4instances ; here != NULL ; here=here->BSIM4nextInstance)
|
||||||
{
|
{
|
||||||
here->relStruct->IsON = NowIsON ;
|
BSIM4reliability_internal (here, ckt, mode) ;
|
||||||
}
|
|
||||||
|
|
||||||
if (mode == 0)
|
|
||||||
{
|
|
||||||
if (NowIsON)
|
|
||||||
{
|
|
||||||
if (here->relStruct->IsON == 1)
|
|
||||||
{
|
|
||||||
// Until now, the device was ON - Do NOTHING
|
|
||||||
delta = -1 ;
|
|
||||||
} else if (here->relStruct->IsON == 0) {
|
|
||||||
// Until now, the device was OFF - Calculate recovery
|
|
||||||
delta = ckt->CKTtime - here->relStruct->time ;
|
|
||||||
|
|
||||||
// Calculate Aging - Giogio Liatis' Model
|
|
||||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
return (E_INTERN) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update time and flag - Stress begins
|
|
||||||
here->relStruct->time = ckt->CKTtime ;
|
|
||||||
here->relStruct->IsON = 1 ;
|
|
||||||
} else {
|
|
||||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (here->relStruct->IsON == 1)
|
|
||||||
{
|
|
||||||
// Until now, the device was ON - Calculate stress
|
|
||||||
delta = ckt->CKTtime - here->relStruct->time ;
|
|
||||||
|
|
||||||
// Calculate Aging - Giorgio Liatis' Model
|
|
||||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
return (E_INTERN) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update time and flag - Recovery begins
|
|
||||||
here->relStruct->time = ckt->CKTtime ;
|
|
||||||
here->relStruct->IsON = 0 ;
|
|
||||||
} else if (here->relStruct->IsON == 0) {
|
|
||||||
// Until now, the device was OFF - Do NOTHING
|
|
||||||
delta = -1 ;
|
|
||||||
} else {
|
|
||||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (mode == 1) {
|
|
||||||
// In this mode, it doesn't matter if NOW the device is in stress or in recovery, since it's the last timestep
|
|
||||||
if (here->relStruct->IsON == 1)
|
|
||||||
{
|
|
||||||
// Calculate stress
|
|
||||||
delta = ckt->CKTtime - here->relStruct->time ;
|
|
||||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
return (E_INTERN) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update time and flag - Maybe Optional
|
|
||||||
here->relStruct->time = ckt->CKTtime ;
|
|
||||||
here->relStruct->IsON = 1 ;
|
|
||||||
} else if (here->relStruct->IsON == 0) {
|
|
||||||
// Calculate recovery
|
|
||||||
delta = ckt->CKTtime - here->relStruct->time ;
|
|
||||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
|
||||||
if (ret == 1)
|
|
||||||
{
|
|
||||||
return (E_INTERN) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update time and flag - Maybe Optional
|
|
||||||
here->relStruct->time = ckt->CKTtime ;
|
|
||||||
here->relStruct->IsON = 0 ;
|
|
||||||
} else {
|
|
||||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
|
||||||
}
|
|
||||||
printf ("\tTime: %-.9gs\t\t", ckt->CKTtime) ;
|
|
||||||
printf ("DeltaVth: %-.9gmV\t\t", here->relStruct->deltaVth * 1000) ;
|
|
||||||
printf ("Device Name: %s\t\t", here->BSIM4name) ;
|
|
||||||
printf ("Device Type: %s\n\n", model->BSIM4modName) ;
|
|
||||||
} else {
|
|
||||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -834,6 +834,7 @@ typedef struct sBSIM4model
|
||||||
|
|
||||||
#ifdef RELAN
|
#ifdef RELAN
|
||||||
GENmodel *BSIM4relmodelModel ;
|
GENmodel *BSIM4relmodelModel ;
|
||||||
|
GENrelmodelDeviceElem *BSIM4relmodelDeviceList ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* --- end of generic struct GENmodel --- */
|
/* --- end of generic struct GENmodel --- */
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,19 @@ extern IFsimulator *ft_sim;
|
||||||
static void
|
static void
|
||||||
dot_appendmodel (CKTcircuit *ckt, INPtables *tab, card *current)
|
dot_appendmodel (CKTcircuit *ckt, INPtables *tab, card *current)
|
||||||
{
|
{
|
||||||
/* .appendmodel from_model to_model */
|
/* .appendmodel from_model to_model <list_of_devices> */
|
||||||
|
|
||||||
int type; /* the type the model says it is */
|
int error ; /* error code temporary */
|
||||||
char *line ; /* the part of the current line left to parse */
|
int type ; /* the type the model says it is */
|
||||||
char *relmodel_name ; /* the relmodel name */
|
char *line ; /* the part of the current line left to parse */
|
||||||
char *appendmodel_name ; /* the appendmodel name */
|
char *relmodel_name ; /* the relmodel name */
|
||||||
char *save ; /* saj - used to save the posn of the start of
|
char *appendmodel_name ; /* the appendmodel name */
|
||||||
the parameters if the model is a mosfet */
|
char *device_name ; /* the device name in the list of devices */
|
||||||
char *model ; /* the name of the model */
|
char *save ; /* saj - used to save the posn of the start of
|
||||||
INPmodel *thismodel ; /* pointer to model description for user's model */
|
the parameters if the model is a mosfet */
|
||||||
GENmodel *mdfast ; /* pointer to the actual model */
|
char *model ; /* the name of the model */
|
||||||
|
INPmodel *thismodel ; /* pointer to model description for user's model */
|
||||||
|
GENmodel *mdfast ; /* pointer to the actual model */
|
||||||
char* err_msg ;
|
char* err_msg ;
|
||||||
|
|
||||||
#ifdef TRACE
|
#ifdef TRACE
|
||||||
|
|
@ -122,6 +124,23 @@ dot_appendmodel (CKTcircuit *ckt, INPtables *tab, card *current)
|
||||||
INPgetModBin (ckt, relmodel_name, &thismodel, tab, line) ;
|
INPgetModBin (ckt, relmodel_name, &thismodel, tab, line) ;
|
||||||
}
|
}
|
||||||
thismodel->INPmodfast->GENrelmodelModel = mdfast ; /* Attach 'relmodel' model to 'appendmodel' model */
|
thismodel->INPmodfast->GENrelmodelModel = mdfast ; /* Attach 'relmodel' model to 'appendmodel' model */
|
||||||
|
|
||||||
|
// Parse the rest of the line, which is a list of devices
|
||||||
|
thismodel->INPmodfast->GENrelmodelDeviceList = NULL ;
|
||||||
|
while (*line)
|
||||||
|
{
|
||||||
|
INPgetTok (&line, &device_name, 1) ;
|
||||||
|
error = INPretrieve (&device_name, tab) ;
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
printf ("Warning: Cannot find the %s instance of the %s model - Skipping this instance\n\n", device_name, appendmodel_name) ;
|
||||||
|
} else {
|
||||||
|
GENrelmodelDeviceElem *GENrelmodelDevice = TMALLOC (GENrelmodelDeviceElem, 1) ;
|
||||||
|
GENrelmodelDevice->device_name = device_name ;
|
||||||
|
GENrelmodelDevice->next = thismodel->INPmodfast->GENrelmodelDeviceList ;
|
||||||
|
thismodel->INPmodfast->GENrelmodelDeviceList = GENrelmodelDevice ;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LITERR ("Error: The model 'relmodel' hasn't been defined\n\n") ;
|
LITERR ("Error: The model 'relmodel' hasn't been defined\n\n") ;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue