VS
This commit is contained in:
Meisam Bahadori 2026-07-26 11:54:37 +02:00 committed by Holger Vogt
parent 14815e8381
commit 3845db2c1f
6 changed files with 88 additions and 0 deletions

View File

@ -53,6 +53,8 @@ libfte_la_SOURCES = \
com_let.h \
com_optimize.c \
com_optimize.h \
com_checkpoint.c \
com_checkpoint.h \
com_option.c \
com_option.h \
com_plot.c \

View File

@ -7,6 +7,8 @@ void com_alter(wordlist *wl);
void com_altermod(wordlist *wl);
void com_alterparam(wordlist *wl);
void com_optimize(wordlist *wl); /* Enhancement-130 */
void com_savestate(wordlist *wl); /* Enhancement-131 */
void com_loadstate(wordlist *wl); /* Enhancement-131 */
void com_meas(wordlist *wl);
void com_sysinfo(wordlist *wl);
void com_check_ifparm(wordlist *wl);

View File

@ -428,6 +428,14 @@ struct comm spcp_coms[] = {
{ 040, 040, 040, 040 }, E_DEFHMASK, 1, LOTS,
NULL,
"-param name init lo hi ... -analysis <cmd> -minimize <expr> [-maxiter N] [-tol T] [-verbose] : Nelder-Mead parameter optimizer." },
{ "savestate", com_savestate, FALSE, TRUE, /* Enhancement-131 */
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, 1,
NULL,
"file : Save the current transient state to a checkpoint file." },
{ "loadstate", com_loadstate, FALSE, TRUE, /* Enhancement-131 */
{ 1, 040000, 040000, 040000 }, E_DEFHMASK, 1, 1,
NULL,
"file : Restore a transient checkpoint and continue the .tran run." },
{ "resume", com_resume, TRUE, FALSE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, 0,
NULL,

View File

@ -270,6 +270,8 @@ struct CKTcircuit {
unsigned int CKTkeepOpInfo:1; /* flag for small signal analyses */
unsigned int CKTcopyNodesets:1; /* NodesetFIX */
unsigned int CKTnodeDamping:1; /* flag for node damping fix */
unsigned int CKTcheckpoint:1; /* Enhancement-131: DCtran should continue from a restored
checkpoint (keep loaded state, build a fresh output plot) */
double CKTabsDv; /* abs limit for iter-iter voltage change */
double CKTrelDv; /* rel limit for iter-iter voltage change */
int CKTtroubleNode; /* Non-convergent node number */

View File

@ -113,6 +113,78 @@ DCtran(CKTcircuit *ckt,
#if defined SHARED_MODULE
int redostep;
#endif
if(ckt->CKTcheckpoint) {
/* Enhancement-131: continue a transient run from a checkpoint that was
restored from disk (see com_loadstate() in com_checkpoint.c). The
restored circuit already carries the saved CKTtime, CKTdelta,
CKTstates[], CKTrhsOld and integration order, so -- unlike a fresh
run -- we must NOT reset them or redo the DC operating point. Unlike
the in-memory `resume` path below we also cannot 666-relink an
existing output plot (there is none across a reload), so we open a
FRESH plot exactly as the restart branch does, then jump straight
into the time-stepping loop. */
ckt->CKTcheckpoint = 0; /* one-shot */
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODETRAN | MODEINITPRED;
INIT_STATS();
firsttime = 0;
if(ckt->CKTminBreak == 0)
ckt->CKTminBreak = ckt->CKTmaxStep * 5e-5;
#ifdef XSPICE
/* The in-memory `resume` inherits these from the original run; a
cross-session restore starts a fresh process, so initialise the
XSPICE temporary-breakpoint markers (otherwise the stepping loop
forces CKTdelta to breakpoint.current - CKTtime = -CKTtime). */
g_mif_info.circuit.anal_type = MIF_DC;
g_mif_info.breakpoint.current = 1.0e30;
g_mif_info.breakpoint.last = 1.0e30;
#endif
/* Build a fresh output plot for the continuation. */
error = CKTnames(ckt, &numNames, &nameList);
if(error) return(error);
SPfrontEnd->IFnewUid (ckt, &timeUid, NULL, "time", UID_OTHER, NULL);
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,
timeUid, IF_REAL,
numNames, nameList, IF_REAL,
&(job->TRANplot));
tfree(nameList);
if(error) return(error);
if (ckt->CKTsoaCheck)
error = CKTsoaInit();
/* Fix up the breakpoint list for the continuation. Drop any restored
breakpoints at or before the resume time (they are in the past and
would yield a negative time step); keep the genuine future ones (e.g.
pending source edges). Then guarantee the (possibly extended) final
time is present and that at least two entries exist -- the stepping
loop reads CKTbreaks[1]. Sources re-schedule their own future edges
as the run proceeds. */
if(ckt->CKTbreaks != NULL && ckt->CKTbreakSize > 0) {
int nb, w = 0;
for(nb = 0; nb < ckt->CKTbreakSize; nb++)
if(ckt->CKTbreaks[nb] > ckt->CKTtime + ckt->CKTdelmin)
ckt->CKTbreaks[w++] = ckt->CKTbreaks[nb];
ckt->CKTbreakSize = w;
}
if(ckt->CKTbreaks == NULL || ckt->CKTbreakSize < 1) {
if(ckt->CKTbreaks) FREE(ckt->CKTbreaks);
ckt->CKTbreaks = TMALLOC(double, 2);
if(ckt->CKTbreaks == NULL) return(E_NOMEM);
ckt->CKTbreaks[0] = ckt->CKTfinalTime;
ckt->CKTbreaks[1] = ckt->CKTfinalTime + ckt->CKTmaxStep;
ckt->CKTbreakSize = 2;
} else {
if(ckt->CKTfinalTime > ckt->CKTtime)
CKTsetBreak(ckt, ckt->CKTfinalTime);
if(ckt->CKTbreakSize < 2)
CKTsetBreak(ckt, ckt->CKTfinalTime + ckt->CKTmaxStep);
}
goto resume;
}
if(restart || ckt->CKTtime == 0) {
/* dctran() is entered here upon starting transient simulation
with time 0 and restart 1.

View File

@ -874,6 +874,7 @@
<ClInclude Include="..\src\frontend\com_asciiplot.h" />
<ClInclude Include="..\src\frontend\com_cdump.h" />
<ClInclude Include="..\src\frontend\com_chdir.h" />
<ClInclude Include="..\src\frontend\com_checkpoint.h" />
<ClInclude Include="..\src\frontend\com_commands.h" />
<ClInclude Include="..\src\frontend\com_compose.h" />
<ClInclude Include="..\src\frontend\com_display.h" />
@ -1490,6 +1491,7 @@
<ClCompile Include="..\src\frontend\com_asciiplot.c" />
<ClCompile Include="..\src\frontend\com_cdump.c" />
<ClCompile Include="..\src\frontend\com_chdir.c" />
<ClCompile Include="..\src\frontend\com_checkpoint.c" />
<ClCompile Include="..\src\frontend\com_compose.c" />
<ClCompile Include="..\src\frontend\com_display.c" />
<ClCompile Include="..\src\frontend\com_dl.c" />