diff --git a/examples/p-to-n-examples/relax_osc_st.cir b/examples/p-to-n-examples/relax_osc_st.cir index 952fc0d36..54ed2e1a2 100644 --- a/examples/p-to-n-examples/relax_osc_st.cir +++ b/examples/p-to-n-examples/relax_osc_st.cir @@ -16,13 +16,14 @@ R4 vs1 vp1 10k C1 vm1 0 1n -.tran 100n 500u uic +.tran 100n 500u startup ; uic .option rshunt=1e12 .control save vs1 vm1 vp1 run +rusage time plot vs1 vm1 vp1 linearize vs1 fft vs1 diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index a354ff669..cc495d340 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -189,6 +189,7 @@ struct CKTcircuit { /* old 'nosolv' paramater */ #define MODEUIC 0x10000l +#define MODESTARTUP 0x20000l int CKTbypass; /* bypass option, how does it work ? */ int CKTdcMaxIter; /* iteration limit for dc op. (itl1) */ diff --git a/src/include/ngspice/trandefs.h b/src/include/ngspice/trandefs.h index bf6bab0ee..07636b238 100644 --- a/src/include/ngspice/trandefs.h +++ b/src/include/ngspice/trandefs.h @@ -33,6 +33,7 @@ enum { TRAN_TSTEP, TRAN_TMAX, TRAN_UIC, + TRAN_STARTUP, }; #endif diff --git a/src/spicelib/analysis/dctran.c b/src/spicelib/analysis/dctran.c index 5515b149d..5b649170d 100644 --- a/src/spicelib/analysis/dctran.c +++ b/src/spicelib/analysis/dctran.c @@ -181,7 +181,7 @@ DCtran(CKTcircuit *ckt, ckt->CKTdelta = 0; ckt->CKTbreak = 1; firsttime = 1; - save_mode = (ckt->CKTmode&MODEUIC) | MODETRANOP | MODEINITJCT; + save_mode = (ckt->CKTmode&MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRANOP | MODEINITJCT; save_order = ckt->CKTorder; /* Add breakpoints here which have been requested by the user setting the @@ -210,8 +210,8 @@ DCtran(CKTcircuit *ckt, if(ckt->evt->counts.num_insts != 0) { /* use new DCOP algorithm */ converged = EVTop(ckt, - (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, - (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITFLOAT, + (ckt->CKTmode & MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRANOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRANOP | MODEINITFLOAT, ckt->CKTdcMaxIter, MIF_TRUE); EVTdump(ckt, IPC_ANAL_DCOP, 0.0); @@ -222,8 +222,8 @@ DCtran(CKTcircuit *ckt, } else #endif converged = CKTop(ckt, - (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITJCT, - (ckt->CKTmode & MODEUIC) | MODETRANOP | MODEINITFLOAT, + (ckt->CKTmode & MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRANOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRANOP | MODEINITFLOAT, ckt->CKTdcMaxIter); if(converged != 0) { @@ -337,7 +337,7 @@ DCtran(CKTcircuit *ckt, } #endif - ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITTRAN; + ckt->CKTmode = (ckt->CKTmode&MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRAN | MODEINITTRAN; /* modeinittran set here */ ckt->CKTag[0]=ckt->CKTag[1]=0; memcpy(ckt->CKTstate1, ckt->CKTstate0, @@ -357,7 +357,7 @@ DCtran(CKTcircuit *ckt, #endif } else { /* saj As traninit resets CKTmode */ - ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITPRED; + ckt->CKTmode = (ckt->CKTmode&MODEUIC) | (ckt->CKTmode&MODESTARTUP) | MODETRAN | MODEINITPRED; /* saj */ INIT_STATS(); if(ckt->CKTminBreak==0) ckt->CKTminBreak=ckt->CKTmaxStep*5e-5; @@ -782,7 +782,7 @@ resume: #endif ckt->CKTstat->STATtimePts ++; - ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITPRED; + ckt->CKTmode = (ckt->CKTmode&MODEUIC)| (ckt->CKTmode&MODESTARTUP)|MODETRAN | MODEINITPRED; if(firsttime) { memcpy(ckt->CKTstate2, ckt->CKTstate1, (size_t) ckt->CKTnumStates * sizeof(double)); @@ -809,7 +809,7 @@ resume: fflush(stdout); #endif if(firsttime) { - ckt->CKTmode = (ckt->CKTmode&MODEUIC) | MODETRAN | MODEINITTRAN; + ckt->CKTmode = (ckt->CKTmode&MODEUIC)| (ckt->CKTmode&MODESTARTUP) | MODETRAN | MODEINITTRAN; } ckt->CKTorder = 1; @@ -824,7 +824,7 @@ resume: g_mif_info.breakpoint.last = ckt->CKTtime + ckt->CKTdelta; if(firsttime) { - ckt->CKTmode = (ckt->CKTmode&MODEUIC)|MODETRAN | MODEINITTRAN; + ckt->CKTmode = (ckt->CKTmode&MODEUIC)| (ckt->CKTmode&MODESTARTUP)|MODETRAN | MODEINITTRAN; } ckt->CKTorder = 1; diff --git a/src/spicelib/analysis/transetp.c b/src/spicelib/analysis/transetp.c index 7fb718fbf..8cbf180fb 100644 --- a/src/spicelib/analysis/transetp.c +++ b/src/spicelib/analysis/transetp.c @@ -53,6 +53,11 @@ TRANsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) job->TRANmode |= MODEUIC; } break; + case TRAN_STARTUP: + if(value->iValue) { + job->TRANmode |= MODESTARTUP; + } + break; default: return(E_BADPARM); @@ -67,6 +72,7 @@ static IFparm TRANparms[] = { { "tstep", TRAN_TSTEP, IF_SET|IF_REAL, "time step" }, { "tmax", TRAN_TMAX, IF_SET|IF_REAL, "maximum time step" }, { "uic", TRAN_UIC, IF_SET|IF_FLAG, "use initial conditions" }, + { "startup", TRAN_STARTUP, IF_SET|IF_FLAG, "turn on independent sources after 20 us" }, }; SPICEanalysis TRANinfo = { diff --git a/src/spicelib/devices/isrc/isrcload.c b/src/spicelib/devices/isrc/isrcload.c index 71a0b72f8..37b138564 100644 --- a/src/spicelib/devices/isrc/isrcload.c +++ b/src/spicelib/devices/isrc/isrcload.c @@ -391,6 +391,9 @@ INoi1 1 0 DC 0 TRNOISE(0n 0.5n 1 10n) : generate 1/f noise #endif } // switch + if ((ckt->CKTmode&MODESTARTUP) && ckt->CKTtime < 20e-6) { + value *= ckt->CKTtime/20e-6; + } } // else (line 48) loadDone: diff --git a/src/spicelib/devices/vsrc/vsrcload.c b/src/spicelib/devices/vsrc/vsrcload.c index f71bc5c43..1c77978c2 100644 --- a/src/spicelib/devices/vsrc/vsrcload.c +++ b/src/spicelib/devices/vsrc/vsrcload.c @@ -405,6 +405,9 @@ VNoi3 3 0 DC 0 TRNOISE(0 0 0 0 15m 22u 50u) : generate RTS noise #endif } // switch + if ((ckt->CKTmode&MODESTARTUP) && ckt->CKTtime < 20e-6) { + value *= ckt->CKTtime/20e-6; + } } // else (line 48) loadDone: diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c index 18be7ca2e..65c070c46 100644 --- a/src/spicelib/parser/inp2dot.c +++ b/src/spicelib/parser/inp2dot.c @@ -390,6 +390,9 @@ dot_tran(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, if (strcmp(word, "uic") == 0) { ptemp.iValue = 1; GCA(INPapName, (ckt, which, foo, "uic", &ptemp)); + } else if (strcmp(word, "startup") == 0) { + ptemp.iValue = 1; + GCA(INPapName, (ckt, which, foo, "startup", &ptemp)); } else { LITERR(" Error: unknown parameter on .tran - ignored\n"); }