From aae86db65c4d2586f3cc9ad8e9686ca694c065a1 Mon Sep 17 00:00:00 2001 From: pnenzi Date: Tue, 10 May 2005 07:01:47 +0000 Subject: [PATCH] Added XSPICE extensions (PHASE parameter) and AM transient function. --- src/spicelib/devices/vsrc/vsrc.c | 1 + src/spicelib/devices/vsrc/vsrcacct.c | 47 ++++-- src/spicelib/devices/vsrc/vsrcask.c | 1 + src/spicelib/devices/vsrc/vsrcdefs.h | 3 + src/spicelib/devices/vsrc/vsrcload.c | 227 +++++++++++++++++++++------ src/spicelib/devices/vsrc/vsrcpar.c | 8 + 6 files changed, 221 insertions(+), 66 deletions(-) diff --git a/src/spicelib/devices/vsrc/vsrc.c b/src/spicelib/devices/vsrc/vsrc.c index ca502bcce..c73da4d67 100644 --- a/src/spicelib/devices/vsrc/vsrc.c +++ b/src/spicelib/devices/vsrc/vsrc.c @@ -19,6 +19,7 @@ IFparm VSRCpTable[] = { /* parameters */ IP ("exp", VSRC_EXP, IF_REALVEC,"Exponential source description"), IP ("pwl", VSRC_PWL, IF_REALVEC,"Piecewise linear description"), IP ("sffm", VSRC_SFFM, IF_REALVEC,"Single freq. FM descripton"), + IP ("am", VSRC_AM, IF_REALVEC,"Amplitude modulation descripton"), OPU ("pos_node",VSRC_POS_NODE, IF_INTEGER,"Positive node of source"), OPU ("neg_node",VSRC_NEG_NODE, IF_INTEGER,"Negative node of source"), OPU ("function",VSRC_FCN_TYPE, IF_INTEGER,"Function of the source"), diff --git a/src/spicelib/devices/vsrc/vsrcacct.c b/src/spicelib/devices/vsrc/vsrcacct.c index 87e2a4761..ac0edc5bb 100644 --- a/src/spicelib/devices/vsrc/vsrcacct.c +++ b/src/spicelib/devices/vsrc/vsrcacct.c @@ -37,7 +37,18 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel) } case PULSE: { + +#define SAMETIME(a,b) (fabs((a)-(b))<= TIMETOL * PW) +#define TIMETOL 1e-7 + double TD, TR, TF, PW, PER; +/* gtri - begin - wbk - add PHASE parameter */ +#ifdef XSPICE + double PHASE; + double phase; + double deltat; + double basephase; +#endif double time; double basetime = 0; @@ -55,25 +66,27 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel) PER = here->VSRCfunctionOrder > 6 && here->VSRCcoeffs[6] != 0.0 ? here->VSRCcoeffs[6] : ckt->CKTfinalTime; +#ifdef XSPICE + PHASE = here->VSRCfunctionOrder > 8 + ? here->VSRCcoeffs[7] : 0.0; + + /* normalize phase to 0 - 2PI */ + phase = PHASE * M_PI / 180.0; + basephase = 2 * M_PI * floor(phase / (2 * M_PI)); + phase -= basephase; -/* - #define TD ((here->VSRCfunctionOrder >=3)?(*(here->VSRCcoeffs+2)):\ - (0.0)) - #define TR ((here->VSRCfunctionOrder >=4)?(*(here->VSRCcoeffs+3)):\ - (ckt->CKTstep)) - #define TF ((here->VSRCfunctionOrder >=5)?(*(here->VSRCcoeffs+4)):\ - (ckt->CKTstep)) - #define PW ((here->VSRCfunctionOrder >=6)?(*(here->VSRCcoeffs+5)):\ - (ckt->CKTfinalTime)) - #define PER ((here->VSRCfunctionOrder>=7)?(*(here->VSRCcoeffs+6)):\ - (ckt->CKTfinalTime)) -*/ + /* compute equivalent delta time and add to time */ + deltat = (phase / (2 * M_PI)) * PER; + time += deltat; +#endif +/* gtri - end - wbk - add PHASE parameter */ -#define SAMETIME(a,b) (fabs((a)-(b))<= TIMETOL * PW) -#define TIMETOL 1e-7 time = ckt->CKTtime - TD; - /* if(ckt->CKTtime >= PER) XXX was this */ + + + + if(time >= PER) { /* repeating signal - figure out where we are */ /* in period */ @@ -144,6 +157,10 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel) /* no breakpoints (yet) */ } break; + case AM:{ + /* no breakpoints (yet) */ + } + break; case PWL: { int i; if(ckt->CKTtime < *(here->VSRCcoeffs)) { diff --git a/src/spicelib/devices/vsrc/vsrcask.c b/src/spicelib/devices/vsrc/vsrcask.c index 07948ec6a..639709e90 100644 --- a/src/spicelib/devices/vsrc/vsrcask.c +++ b/src/spicelib/devices/vsrc/vsrcask.c @@ -43,6 +43,7 @@ VSRCask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue * case VSRC_EXP: case VSRC_PWL: case VSRC_SFFM: + case VSRC_AM: case VSRC_FCN_COEFFS: temp = value->v.numValue = here->VSRCfunctionOrder; v = value->v.vec.rVec = (double *) diff --git a/src/spicelib/devices/vsrc/vsrcdefs.h b/src/spicelib/devices/vsrc/vsrcdefs.h index 867379ddc..28c836b6e 100644 --- a/src/spicelib/devices/vsrc/vsrcdefs.h +++ b/src/spicelib/devices/vsrc/vsrcdefs.h @@ -88,6 +88,7 @@ typedef struct sVSRCmodel { #define EXP 3 #define SFFM 4 #define PWL 5 +#define AM 6 #endif /*PULSE*/ /* device parameters */ @@ -113,6 +114,8 @@ typedef struct sVSRCmodel { #define VSRC_D_F1 20 #define VSRC_D_F2 21 +#define VSRC_AM 22 + /* model parameters */ /* device questions */ diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index c94ac8e4b..e173a8f00 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -11,6 +11,12 @@ Modified: 2000 AlansFixes #include "sperror.h" #include "suffix.h" +#ifdef XSPICE_EXP +/* gtri - begin - wbk - modify for supply ramping option */ +#include "cmproto.h" +/* gtri - end - wbk - modify for supply ramping option */ +#endif /* XSPICE_EXP */ + int VSRCload(GENmodel *inModel, CKTcircuit *ckt) /* actually load the current voltage value into the @@ -37,7 +43,11 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) if( (ckt->CKTmode & (MODEDCOP | MODEDCTRANCURVE)) && here->VSRCdcGiven ) { /* grab dc value */ +#ifdef XSPICE_EXP + value = here->VSRCdcValue; +#else value = ckt->CKTsrcFact * here->VSRCdcValue; +#endif } else { if(ckt->CKTmode & (MODEDC)) { time = 0; @@ -54,6 +64,25 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) case PULSE: { double V1, V2, TD, TR, TF, PW, PER; double basetime = 0; +#ifdef XSPICE + double PHASE; + double phase; + double deltat; + double basephase; + + PHASE = here->VSRCfunctionOrder > 7 + ? here->VSRCcoeffs[7] : 0.0; + + /* normalize phase to 0 - 2PI */ + phase = PHASE * M_PI / 180.0; + basephase = 2 * M_PI * floor(phase / (2 * M_PI)); + phase -= basephase; + + /* compute equivalent delta time and add to time */ + deltat = (phase / (2 * M_PI)) * PER; + time += deltat; +#endif +/* gtri - end - wbk - add PHASE parameter */ V1 = here->VSRCcoeffs[0]; V2 = here->VSRCcoeffs[1]; @@ -93,79 +122,168 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) break; case SINE: { -#define VO (*(here->VSRCcoeffs)) -#define VA (*(here->VSRCcoeffs+1)) -#define FREQ (((here->VSRCfunctionOrder >=3) && (*(here->VSRCcoeffs+2)))? \ - (*(here->VSRCcoeffs+2)):(1/ckt->CKTfinalTime)) -#define TD ((here->VSRCfunctionOrder >=4)?(*(here->VSRCcoeffs+3)):(0.0)) -#define THETA ((here->VSRCfunctionOrder >=5)?(*(here->VSRCcoeffs+4)):(0.0)) + + double VO, VA, FREQ, TD, THETA; +/* gtri - begin - wbk - add PHASE parameter */ +#ifdef XSPICE + double PHASE; + double phase; + + PHASE = here->VSRCfunctionOrder > 5 + ? here->VSRCcoeffs[5] : 0.0; + + /* compute phase in radians */ + phase = PHASE * M_PI / 180.0; +#endif + VO = here->VSRCcoeffs[0]; + VA = here->VSRCcoeffs[1]; + FREQ = here->VSRCfunctionOrder > 2 + && here->VSRCcoeffs[2] != 0.0 + ? here->VSRCcoeffs[2] : (1/ckt->CKTfinalTime); + TD = here->VSRCfunctionOrder > 3 + ? here->VSRCcoeffs[3] : 0.0; + THETA = here->VSRCfunctionOrder > 4 + ? here->VSRCcoeffs[4] : 0.0; + time -= TD; if (time <= 0) { value = VO; } else { +#ifdef XSPICE + value = VO + VA * sin(FREQ*time * 2.0 * M_PI + phase) * + exp(-time*THETA); +#else value = VO + VA * sin(FREQ * time * 2.0 * M_PI) * exp(-(time*THETA)); +#endif +/* gtri - end - wbk - add PHASE parameter */ } -#undef VO -#undef VA -#undef FREQ -#undef TD -#undef THETA } break; case EXP: { - double td1; - double td2; -#define V1 (*(here->VSRCcoeffs)) -#define V2 (*(here->VSRCcoeffs+1)) -#define TD1 ((here->VSRCfunctionOrder >=3)?(*(here->VSRCcoeffs+2)):\ - ckt->CKTstep) -#define TAU1 (((here->VSRCfunctionOrder >=4) && (*(here->VSRCcoeffs+3)))? \ - (*(here->VSRCcoeffs+3)):ckt->CKTstep) -#define TD2 (((here->VSRCfunctionOrder >=5) && (*(here->VSRCcoeffs+4)))? \ - (*(here->VSRCcoeffs+4)):TD1+ckt->CKTstep) -#define TAU2 (((here->VSRCfunctionOrder >=6) && (*(here->VSRCcoeffs+5)))? \ - (*(here->VSRCcoeffs+5)):ckt->CKTstep) - td1 = TD1; - td2 = TD2; - if(time <= td1) { + double V1, V2, TD1, TD2, TAU1, TAU2; + + V1 = here->VSRCcoeffs[0]; + V2 = here->VSRCcoeffs[1]; + TD1 = here->VSRCfunctionOrder > 2 + && here->VSRCcoeffs[2] != 0.0 + ? here->VSRCcoeffs[2] : ckt->CKTstep; + TAU1 = here->VSRCfunctionOrder > 3 + && here->VSRCcoeffs[3] != 0.0 + ? here->VSRCcoeffs[3] : ckt->CKTstep; + TD2 = here->VSRCfunctionOrder > 4 + && here->VSRCcoeffs[4] != 0.0 + ? here->VSRCcoeffs[4] : TD1 + ckt->CKTstep; + TAU2 = here->VSRCfunctionOrder > 5 + && here->VSRCcoeffs[5] + ? here->VSRCcoeffs[5] : ckt->CKTstep; + + + if(time <= TD1) { value = V1; - } else if (time <= td2) { - value = V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)); + } else if (time <= TD2) { + value = V1 + (V2-V1)*(1-exp(-(time-TD1)/TAU1)); } else { - value = V1 + (V2-V1)*(1-exp(-(time-td1)/TAU1)) + - (V1-V2)*(1-exp(-(time-td2)/TAU2)) ; + value = V1 + (V2-V1)*(1-exp(-(time-TD1)/TAU1)) + + (V1-V2)*(1-exp(-(time-TD2)/TAU2)) ; } -#undef V1 -#undef V2 -#undef TD1 -#undef TAU1 -#undef TD2 -#undef TAU2 } break; case SFFM:{ -#define VO (*(here->VSRCcoeffs)) -#define VA (*(here->VSRCcoeffs+1)) -#define FC (((here->VSRCfunctionOrder >=3) && (*(here->VSRCcoeffs+2)))? \ - (*(here->VSRCcoeffs+2)):(1/ckt->CKTfinalTime)) -#define MDI ((here->VSRCfunctionOrder>=4)?(*(here->VSRCcoeffs+3)):\ - 0.0) -#define FS (((here->VSRCfunctionOrder >=5) && (*(here->VSRCcoeffs+4)))? \ - (*(here->VSRCcoeffs+4)):(1/ckt->CKTfinalTime)) + + double VO, VA, FC, MDI, FS; +/* gtri - begin - wbk - add PHASE parameters */ +#ifdef XSPICE + + double PHASEC, PHASES; + double phasec; + double phases; + + PHASEC = here->VSRCfunctionOrder > 5 + ? here->VSRCcoeffs[5] : 0.0; + PHASES = here->VSRCfunctionOrder > 6 + ? here->VSRCcoeffs[6] : 0.0; + + /* compute phases in radians */ + phasec = PHASEC * M_PI / 180.0; + phases = PHASES * M_PI / 180.0; + +#endif + VO = here->VSRCcoeffs[0]; + VA = here->VSRCcoeffs[1]; + FC = here->VSRCfunctionOrder > 2 + && here->VSRCcoeffs[2] + ? here->VSRCcoeffs[2] : (1/ckt->CKTfinalTime); + MDI = here->VSRCfunctionOrder > 3 + ? here->VSRCcoeffs[3] : 0.0; + FS = here->VSRCfunctionOrder > 4 + && here->VSRCcoeffs[4] + ? here->VSRCcoeffs[4] : (1/ckt->CKTfinalTime); +#ifdef XSPICE + /* compute waveform value */ value = VO + VA * - sin((2 * 3.141592654 * FC * time) + - MDI * sin(2 * 3.141592654 * FS * time)); -#undef VO -#undef VA -#undef FC -#undef MDI -#undef FS + sin((2 * M_PI * FC * time + phasec) + + MDI * sin(2.0 * M_PI * FS * time + phases)); +#else /* XSPICE */ + value = VO + VA * + sin((2.0 * M_PI * FC * time) + + MDI * sin(2 * M_PI * FS * time)); +#endif /* XSPICE */ +/* gtri - end - wbk - add PHASE parameters */ } break; + case AM:{ + + double VA, FC, MF, VO, TD; +/* gtri - begin - wbk - add PHASE parameters */ +#ifdef XSPICE + double PHASEC, PHASES; + double phasec; + double phases; + + PHASEC = here->VSRCfunctionOrder > 5 + ? here->VSRCcoeffs[5] : 0.0; + PHASES = here->VSRCfunctionOrder > 6 + ? here->VSRCcoeffs[6] : 0.0; + + /* compute phases in radians */ + phasec = PHASEC * M_PI / 180.0; + phases = PHASES * M_PI / 180.0; + +#endif + + VA = here->VSRCcoeffs[0]; + VO = here->VSRCcoeffs[1]; + MF = here->VSRCfunctionOrder > 2 + && here->VSRCcoeffs[2] + ? here->VSRCcoeffs[2] : (1/ckt->CKTfinalTime); + FC = here->VSRCfunctionOrder > 3 + ? here->VSRCcoeffs[3] : 0.0; + TD = here->VSRCfunctionOrder > 4 + && here->VSRCcoeffs[4] + ? here->VSRCcoeffs[4] : 0,0; + + time -= TD; + if (time <= 0) { + value = 0; + } else { +#ifdef XSPICE + /* compute waveform value */ + value = VA * (VO + sin(2.0 * M_PI * MF * time + phases )) * + sin(2 * M_PI * FC * time + phases); + +#else /* XSPICE */ + value = VA * (VO + sin(2.0 * M_PI * MF * time)) * + sin(2 * M_PI * FC * time); +#endif + } + +/* gtri - end - wbk - add PHASE parameters */ + } + break; case PWL: { int i; double foo; @@ -198,8 +316,15 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt) } } loadDone: +/* gtri - begin - wbk - modify for supply ramping option */ +#ifdef XSPICE_EXP + value *= ckt->CKTsrcFact; + value *= cm_analog_ramp_factor(); +#else if (ckt->CKTmode & MODETRANOP) value *= ckt->CKTsrcFact; *(ckt->CKTrhs + (here->VSRCbranch)) += value; +#endif +/* gtri - end - wbk - modify to process srcFact, etc. for all sources */ } } return(OK); diff --git a/src/spicelib/devices/vsrc/vsrcpar.c b/src/spicelib/devices/vsrc/vsrcpar.c index e11b48ff6..c59c35426 100644 --- a/src/spicelib/devices/vsrc/vsrcpar.c +++ b/src/spicelib/devices/vsrc/vsrcpar.c @@ -93,6 +93,14 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) here->VSRCfunctionOrder = value->v.numValue; here->VSRCcoeffsGiven = TRUE; break; + case VSRC_AM: + if(value->v.numValue <2) return(E_BADPARM); + here->VSRCfunctionType = AM; + here->VSRCfuncTGiven = TRUE; + here->VSRCcoeffs = value->v.vec.rVec; + here->VSRCfunctionOrder = value->v.numValue; + here->VSRCcoeffsGiven = TRUE; + break; case VSRC_D_F1: here->VSRCdF1given = TRUE; here->VSRCdGiven = TRUE;