add loop as interactive command

This commit is contained in:
Florian Ballenegger 2020-09-12 14:45:23 +02:00
parent eac44e4b54
commit 2aa2316fe0
5 changed files with 75 additions and 4 deletions

31
examples/loop/vreg.cir Normal file
View File

@ -0,0 +1,31 @@
* simple voltage regulator example
Mout out pgate vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=100
R1 out fb 33.3K
R2 fb vss 66.7K
Mp1 mir mir vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=2
Mp2 pgate mir vdd vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=2
M1 pgate set tail vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=10
M2 mir fbinj tail vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=10
Mb1 tail bn vss vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
Mb0 bn bn vss vss n1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p m=4
Ib vss bn 1u
Vloop fb fbinj DC 0
Vset set vss DC 1.2 AC 1
Vvdd vdd vss DC 3.3
Vvss vss 0 DC 0
Iload out vss DC 10e-3 PWL 1n 10e-3 2n 9e-3
.model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.6
.model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.7
.loop M2/Gate DEC 10 1 10e9 insrc="Vset" outpos="out" outneg="vss" dir=-1 refnode="set"
.ac dec 10 1 1e9
.tran 1n 10u

View File

@ -300,6 +300,14 @@ struct comm spcp_coms[] = {
"[.pss line args] : Do a periodic state analysis." } ,
/* SP */
#endif
#ifdef WITH_LOOPANA
/* F.B.: Loop stability analysis */
{ "loop", com_loop, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
"[.loop line args] : Do a loop stability analysis." } ,
#endif
{ "ac", com_ac, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
@ -759,6 +767,14 @@ struct comm nutcp_coms[] = {
NULL,
"[.pss line args] : Do a periodic steady state analysis." } ,
/* SP */
#endif
#ifdef WITH_LOOPANA
/* F.B.: Loop stability analysis */
{ "loop", NULL, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
"[.loop line args] : Do a loop stability analysis." } ,
/* SP */
#endif
{ "ac", NULL, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,

View File

@ -186,6 +186,14 @@ com_pss(wordlist *wl)
/* SP */
#endif
#ifdef WITH_LOOPANA
/* F.B. Loop stability analysis */
void
com_loop(wordlist *wl)
{
dosim("loop", wl);
}
#endif
static int dosim(
char *what, /* in: command

View File

@ -16,6 +16,9 @@ void com_tran(wordlist *wl);
/* SP: Stady State Analysis */
void com_pss(wordlist *wl);
/* SP */
#ifdef WITH_LOOPANA
void com_loop(wordlist *wl);
#endif
void com_sens(wordlist *wl);
void com_disto(wordlist *wl);
void com_noise(wordlist *wl);

View File

@ -151,13 +151,25 @@ LOOPpreset(CKTcircuit *ckt, JOB *anal)
return E_NOTFOUND;
}
/* now break the loop at terminal termidx */
{
char probename[32];
sprintf(probename, "probe_%d", termidx);
error = SPfrontEnd->IFnewUid (ckt, &eltUid, inst->GENname,
probename, UID_INSTANCE, NULL);
}
if(error) return(error);
probesrc = CKTfndDev(ckt, eltUid);
if (probesrc && probesrc->GENmodPtr->GENmodType >= 0)
{
/* probe already inserted, nothing to do except to free eltUid ? */
printf("Loop analysis: The probe was already in place\n");
}
else
{
printf("Loop analysis: Break the loop at device '%s' terminal '%s'\n", inst->GENname, dev->termNames[termidx]);
node = CKTnum2nod(ckt, GENnode(inst)[termidx]);
error = CKTmkVolt(ckt, &nodeinj, inst->GENname, "loopinj");
if(error) return(error);
error = SPfrontEnd->IFnewUid (ckt, &eltUid, inst->GENname,
"probe", UID_INSTANCE, NULL);
if(error) return(error);
error = SPfrontEnd->IFnewUid (ckt, &modUid, inst->GENname,
"probemod", UID_MODEL, NULL);
if(error) return(error);
@ -176,7 +188,8 @@ LOOPpreset(CKTcircuit *ckt, JOB *anal)
error = CKTbindNode(ckt,probesrc,job->LOOPdirection==2 ? 2 : 2 ,node);
if(error) return(error);
error = CKTbindNode(ckt,inst,termidx+1,nodeinj); /* bindNode counts from 1 ! */
ptemp.rValue = 0;
if(error) return(error);
}
job->LOOPprobeSrc = probesrc->GENname;
job->LOOPportnameGiven = 0; /* don't mess if LOOPpreset is called a second time */
job->LOOPportnumGiven = 0; /* idem */