Merge branch 'pre-master-42' into bt_dev
This commit is contained in:
commit
be7f14e43b
28
NEWS
28
NEWS
|
|
@ -1,3 +1,31 @@
|
|||
Ngspice-42, Dec 24th, 2023
|
||||
============
|
||||
- New features:
|
||||
+ New optional matrix solver KLU (select by 'option klu')
|
||||
+ improve error messages (more verbose, user centric)
|
||||
+ Add variable wr_onspace to allow printing the vetor name with
|
||||
one space delimiter
|
||||
+ Re-write of the code model PWM generator
|
||||
+ Linked list modtab has been enhanced by a hash table
|
||||
modtabhash
|
||||
+ Add a code model function cm_cexit(const int exitcode).
|
||||
+ PSP103 model pspnqs103va is now standard
|
||||
+ Add Isotel d_process xspice digital model (enable C models).
|
||||
+ OSDI interface allows small signal noise simulation in Verilog-A
|
||||
compact models compiled by current OpenVAF.
|
||||
+ Add series resistance 1e-4 Ohms to diode model, if RS is not given
|
||||
+ Generate seed numbers from a microseconds clock, not a seconds clock
|
||||
+ Add functions ngSpice_LockRealloc and ngSpice_UnlockRealloc
|
||||
+ Add new code model function cm_irreversible().
|
||||
+ Add XSPICE code model d_cosim, a generic adaptor for digital cosimulation.
|
||||
+ New interpreter commands strstr, strslice, fopen, fread and fclose.
|
||||
+ Recognise *ng_script_with_params"
|
||||
+ Add a predifined variable 'skywaterpdk' to speed up circuit
|
||||
loading and parsing.
|
||||
+ Add scripts for running the paranoia tests in parallel on Linux with valgrind.
|
||||
|
||||
|
||||
|
||||
Ngspice-41, Aug 13th, 2023
|
||||
============
|
||||
- New features:
|
||||
|
|
|
|||
|
|
@ -91,5 +91,7 @@ meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG VAL=0.5 RISE=2
|
|||
meas tran tdiff TRIG v(1) VAL=0.5 RISE=1 TARG v(1) RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL= RISE=1 TARG v(1) VAL=0.5 RISE=2
|
||||
meas tran tdiff TRIG v(1) VAL=0.5 RISE= TARG v(1) VAL=0.5 RISE=2
|
||||
meas sp tmax MAX v(2) from=2m to=3m
|
||||
meas dc ymax MAX v(2) from=2m to=3m
|
||||
.endc
|
||||
.end
|
||||
|
|
|
|||
|
|
@ -432,7 +432,10 @@ com_measure_when(
|
|||
value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
|
||||
else
|
||||
value = d->v_realdata[i];
|
||||
scaleValue = dScale->v_compdata[i].cx_real;
|
||||
if (dScale->v_compdata)
|
||||
scaleValue = dScale->v_compdata[i].cx_real;
|
||||
else
|
||||
scaleValue = dScale->v_realdata[i];
|
||||
} else if (sp_check) {
|
||||
if (d->v_compdata)
|
||||
value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
|
||||
|
|
@ -688,7 +691,10 @@ measure_at(
|
|||
value = d->v_realdata[i];
|
||||
// fprintf(cp_err, "Warning: 'meas ac' input vector is real!\n");
|
||||
}
|
||||
svalue = dScale->v_compdata[i].cx_real;
|
||||
if (dScale->v_compdata)
|
||||
svalue = dScale->v_compdata[i].cx_real;
|
||||
else
|
||||
svalue = dScale->v_realdata[i]; //prevent crash in case if buggy input
|
||||
} else if (sp_check) {
|
||||
if (d->v_compdata)
|
||||
value = get_value(meas, d, i); //d->v_compdata[i].cx_real;
|
||||
|
|
@ -768,22 +774,40 @@ measure_minMaxAvg(
|
|||
|
||||
if (ac_check || sp_check) {
|
||||
dScale = vec_get("frequency");
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as frequency.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else if (tran_check) {
|
||||
dScale = vec_get("time");
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as time.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else if (dc_check) {
|
||||
dScale = vec_get("v-sweep");
|
||||
if (!dScale) {
|
||||
dScale = vec_get("i-sweep");
|
||||
if (!dScale) {
|
||||
dScale = vec_get("temp-sweep");
|
||||
if (!dScale)
|
||||
dScale = vec_get("res-sweep");
|
||||
}
|
||||
}
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as v-sweep, i-sweep, temp-sweep, or res-sweep.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else { /* error */
|
||||
fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis);
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (dScale == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as time, frequency or v-sweep.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (dScale->v_realdata == NULL && dScale->v_compdata == NULL) {
|
||||
fprintf(cp_err, "Error: scale vector time, frequency or v-sweep has no data.\n");
|
||||
fprintf(cp_err, "Error: scale vector time, frequency or ?-sweep has no data.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
@ -949,22 +973,40 @@ measure_rms_integral(
|
|||
|
||||
if (ac_check || sp_check) {
|
||||
xScale = vec_get("frequency");
|
||||
if (xScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as frequency.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else if (tran_check) {
|
||||
xScale = vec_get("time");
|
||||
if (xScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as time.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else if (dc_check) {
|
||||
xScale = vec_get("v-sweep");
|
||||
if (!xScale) {
|
||||
xScale = vec_get("i-sweep");
|
||||
if (!xScale) {
|
||||
xScale = vec_get("temp-sweep");
|
||||
if (!xScale)
|
||||
xScale = vec_get("res-sweep");
|
||||
}
|
||||
}
|
||||
if (xScale == NULL) {
|
||||
fprintf(cp_err, "Error: meas %s ...\n", meas->m_analysis);
|
||||
fprintf(cp_err, " no such scale vector as v-sweep, i-sweep, temp-sweep, or res-sweep.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
} else { /* error */
|
||||
fprintf(cp_err, "Error: no such analysis type as %s.\n", meas->m_analysis);
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (xScale == NULL) {
|
||||
fprintf(cp_err, "Error: no such vector as time, frequency or v-sweep.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
if (xScale->v_realdata == NULL && xScale->v_compdata == NULL) {
|
||||
fprintf(cp_err, "Error: scale vector time, frequency or v-sweep has no data.\n");
|
||||
fprintf(cp_err, "Error: scale vector time, frequency or ?-sweep has no data.\n");
|
||||
return MEASUREMENT_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ ft_interpolate(double *data, double *ndata, double *oscale, int olen,
|
|||
/* Now plot the rest, piece by piece. l is the
|
||||
* last element under consideration.
|
||||
*/
|
||||
for (++l; l < olen; l++) {
|
||||
for (++l; l < olen && lastone < nlen - 1; l++) {
|
||||
double out;
|
||||
|
||||
/* Shift the old stuff by one and get another value. */
|
||||
|
|
|
|||
|
|
@ -121,7 +121,10 @@ double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0;
|
|||
double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb;
|
||||
|
||||
double m = 1.0;
|
||||
|
||||
#ifndef NEWCONV
|
||||
double tol;
|
||||
#endif
|
||||
|
||||
struct bsim3v1SizeDependParam *pParam;
|
||||
int ByPass, Check, ChargeComputationNeeded = 0, error;
|
||||
|
||||
|
|
|
|||
|
|
@ -487,6 +487,9 @@ int B4SOILoadOMP(B4SOIinstance *here, CKTcircuit *ckt) {
|
|||
|
||||
double eggbcp2, eggdep, agb1, bgb1, agb2, bgb2, agbc2n, agbc2p, bgbc2n, bgbc2p, Vtm00; /* v4.3.1 bugfix for mtrlMod=1 -Tanvir */
|
||||
double m;
|
||||
#ifndef NEWCONV
|
||||
double tol;
|
||||
#endif
|
||||
|
||||
#ifndef USE_OMP
|
||||
for (; model != NULL; model = B4SOInextModel(model))
|
||||
|
|
|
|||
|
|
@ -853,7 +853,6 @@ tm0 = gtodsecld() ;
|
|||
isConv = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* NEWCONV */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel)
|
|||
model->RESefGiven = TRUE;
|
||||
break;
|
||||
case RES_MOD_R:
|
||||
if ( value->rValue > 1e-03 ) {
|
||||
if ( value->rValue > 0 ) {
|
||||
model->RESres = value->rValue;
|
||||
model->RESresGiven = TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ RESupdate_conduct(RESinstance *here, bool spill_warnings)
|
|||
} else {
|
||||
if (spill_warnings)
|
||||
SPfrontEnd->IFerrorf (ERR_WARNING,
|
||||
"%s: resistance to low, set to 1 mOhm", here->RESname);
|
||||
"%s: resistance too low or not given, set to 1 mOhm", here->RESname);
|
||||
here->RESresist = 1e-03;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ VSRCtemp(GENmodel *inModel, CKTcircuit *ckt)
|
|||
if (!here->VSRCportZ0Given)
|
||||
here->VSRCportZ0 = 50.0;
|
||||
|
||||
here->VSRCisPort = here->VSRCportZ0 > 0.0;
|
||||
here->VSRCisPort = here->VSRCportZ0 > 0.0 && here->VSRCportNum > 0;
|
||||
}
|
||||
else
|
||||
here->VSRCisPort = FALSE;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
int error1; /* secondary error code temporary */
|
||||
INPmodel *thismodel; /* pointer to model structure describing our model */
|
||||
GENmodel *mdfast = NULL; /* pointer to the actual model */
|
||||
GENinstance *fast; /* pointer to the actual instance */
|
||||
GENinstance *fast = NULL;/* pointer to the actual instance */
|
||||
IFvalue ptemp; /* a value structure to package resistance into */
|
||||
int waslead; /* flag to indicate that funny unlabeled number was found */
|
||||
double leadval; /* actual value of unlabeled number */
|
||||
|
|
@ -49,11 +49,25 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
}
|
||||
}
|
||||
line = current->line;
|
||||
INPgetNetTok(&line, &name, 1);
|
||||
|
||||
INPgetNetTok(&line, &name, 1); /* Cname */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname1, 1); /* <node> */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname2, 1); /* <node> */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid capacitor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
INPinsert(&name, tab);
|
||||
INPgetNetTok(&line, &nname1, 1);
|
||||
INPtermInsert(ckt, &nname1, tab, &node1);
|
||||
INPgetNetTok(&line, &nname2, 1);
|
||||
INPtermInsert(ckt, &nname2, tab, &node2);
|
||||
|
||||
/* enable reading values like 4u7 */
|
||||
|
|
@ -109,7 +123,12 @@ void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!fast || !fast->GENmodPtr) {
|
||||
fprintf(stderr, "\nWarning: Instance for capacitor '%s' could not be set up properly, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error1 == 0) { /* Looks like a number */
|
||||
ptemp.rValue = val;
|
||||
GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast));
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
int error1; /* secondary error code temporary */
|
||||
INPmodel *thismodel; /* pointer to model structure describing our model */
|
||||
GENmodel *mdfast = NULL; /* pointer to the actual model */
|
||||
GENinstance *fast; /* pointer to the actual instance */
|
||||
GENinstance *fast = NULL;/* pointer to the actual instance */
|
||||
IFvalue ptemp; /* a value structure to package inductance into */
|
||||
int waslead; /* flag to indicate that funny unlabeled number was found */
|
||||
double leadval; /* actual value of unlabeled number */
|
||||
|
|
@ -49,14 +49,25 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
}
|
||||
}
|
||||
line = current->line;
|
||||
INPgetNetTok(&line, &name, 1);
|
||||
INPinsert(&name, tab);
|
||||
INPgetNetTok(&line, &nname1, 1);
|
||||
INPtermInsert(ckt, &nname1, tab, &node1);
|
||||
INPgetNetTok(&line, &nname2, 1);
|
||||
INPtermInsert(ckt, &nname2, tab, &node2);
|
||||
INPgetNetTok(&line, &name, 1); /* Lname */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname1, 1); /* <node> */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname2, 1); /* <node> */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid inductor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
// val = INPevaluate(&line, &error1, 1);
|
||||
INPinsert(&name, tab);
|
||||
INPtermInsert(ckt, &nname1, tab, &node1);
|
||||
INPtermInsert(ckt, &nname2, tab, &node2);
|
||||
|
||||
/* enable reading values like 4u7 */
|
||||
if (newcompat.lt)
|
||||
|
|
@ -110,7 +121,12 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!fast || !fast->GENmodPtr) {
|
||||
fprintf(stderr, "\nWarning: Instance for inductor '%s' could not be set up properly, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error1 == 0) { /* Looks like a number */
|
||||
ptemp.rValue = val;
|
||||
GCA(INPpName, ("inductance", &ptemp, ckt, type, fast));
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
int error1; /* secondary error code temporary */
|
||||
INPmodel *thismodel; /* pointer to model structure describing our model */
|
||||
GENmodel *mdfast = NULL; /* pointer to the actual model */
|
||||
GENinstance *fast; /* pointer to the actual instance */
|
||||
GENinstance *fast = NULL; /* pointer to the actual instance */
|
||||
IFvalue ptemp; /* a value structure to package resistance into */
|
||||
int waslead; /* flag to indicate that funny unlabeled number was found */
|
||||
double leadval; /* actual value of unlabeled number */
|
||||
|
|
@ -59,10 +59,23 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
}
|
||||
line = current->line;
|
||||
INPgetNetTok(&line, &name, 1); /* Rname */
|
||||
INPinsert(&name, tab);
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname1, 1); /* <node> */
|
||||
INPtermInsert(ckt, &nname1, tab, &node1);
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
INPgetNetTok(&line, &nname2, 1); /* <node> */
|
||||
if (*line == '\0') {
|
||||
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
INPinsert(&name, tab);
|
||||
INPtermInsert(ckt, &nname1, tab, &node1);
|
||||
INPtermInsert(ckt, &nname2, tab, &node2);
|
||||
|
||||
/* enable reading values like 4k7 */
|
||||
|
|
@ -197,6 +210,11 @@ void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current)
|
|||
}
|
||||
}
|
||||
|
||||
if (!fast || !fast->GENmodPtr) {
|
||||
fprintf(stderr, "\nWarning: Instance for resistor '%s' could not be set up properly, ignored!\n\n", current->line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (error1 == 0) { /* got a resistance above */
|
||||
ptemp.rValue = val;
|
||||
GCA(INPpName, ("resistance", &ptemp, ckt, type, fast));
|
||||
|
|
|
|||
Loading…
Reference in New Issue