Merge branch 'pre-master-42' into bt_dev

This commit is contained in:
Brian Taylor 2023-12-18 09:33:34 -08:00
commit be7f14e43b
13 changed files with 167 additions and 37 deletions

28
NEWS
View File

@ -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:

View File

@ -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

View File

@ -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;
}

View File

@ -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. */

View File

@ -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;

View File

@ -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))

View File

@ -853,7 +853,6 @@ tm0 = gtodsecld() ;
isConv = 0;
}
}
}
#endif /* NEWCONV */
}
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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));

View File

@ -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));

View File

@ -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));