The 8th parameter on a voltage or current source now is 'number of pulses'.

Previous usage had been PHASE, introduced by XSPICE, which has
been redundant to DELAY. PHASE is again available when compatibility flag
xs has been set.
This commit is contained in:
Holger Vogt 2022-11-24 14:46:54 +01:00
parent d763b39ec3
commit f7c038466b
4 changed files with 212 additions and 140 deletions

View File

@ -11,6 +11,7 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/suffix.h"
#include "ngspice/missing_math.h"
#include "ngspice/1-f-code.h"
#include "ngspice/compatmode.h"
#ifndef HAVE_LIBFFTW3
extern void fftFree(void);
@ -56,6 +57,7 @@ ISRCaccept(CKTcircuit *ckt, GENmodel *inModel)
double PHASE;
double phase;
double deltat;
double tmax = 1e99;
TD = here->ISRCfunctionOrder > 2
? here->ISRCcoeffs[2] : 0.0;
@ -78,60 +80,79 @@ ISRCaccept(CKTcircuit *ckt, GENmodel *inModel)
time = ckt->CKTtime - TD;
tshift = TD;
/* normalize phase to 0 - 360° */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
time += deltat;
tshift = TD - deltat;
if(time >= PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time/PER);
time -= basetime;
if (newcompat.xs) {
/* normalize phase to 0 - 360° */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
time += deltat;
tshift = TD - deltat;
}
else if (PHASE > 0.0) {
tmax = PHASE * PER;
}
if( time <= 0.0 || time >= TR + PW + TF) {
if(ckt->CKTbreak && SAMETIME(time,0.0)) {
error = CKTsetBreak(ckt,basetime + TR + tshift);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(TR+PW+TF,time) ) {
error = CKTsetBreak(ckt,basetime + PER + tshift);
if(error) return(error);
} else if (ckt->CKTbreak && (time == -tshift) ) {
error = CKTsetBreak(ckt,basetime + tshift);
if(error) return(error);
} else if (ckt->CKTbreak && SAMETIME(PER,time) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PER);
if(error) return(error);
if (!newcompat.xs && time > tmax) {
/* Do nothing */
}
else {
if (time >= PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time / PER);
time -= basetime;
}
} else if ( time >= TR && time <= TR + PW) {
if(ckt->CKTbreak && SAMETIME(time,TR) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(TR+PW,time) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW + TF);
if(error) return(error);
if (time <= 0.0 || time >= TR + PW + TF) {
if (ckt->CKTbreak && SAMETIME(time, 0.0)) {
error = CKTsetBreak(ckt, basetime + TR + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(TR + PW + TF, time)) {
error = CKTsetBreak(ckt, basetime + PER + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && (time == -tshift)) {
error = CKTsetBreak(ckt, basetime + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(PER, time)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PER);
if (error) return(error);
}
}
} else if (time > 0 && time < TR) {
if(ckt->CKTbreak && SAMETIME(time,0) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(time,TR)) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW);
if(error) return(error);
else if (time >= TR && time <= TR + PW) {
if (ckt->CKTbreak && SAMETIME(time, TR)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(TR + PW, time)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW + TF);
if (error) return(error);
}
}
} else { /* time > TR + PW && < TR + PW + TF */
if(ckt->CKTbreak && SAMETIME(time,TR+PW) ) {
error = CKTsetBreak(ckt,basetime + tshift+TR + PW +TF);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(time,TR+PW+TF) ) {
error = CKTsetBreak(ckt,basetime + tshift + PER);
if(error) return(error);
else if (time > 0 && time < TR) {
if (ckt->CKTbreak && SAMETIME(time, 0)) {
error = CKTsetBreak(ckt, basetime + tshift + TR);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(time, TR)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW);
if (error) return(error);
}
}
else { /* time > TR + PW && < TR + PW + TF */
if (ckt->CKTbreak && SAMETIME(time, TR + PW)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW + TF);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(time, TR + PW + TF)) {
error = CKTsetBreak(ckt, basetime + tshift + PER);
if (error) return(error);
}
}
}
}

View File

@ -11,6 +11,7 @@ Modified: 2000 Alansfixes
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/1-f-code.h"
#include "ngspice/compatmode.h"
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify for supply ramping option */
@ -75,6 +76,7 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt)
double PHASE;
double phase;
double deltat;
double tmax = 1e99;
V1 = here->ISRCcoeffs[0];
V2 = here->ISRCcoeffs[1];
@ -99,29 +101,42 @@ ISRCload(GENmodel *inModel, CKTcircuit *ckt)
PHASE = here->ISRCfunctionOrder > 7
? here->ISRCcoeffs[7] : 0.0;
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
/* shift time by pase (neg. for pos. phase value) */
time += deltat;
if(time > PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time/PER);
time -= basetime;
if (newcompat.xs) { /* 7th parameter is PHASE */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
/* shift time by pase (neg. for pos. phase value) */
time += deltat;
}
if (time <= 0 || time >= TR + PW + TF) {
else if (PHASE > 0.0) { /* 7th parameter is number of pulses */
tmax = PHASE * PER;
}
if (!newcompat.xs && time > tmax) {
value = V1;
} else if (time >= TR && time <= TR + PW) {
value = V2;
} else if (time > 0 && time < TR) {
value = V1 + (V2 - V1) * (time) / TR;
} else { /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF;
}
else {
if (time > PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time / PER);
time -= basetime;
}
if (time <= 0 || time >= TR + PW + TF) {
value = V1;
}
else if (time >= TR && time <= TR + PW) {
value = V2;
}
else if (time > 0 && time < TR) {
value = V1 + (V2 - V1) * (time) / TR;
}
else { /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF;
}
}
}
break;

View File

@ -11,6 +11,7 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/suffix.h"
#include "ngspice/missing_math.h"
#include "ngspice/1-f-code.h"
#include "ngspice/compatmode.h"
#ifndef HAVE_LIBFFTW3
extern void fftFree(void);
@ -53,6 +54,7 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
double tshift;
double time = 0.;
double basetime = 0;
double tmax = 1e99;
double PHASE;
double phase;
@ -79,60 +81,79 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
time = ckt->CKTtime - TD;
tshift = TD;
/* normalize phase to 0 - 360° */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
time += deltat;
tshift = TD - deltat;
if(time >= PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time/PER);
time -= basetime;
if (newcompat.xs) {
/* normalize phase to 0 - 360° */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
time += deltat;
tshift = TD - deltat;
}
else if (PHASE > 0.0) {
tmax = PHASE * PER;
}
if( time <= 0.0 || time >= TR + PW + TF) {
if(ckt->CKTbreak && SAMETIME(time,0.0)) {
error = CKTsetBreak(ckt,basetime + TR + tshift);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(TR+PW+TF,time) ) {
error = CKTsetBreak(ckt,basetime + PER + tshift);
if(error) return(error);
} else if (ckt->CKTbreak && (time == -tshift) ) {
error = CKTsetBreak(ckt,basetime + tshift);
if(error) return(error);
} else if (ckt->CKTbreak && SAMETIME(PER,time) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PER);
if(error) return(error);
if (!newcompat.xs && time > tmax) {
/* Do nothing */
}
else {
if (time >= PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time / PER);
time -= basetime;
}
} else if ( time >= TR && time <= TR + PW) {
if(ckt->CKTbreak && SAMETIME(time,TR) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(TR+PW,time) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW + TF);
if(error) return(error);
if (time <= 0.0 || time >= TR + PW + TF) {
if (ckt->CKTbreak && SAMETIME(time, 0.0)) {
error = CKTsetBreak(ckt, basetime + TR + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(TR + PW + TF, time)) {
error = CKTsetBreak(ckt, basetime + PER + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && (time == -tshift)) {
error = CKTsetBreak(ckt, basetime + tshift);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(PER, time)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PER);
if (error) return(error);
}
}
} else if (time > 0 && time < TR) {
if(ckt->CKTbreak && SAMETIME(time,0) ) {
error = CKTsetBreak(ckt,basetime + tshift + TR);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(time,TR)) {
error = CKTsetBreak(ckt,basetime + tshift + TR + PW);
if(error) return(error);
else if (time >= TR && time <= TR + PW) {
if (ckt->CKTbreak && SAMETIME(time, TR)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(TR + PW, time)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW + TF);
if (error) return(error);
}
}
} else { /* time > TR + PW && < TR + PW + TF */
if(ckt->CKTbreak && SAMETIME(time,TR+PW) ) {
error = CKTsetBreak(ckt,basetime + tshift+TR + PW +TF);
if(error) return(error);
} else if(ckt->CKTbreak && SAMETIME(time,TR+PW+TF) ) {
error = CKTsetBreak(ckt,basetime + tshift + PER);
if(error) return(error);
else if (time > 0 && time < TR) {
if (ckt->CKTbreak && SAMETIME(time, 0)) {
error = CKTsetBreak(ckt, basetime + tshift + TR);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(time, TR)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW);
if (error) return(error);
}
}
else { /* time > TR + PW && < TR + PW + TF */
if (ckt->CKTbreak && SAMETIME(time, TR + PW)) {
error = CKTsetBreak(ckt, basetime + tshift + TR + PW + TF);
if (error) return(error);
}
else if (ckt->CKTbreak && SAMETIME(time, TR + PW + TF)) {
error = CKTsetBreak(ckt, basetime + tshift + PER);
if (error) return(error);
}
}
}
}

View File

@ -11,6 +11,7 @@ Modified: 2000 AlansFixes
#include "ngspice/sperror.h"
#include "ngspice/suffix.h"
#include "ngspice/1-f-code.h"
#include "ngspice/compatmode.h"
#ifdef XSPICE_EXP
/* gtri - begin - wbk - modify for supply ramping option */
@ -98,6 +99,7 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
double PHASE;
double phase;
double deltat;
double tmax = 1e99;
V1 = here->VSRCcoeffs[0];
V2 = here->VSRCcoeffs[1];
@ -122,29 +124,42 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
PHASE = here->VSRCfunctionOrder > 7
? here->VSRCcoeffs[7] : 0.0;
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
/* shift time by pase (neg. for pos. phase value) */
time += deltat;
if(time > PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time/PER);
time -= basetime;
if (newcompat.xs) { /* 7th parameter is PHASE */
/* normalize phase to cycles */
phase = PHASE / 360.0;
phase = fmod(phase, 1.0);
deltat = phase * PER;
while (deltat > 0)
deltat -= PER;
/* shift time by pase (neg. for pos. phase value) */
time += deltat;
}
if (time <= 0 || time >= TR + PW + TF) {
else if (PHASE > 0.0) { /* 7th parameter is number of pulses */
tmax = PHASE * PER;
}
if (!newcompat.xs && time > tmax) {
value = V1;
} else if (time >= TR && time <= TR + PW) {
value = V2;
} else if (time > 0 && time < TR) {
value = V1 + (V2 - V1) * (time) / TR;
} else { /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF;
}
else {
if (time > PER) {
/* repeating signal - figure out where we are */
/* in period */
basetime = PER * floor(time / PER);
time -= basetime;
}
if (time <= 0 || time >= TR + PW + TF) {
value = V1;
}
else if (time >= TR && time <= TR + PW) {
value = V2;
}
else if (time > 0 && time < TR) {
value = V1 + (V2 - V1) * (time) / TR;
}
else { /* time > TR + PW && < TR + PW + TF */
value = V2 + (V1 - V2) * (time - (TR + PW)) / TF;
}
}
}
break;