Interface Variables

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.

typedef struct CMI_MosDef {

char ModelName[100];

char InstanceName[100];

char *pModel;

char *pInstance;

int modelSize;

int instSize;

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. */

int topoid;
} CMI_MOSDEF;

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.

pModel, pInstance

Structure entries of the interface variable are initialized at compile time.

Example

/* function declaration */

int CMImos3ResetModel(char*,int,int);

int CMImos3ResetInstance(char*);

int CMImos3AssignMP(char*,char*,double);

int CMImos3AssignIP(char*,char*,double);

int CMImos3SetupModel(char*);

int CMImos3SetupInstance(char*,char*);

int CMImos3Evaluate(CMI_VAR*,char*,char*);

int CMImos3DiodeEval(CMI_VAR*,char*,char*);

int CMImos3Noise(CMI_VAR *,char*,char*);

int CMImos3PrintModel(char*);

int CMImos3FreeModel(char*);

int CMImos3FreeInstance(char*,char*);

int CMImos3WriteError(int, char*);

int CMImos3Start(void);

int CMImos3Conclude(void);

/* extended model topology, 0 is normal mos, 1 is berkeley SOI, etc. */

/* local */

static MOS3model _Mos3Model;

static MOS3instance _Mos3Instance;

 

static CMI_MOSDEF CMI_mos3def = {

(char*)&_Mos3Model,

(char*)&_Mos3Instance,

CMImos3ResetModel,

CMImos3ResetInstance,

CMImos3AssignMP,

CMImos3AssignIP,

CMImos3SetupModel,

CMImos3SetupInstance,

CMImos3Evaluate,

CMImos3DiodeEval,

CMImos3Noise,

CMImos3PrintModel,

CMImos3FreeModel,

CMImos3FreeInstance,

CMImos3 ,

CMImos3Start,

CMImos3Conclude

};

/* export */

CMI_MOSDEF *pCMI_mos3def = &CMI_mos3def;

*Note: the last 8 functions are optional. Any function not defined should be replaced with NULL.

CMI_ResetModel

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)

 

pmodel

Pointer to the model instance

pmos

1 if PMOS, 0 if NMOS

level

model level value passed from parser

Example

int

#ifdef __STDC__

CMImos3ResetModel(

char *pmodel,

int pmos)

#else

CMImos3ResetModel(pmodel,pmos)

char *pmodel;

int pmos;

#endif

{

/* reset all flags to undefined */

(void)memset(pmodel, 0, sizeof(MOS3model));

/* Note: level contains model level value passed from parser */

if(pmos)

{

((MOS3model*)pmodel)->MOS3type = PMOS;

((MOS3model*)pmodel)->MOS3typeGiven = 1;

}

return 0;

} /* int CMImos3ResetModel() */

CMI_ResetInstance

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)

pinst

Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3ResetInstance(

char *ptran)

#else

CMImos3ResetInstance(ptran)

char *ptran;

#endif

{

(void)memset(ptran, 0, sizeof(MOS3instance));

 

((MOS3instance*)ptran)->MOS3w = 1.0e-4;

((MOS3instance*)ptran)->MOS3l = 1.0e-4;

 

return 0;

} /* int CMImos3ResetInstance() */

CMI_AssignModelParm

This routine sets the value of a model parameter.

int CMI_AssignModelParm(char* pmodel, char* pname,double value)

pmodel

Pointer to the model instance

pname

String of parameter name

value

Parameter value

Example

int

#ifdef __STDC__

CMImos3AssignMP(

char *pmodel,

char *pname,

double value)

#else

CMImos3AssignMP(pmodel,pname,value)

char *pmodel;

char *pname;

double value;

#endif

{

int param;

 

CMImos3GetMpar(pname, &param);

CMImos3SetMpar(param, value, (MOS3model*)pmodel);

 

return 0;

} /* int CMImos3AssignMP() */

CMI_AssignInstanceParm

This routine sets the value of an instance parameter.

int CMI_AssignInstanceParm(char *pinst,char* pname,double value)

pinst

Pointer to the instance

pname

String of parameter name

value

Parameter value

Example

int

#ifdef __STDC__

CMImos3AssignIP(

char *ptran,

char *pname,

double value)

#else

CMImos3AssignIP(ptran,pname,value)

char *ptran;

char *pname;

double value;

#endif

{

int param;

 

CMImos3GetIpar(pname, &param);

CMImos3SetIpar(param, value, (MOS3instance*)ptran);

 

return 0;

} /* int CMImos3AssignIP() */

CMI_SetupModel

This routine sets up a model after all the model parameters are specified.

int CMI_SetupModel(char* pmodel)

pmodel

Pointer to the model

Example

int

#ifdef __STDC__

CMImos3SetupModel(

char *pmodel)

#else

CMImos3SetupModel(pmodel)

char *pmodel;

#endif

{

CMImos3setupModel((MOS3model*)pmodel);

 

return 0;

} /* int CMImos3SetupModel() */

CMI_SetupInstance

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)

pinst

Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3SetupInstance(

char *pmodel,

char *ptran)

#else

CMImos3SetupInstance(pmodel,ptran)

char *pmodel;

char *ptran;

#endif

{

/* temperature modified parameters */

CMImos3temp((MOS3model*)pmodel,(MOS3instance*)ptran);

 

return 0;

} /* int CMImos3SetupInstance() */

CMI_Evaluate

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

pmodel Pointer to the model

pinst Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3Evaluate(

CMI_VAR *pslot,

char *pmodel,

char *ptr)

#else

CMImos3Evaluate(pslot,pmodel,ptr)

CMI_VAR *pslot;

char *pmodel;

char *ptr;

#endif

{

CMI_ENV *penv;

MOS3instance *ptran;

penv = pCMIenv; /* pCMIenv is a global */

ptran = (MOS3instance*)ptr;

/* call model evaluation */

(void)CMImos3evaluate(penv,(MOS3model*)pmodel,ptran,

pslot->vgs,pslot->vds,pslot->vbs);

 

pslot->gd = ptran->MOS3drainConductance;

pslot->gs = ptran->MOS3sourceConductance;

pslot->von = ptran->MOS3von;

pslot->ids = ptran->MOS3cd;

pslot->gds = ptran->MOS3gds;

pslot->gm = ptran->MOS3gm;

pslot->gmbs = ptran->MOS3gmbs;

pslot->gbd = ptran->MOS3gbd;

pslot->gbs = ptran->MOS3gbs;

pslot->cgs = ptran->MOS3capgs;

pslot->cgd = ptran->MOS3capgd;

pslot->cgb = ptran->MOS3capgb;

pslot->capdb = ptran->MOS3capbd;

pslot->capsb = ptran->MOS3capbs;

pslot->cbso = ptran->MOS3cbs;

pslot->cbdo = ptran->MOS3cbd;

...Additional CMI_VAR elements should be assigned here for substrate model and overlap capacitances.

 

return 0;

} /* int CMImos3Evaluate() */

CMI_DiodeEval

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)

 

pvar

Pointer to CMI_VAR variable

pmodel

Pointer to the model

pinst

Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3DiodeEval(

CMI_VAR *pslot,

char *pmodel,

char *ptr)

#else

CMImos3Diode(pslot,pmodel,ptr)

CMI_VAR *pslot;

char *pmodel;

char *ptr;

#endif

{

CMI_ENV *penv;

MOS3instance *ptran;

penv = pCMIenv; /* pCMIenv is global */

ptran = (MOS3instance*)ptr;

/* call model evaluation */

(void)CMImos3diode(penv,(MOS3model*)pmodel,ptran,

pslot->vgs,pslot->vds,pslot->vbs);

 

pslot->ibs = ptran->MOS3ibs;

pslot->ibd = ptran->MOS3ibd;

pslot->gbs = ptran->MOS3gbs;

pslot->gbd = ptran->MOS3gbd;

pslot->capbs = ptran->MOS3capbs;

pslot->capbd = ptran->MOS3capbd;

pslot->qbs = ptran->MOS3qbs;

pslot->qdb = ptran->MOS3qbd;

return 0;

} /* int CMImos3DiodeEval() */

CMI_Noise

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)

pvar

Pointer to CMI_VAR variable

pmodel

Pointer to the model

pinst

Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3Noise(

CMI_VAR *pslot,

char *pmodel,

char *ptr)

#else

CMImos3Noise(pslot,pmodel,ptr)

CMI_VAR *pslot;

char *pmodel;

char *ptr;

#endif

{double freq,fourkt;

CMI_ENV *penv

MOS3instance *ptran;

penv = pCMIenv; /* pCMIenv is a global */

 

ptran = (MOS3instance*)ptr;

fourkt = 4.0 * BOLTZMAN * ptran->temp; /* 4kT */

freq = pslot->freq;

 

/* 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);

 

return 0;

} /* int CMImos3Noise() */

CMI_PrintModel

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)

pmodel

Pointer to the model

Example

int

#ifdef __STDC__

CMImos3PrintModel(

char *pmodel)

#else

CMImos3PrintModel(pmodel)

char *pmodel;

#endif

{

CMI_ENV *penv

 

/* Note: source for CMImos3printmodel() not shown*/

(void)CMImos3printmodel((MOS3model*)pmodel);

 

return 0;

} /* int CMImos3PrintModel() */

CMI_FreeModel

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)

pmodel

Pointer to the model

Example

int

#ifdef __STDC__

CMImos3FreeModel(

char *pmodel)

#else

CMImos3FreeModel(pmodel)

char *pmodel;

#endif

{

/* free memory allocated for model data. Note CMImos3freemodel() source code not shown. */

(void)CMImos3freemodel((MOS3model*)pmodel);

 

return 0;

} /* int CMImos3FreeModel() */

CMI_FreeInstance

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)

pmodel

Pointer to the model

pinst

Pointer to the instance

Example

int

#ifdef __STDC__

CMImos3FreeInstance(

char *pmodel,

char *ptr)

#else

CMImos3FreeInstance(pmodel,ptr)

char *pmodel;

char *ptr;

#endif

{

CMI_ENV *penv

MOS3instance *ptran;

 

ptran = (MOS3instance*)ptr;

/* free memory allocated for model data. Note CMImos3freeinstance()source code not shown.
*/

(void)CMImos3freeinstance((MOS3model*)pmodel,ptran);

 

return 0;

} /* int CMImos3FreeInstance() */

CMI_WriteError

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)

err_code

Error code

err_str

Pointer to error message

returns error status (>0 Hspice aborts, ==0 Hspice continues)

Example

int

#ifdef __STDC__

CMImos3WriteError(

void err_code,

char *err_str)

#else

CMImos3WriteError(err_code,err_str)

int err_code;

char *err_str;

#endif

{

/* */

int err_status=0;

switch err_code

{

case 1:

strcpyn(err_str,"User Err: Eval()",CMI_ERR_STR_LEN);

err_status=1;

case 2:

strcpyn(err_str,"User Warn: Eval()",CMI_ERR_STR_LEN);

err_status=1;

default:

strcpyn(err_str,"User Err:Generic",CMI_ERR_STR_LEN);

err_status=1;

}

return err_status;

} /* int CMImos3WriteError() */

CMI_Start

This routine allows user-defined startup functions to be run once prior to simulation.

int CMI_Start(void)

Example

int

#ifdef __STDC__

CMImos3Start(void)

#else

CMImos3Start(void)

#endif

{

(void)CMImos3start();

 

return 0;

} /* int CMImos3Start() */

CMI_Conclude

This routine allows user-defined conclude functions to be run once at post-simulation time.

int CMI_Conclude(void)

Example

int

#ifdef __STDC__

CMImos3Conclude(void)

#else

CMImos3Conclude(void)

#endif

{

(void)CMImos3conclude();

 

return 0;

} /* int CMImos3Conclude() */Internal Routines */

CMI Function Calling Protocol

CMI calls the interface routines in the sequence as shown in Interface Routines Calling Sequence.

 

Figure 23-1: Interface Routines Calling Sequence
Star-Hspice Manual - Release 2001.2 - June 2001