To assign model/instance parameter values and evaluate I-V, C-V response, fifteen interface routines are required. For each new model, pointers to these routines and the model/instance variables are defined by an interface variable in type CMI_MOSDEF, which can be found in the include/CMIdef.h file.
int (*CMI_ResetModel)(char*,int,int);
int (*CMI_ResetInstance)(char*);
int (*CMI_AssignModelParm)(char*,char*,double);
int (*CMI_AssignInstanceParm)(char*,char*,double);
int (*CMI_SetupModel)(char*);
int (*CMI_SetupInstance)(char*,char*);
int (*CMI_Evaluate)(CMI_VAR*,char*,char*);
int (*CMI_DiodeEval)(CMI_VAR*,char*,char*);
int (*CMI_Noise)(CMI_VAR *,char*,char*);
int (*CMI_PrintModel)(char*);
int (*CMI_FreeModel)(char*);
int (*CMI_FreeInstance)(char*,char*);
int (*CMI_WriteError)(int, char*);
int (*CMI_Start)(void);
int (*CMI_Conclude)(void);
/* extended model topology,0 is normal mos, 1 is berkeley SOI, etc. */
All routines return 0 on success, or nonzero integer (a user-defined error code) in case of warning or error. The following sections describe each entry. Examples for the first seven functions are extracted from the MOS3 implementation. Examples for the remaining eight functions are not part of the actual MOS3 code, but are included for demonstration. The example MOS3 implementation contains one header file and eight C files. All routines are derived from SPICE-3 code.
Structure entries of the interface variable are initialized at compile time.
int CMImos3ResetModel(char*,int,int);
int CMImos3ResetInstance(char*);
int CMImos3AssignMP(char*,char*,double);
int CMImos3AssignIP(char*,char*,double);
int CMImos3SetupInstance(char*,char*);
int CMImos3Evaluate(CMI_VAR*,char*,char*);
int CMImos3DiodeEval(CMI_VAR*,char*,char*);
int CMImos3Noise(CMI_VAR *,char*,char*);
int CMImos3FreeInstance(char*,char*);
int CMImos3WriteError(int, char*);
/* extended model topology, 0 is normal mos, 1 is berkeley SOI, etc. */
static MOS3instance _Mos3Instance;
static CMI_MOSDEF CMI_mos3def = {
CMI_MOSDEF *pCMI_mos3def = &CMI_mos3def;
*Note: the last 8 functions are optional. Any function not defined should be replaced with NULL.
This routine initializes all the parameters of a model. All model parameters should become undefined after initialization. Undefined means "not given in a netlist model card". The flag pmos is used to set transistor type after initialization.
int CMI_ResetModel(char* pmodel, int pmos, int level)
CMImos3ResetModel(pmodel,pmos)
/* reset all flags to undefined */
(void)memset(pmodel, 0, sizeof(MOS3model));
/* Note: level contains model level value passed from parser */
((MOS3model*)pmodel)->MOS3type = PMOS;
((MOS3model*)pmodel)->MOS3typeGiven = 1;
} /* int CMImos3ResetModel() */
This routine initializes all parameter settings of an instance. All instance parameters should be undefined after initialization. "Undefined" means "not given in a netlist MOS instance".
int CMI_ResetInstance(char* pinst)
(void)memset(ptran, 0, sizeof(MOS3instance));
((MOS3instance*)ptran)->MOS3w = 1.0e-4;
((MOS3instance*)ptran)->MOS3l = 1.0e-4;
} /* int CMImos3ResetInstance() */
This routine sets the value of a model parameter.
int CMI_AssignModelParm(char* pmodel, char* pname,double value)
CMImos3AssignMP(pmodel,pname,value)
CMImos3GetMpar(pname, ¶m);
CMImos3SetMpar(param, value, (MOS3model*)pmodel);
This routine sets the value of an instance parameter.
int CMI_AssignInstanceParm(char *pinst,char* pname,double value)
CMImos3AssignIP(ptran,pname,value)
CMImos3GetIpar(pname, ¶m);
CMImos3SetIpar(param, value, (MOS3instance*)ptran);
This routine sets up a model after all the model parameters are specified.
int CMI_SetupModel(char* pmodel)
CMImos3setupModel((MOS3model*)pmodel);
} /* int CMImos3SetupModel() */
This routine sets up an instance after all the instance parameters are specified. Typically temperature and geometry processing are performed here.
int CMI_SetupInstance(char* pinst)
CMImos3SetupInstance(pmodel,ptran)
/* temperature modified parameters */
CMImos3temp((MOS3model*)pmodel,(MOS3instance*)ptran);
} /* int CMImos3SetupInstance() */
Based on the bias conditions and model/instance parameter values, this routine evaluates the model equations and passes all transistor characteristics via the CMI_VAR variable.
int CMI_Evaluate(CMI_VAR *pvar ,char *pmodel. char *pinst)
pvar Pointer to CMI_VAR variable
CMImos3Evaluate(pslot,pmodel,ptr)
penv = pCMIenv; /* pCMIenv is a global */
(void)CMImos3evaluate(penv,(MOS3model*)pmodel,ptran,
pslot->vgs,pslot->vds,pslot->vbs);
pslot->gd = ptran->MOS3drainConductance;
pslot->gs = ptran->MOS3sourceConductance;
pslot->gmbs = ptran->MOS3gmbs;
pslot->cgs = ptran->MOS3capgs;
pslot->cgd = ptran->MOS3capgd;
pslot->cgb = ptran->MOS3capgb;
pslot->capdb = ptran->MOS3capbd;
pslot->capsb = ptran->MOS3capbs;
...Additional CMI_VAR elements should be assigned here for substrate model and overlap capacitances.
Based on the bias conditions and model/instance parameter values, this routine evaluates the MOS junction diode model equations and passes all transistor characteristics via the CMI_VAR variable.
int CMI_DiodeEval(CMI_VAR *pvar ,char *pmodel. char *pinst)
CMImos3Diode(pslot,pmodel,ptr)
penv = pCMIenv; /* pCMIenv is global */
(void)CMImos3diode(penv,(MOS3model*)pmodel,ptran,
pslot->vgs,pslot->vds,pslot->vbs);
pslot->capbs = ptran->MOS3capbs;
pslot->capbd = ptran->MOS3capbd;
} /* int CMImos3DiodeEval() */
Based on the bias conditions, temperature, and model/instance parameter values, this routine evaluates the noise model equations and returns noise characteristics via the CMI_VAR variable.
The value passed to pslot->nois_irs should be the thermal noise associated with the parasitic source resistance expressed as a mean square noise current in parallel with Rs.
The value passed to
pslot->nois_ird
should be the thermal noise associated with
the parasitic drain resistance expressed as a mean square noise current in parallel with Rd.
The value passed to pslot->nois_idsth should be the thermal noise associated with the MOSFET expressed as a mean square noise current referenced across the MOSFET channel.
The value passed to pslot->nois_idsfl should be the flicker noise associated with the MOSFET expressed as a mean square noise current referenced across the MOSFET channel. Frequency is passed into CMI_Noise via pslot->freq.
int CMI_Noise(CMI_VAR *pvar ,char *pmodel. char *pinst)
CMImos3Noise(pslot,pmodel,ptr)
penv = pCMIenv; /* pCMIenv is a global */
fourkt = 4.0 * BOLTZMAN * ptran->temp; /* 4kT */
/* Drain resistor thermal noise as current^2 source*/
pslot->nois_ird = fourkt * ptran->gdpr;
/* Source resistor thermal noise as current^2 source */
pslot->nois_irs = fourkt * ptran->gspr;
/* thermal noise assumed to be current^2 source referenced to channel. The source code for thermalnoise() is not shown here*/
pslot->nois_idsth = thermalnoise(model, here, fourkt);
/* flicker (1/f) noise assumed to be current^2 source referenced to channel. The source code for flickernoise() is not shown here */
pslot->nois_idsfl = flickernoise(model, here, freq);
This routine prints all model parameter names, values and units to standard output and is called by Star-Hspice for each model after CMI_SetupModel.
int CMI_PrintModel(char *pmodel)
/* Note: source for CMImos3printmodel() not shown*/
(void)CMImos3printmodel((MOS3model*)pmodel);
} /* int CMImos3PrintModel() */
This routine allows the user to free memory that previously was allocated for model related data. This routine is called during a loop over all models at post-simulation time.
int CMI_FreeModel(char *pmodel)
/* free memory allocated for model data. Note CMImos3freemodel() source code not shown. */
(void)CMImos3freemodel((MOS3model*)pmodel);
} /* int CMImos3FreeModel() */
This routine allows the user to free memory that was previously allocated for storing instance-related data. This routine is called during an outer loop over all models and an inner loop over all instances associated with each model at post-simulation time.
int CMI_FreeInstance(char *pmodel. char *pinst)
CMImos3FreeInstance(pmodel,ptr)
/* free memory allocated for model data. Note CMImos3freeinstance()source code not shown.
*/
(void)CMImos3freeinstance((MOS3model*)pmodel,ptran);
} /* int CMImos3FreeInstance() */
This routine writes user-defined error messages to standard output when an error is detected during model evaluation. All CMI functions return a user-defined error code that is passed into CMI_WriteError(). In CMI_WriteError(), the user defines an error statement, copied to err_str, which is selected based on the error code value. CMI_WriteError() returns the error status: err_status>0 will cause Star-Hspice to write the error message and abort, err_status=0 will cause Star-Hspice to write the warning message and continue. Star-Hspice calls CMI_WriteError() after every CMI function call.
int CMI_WriteError(int err_code, char *err_str)
returns error status (>0 Hspice aborts, ==0 Hspice continues)
CMImos3WriteError(err_code,err_str)
strcpyn(err_str,"User Err: Eval()",CMI_ERR_STR_LEN);
strcpyn(err_str,"User Warn: Eval()",CMI_ERR_STR_LEN);
strcpyn(err_str,"User Err:Generic",CMI_ERR_STR_LEN);
} /* int CMImos3WriteError() */
This routine allows user-defined startup functions to be run once prior to simulation.
This routine allows user-defined conclude functions to be run once at post-simulation time.
} /* int CMImos3Conclude() */Internal Routines */
CMI calls the interface routines in the sequence as shown in Interface Routines Calling Sequence.