# HP ADS 1.5 User-defined Models Manual PDF

Brand: HP, Pages: 216, PDF Size: 1.33 MB

### Page 26 from 216

1-20 Characteristics of User-Compiled Elements

Building User-Compiled Analog Models

Creating Circuit Elements Interface Definitions and Declarations

Interfacing to the simulator code requires the use of certain ADS defined public C

symbols in user-defined element modules. The remainder of this chapter describes

the supplied userdefs.h file that contains these symbols (macros, interface data

structure typedefs, and function declarations). Note that the Model Development Kit

interface will automatically generate most of these functions and that the header file

will automatically be included.

Success or failure of a typical interface function call is determined by its return value,

1 for success and 0 for failure. Therefore, the ‘

boolean’ typedef and these macros are

provided. Although this boolean type is integer-valued, only

TRUE and FALSE values

should be associated with it.

#define FALSE 0

#define false 0

#define TRUE 1

#define true 1

typedef int boolean;

Four macros define the Boltzmann constant (Joules/Kelvin), the charge of an electron

(Coulombs), the negative of absolute zero temperature (Celsius), and the standard

noise reference temperature (Kelvin). The noise-current correlation parameters

returned by an element’s noise analysis function must be normalized to

FOUR_K_TO--these parameters have admittance dimensions.

/* * define some physical constants */

#define BOLTZ 1.3806226e-23

#define CHARGE 1.6021918e-19

#define CTOK 273.15

#define NOISE_REF_TEMP 2 90.0 /* standard noise reference

temperature, in Kelvin */

#define FOUR_K_TO (4.0*BOLTZ*NOISE_REF_TEMP)

/* noise normalization 4kToB, B=1 Hz */

This macro obtains the number of items in an array definition at compile time.

#define siz(thing) (sizeof(thing)/sizeof(*thing))

For clarity, an argument passed by reference can be prefixed by one of these macros

in an ANSI function definition and prototype declaration.

#define IN /* input argument to function */

#define OUT /* output argument: modified/set by function */

#define INOUT /* argument used and modified by function */

#define UNUSED /* unused argument */

### Page 27 from 216

Characteristics of User-Compiled Elements 1-21

Linear response modeled in the frequency domain is complex, so the COMPLEX type is

used for admittance (Y), scattering (S), and noise current-correlation parameters.

typedef struct

{

double real;

double imag;

}

COMPLEX;

Each element parameter has a specific type.

typedef enum

{

NO_data = -1, /* unspecified */

REAL_data = 0,

INT_data = 1,

MTRL_data = 2, /* for parameter referring to an instance */

STRG_data = 3,

COMPLEX_data = 4

}

DataTypeE;

Each element parameter definition consists of a keyword string and type.

typedef struct {

char *keyword;

DataTypeE dataType

}

UserParamType;

The parameter values of an item are obtained in an array of the UserParamData type.

dataType is the discriminator tag to determine the actual value of the union. For

example, if it is

MTRL_data, value.eeElemInst will refer to a substrate or model form.

typedef struct

{

DataTypeE dataType;

union

{

double dVal; /* for REAL_data */

int iVal; /* for INT_data */

void *eeElemInst; /* for MTRL_data */

char *strg; /* for STRG_data */

}value;

} UserParamData;

### Page 28 from 216

1-22 Characteristics of User-Compiled Elements

Building User-Compiled Analog Models

This type can be used specifically for 2-port elements if the conventional 2-port noise

parameters are available.

typedef struct

{

double nFmin; /* Noise Figure (dB) */

double magGamma; /* |opt. source Gamma| */

double angGamma; /*

double rNorm; /* Normalizing resistance (ohms) */

} NParType;

Each user-element definition is of the UserElemDef type. The pre_analysis function is

useful for one-time operations such as parameter type checking, allocating memory,

and reading data files. This routine is called for all types of analysis.

Note that a nonlinear or parametric subnetwork instantiation will be flattened

(expanded) in the parent network. If there are two or more uses of a given

subnetwork, each occurrence will result in the pre-analysis function (and

post-analysis function) being called. The function must be written to properly

manage such actions as reading data files and allocating memory.

The

compute_y function must load the nodal admittance matrix parameters at

frequency omega radians/sec into the passed

yPar array. This function can call

ee_compute_y (described later) to use another element's admittance parameters.

The

compute_n function must load the normalized nodal noise current correlation

parameters (Siemens, normalized to

FOUR_K_TO) into the passed nCor array at

frequency omega radians/sec and the element admittance parameters,

yPar. It can

call

ee_compute_y (described later) to make use of another element's admittance and

noise correlation matrices.

The

post_analysis function, called before processing a new circuit, is generally used

for cleanup operations such as freeing memory or deleting temporary files. This

function is called for all types of analysis. This function is called once for each

occurrence of an element, so it must be written to properly manage this situation.

A nonlinear element must contain additional device information in a static area of

type

UserNonLinDef (described later); the pointer devDef must point to it.

The

seniorInfo field is of arbitrary type, and can be used for any extra user-defined

data/description that is of no concern to the simulator.

A transient response for an element can be defined in a structure of type

UserTranDef

(described later); the pointer

tranDef must point to the structure. A transient

response function can be defined for either a linear or nonlinear element.

### Page 29 from 216

Characteristics of User-Compiled Elements 1-23 typedef struct _UserElemDef UserElemDef;

struct _UserElemDef

{

char *name; /* Element name. Not to exceed 8 characters */

int numExtNodes; /* Number of external nodes, max. 20 for linear element */

int numPars; /* Number of parameters for this element */

UserParamType *params; /* parameter array */

/* pre-analysis function: called after element item parsed successfully */

boolean (*pre_analysis)(INOUT UserInstDef *pInst);

/* Linear analysis function: called once for each new frequency point.

* Must return the item's admittance matrix in yPar array.

* NULL for nonlinear element */

boolean (*compute_y)(IN UserInstDef *pInst, IN double omega, OUT COMPLEX

*yPar);

/* Linear noise-analysis function: called once for each new frequency point.

Must return the item's noise-current correlation admittance, normalized to

FOUR_K_TO in nCor array.

* NULL if noiseless */

boolean (*compute_n)(IN UserInstDef *pInst, IN double omega, IN COMPLEX

*yPar, OUT COMPLEX *nCor);

/* post-analysis: called before new netlist is parsed */

boolean (*post_analysis)(INOUT UserInstDef *pInst);

UserNonLinDef *devDef; /* User's nonlinear device definition (NULL if

linear) */

struct _SeniorType *seniorInfo; /* Senior user defined type and data

(arbitrary) */

UserTranDef *tranDef; /* User's transient definition; NULL if none */

};

A nonlinear element response is characterized by the functions in the UserNonLinDef

type.

### Page 30 from 216

1-24 Characteristics of User-Compiled Elements

Building User-Compiled Analog Models

numIntNodes

is the number of nodes internal to the element. In its model, the element

code must compute the contributions at all of its pins, which are ordered by external

followed by internal pins. If a

UserTranDef type is defined for the element, the

numIntNodes in that structure must match this definition.

analyze_lin must load only the linear part (complex admittances) of the nonlinear

element in the frequency domain. Each admittance must be loaded by calling the

primitive add_lin_y function. For a branch admittance between nodes (i, j), 4 calls are

needed: +Y for (i, i), (j, j) and -Y for (i, j) and (j, i).

analyze_lin can use ee_compute_y

to take advantage of pre-existing linear elements.

analyze_nl must compute and load

the nonlinear response, using the element's pin voltages as input. The passed array

pinVoltage contains instantaneous values; however, delayed voltage differences can

be obtained using the

get_delay_v function.

If P is the total number of pin voltages, formulate non-zero nonlinear current and

charge at each pin n as follows:

rn (t) = f (v0 (t), v1(t),..., vP-1(t), vk(t-*k), vl(t-*l),...) where rn is the pin current or

charge response,

*k, *l... are ideal delays, independent of the voltages. These responses and their

derivatives with respect to voltage (nonlinear conductances, capacitances) must be

computed and loaded using the

add_nl_iq and add_nl_gc functions, respectively. Note

that the derivatives help the simulator to converge to a solution, but do not affect the

steady-state nonlinear response—therefore they may work even if not exact.

However, under certain simulation conditions in-exact derivatives may cause

convergence problems. However, for noise analysis they should be accurate, and for

convergence they should be continuous.

In a linear simulation, a nonlinear element must contribute its small-signal

linearized response; this is done through the

analyze_ac function. The linear part can

be loaded by calling the element's

analyze_lin function. The linearized part is just

the nonlinear conductances and capacitances computed above simply converted to

admittances at angular frequency omega and loaded into the circuit matrix using

add_lin_y.

Noise contribution of a nonlinear element in a linear simulation is added through the

analyze_ac_n function. The linear and linearized noise correlation parameters are

loaded using the primitive

add_lin_n function. The linearized portion can include

shot, flicker, and burst noise contributions.

The

modelDef field is of arbitrary type and can be used for any extra user-defined

nonlinear model data/description that is of no concern to the simulator.