diff --git a/src/frontend/fourier.c b/src/frontend/fourier.c index 47b7e6158..d66efe3ee 100644 --- a/src/frontend/fourier.c +++ b/src/frontend/fourier.c @@ -50,6 +50,7 @@ fourier(wordlist *wl, struct plot *current_plot) char xbuf[20]; int shift; int rv = 1; + bool foursave = TRUE; struct dvec *n; int newveccount = 1; @@ -71,6 +72,8 @@ fourier(wordlist *wl, struct plot *current_plot) polydegree = 1; if (!cp_getvar("fourgridsize", CP_NUM, &fourgridsize, 0) || fourgridsize < 1) fourgridsize = DEF_FOURGRIDSIZE; + if (cp_getvar("fournosave", CP_BOOL, NULL, 0)) + foursave = FALSE; time = current_plot->pl_scale; if (!isreal(time)) { @@ -188,34 +191,48 @@ fourier(wordlist *wl, struct plot *current_plot) } fputs("\n", cp_out); - /* create and assign a new vector n */ - /* with size 3 * nfreqs in current plot */ - /* generate name for new vector, using vec->name */ - n = dvec_alloc(tprintf("fourier%d%d", callstof, newveccount), - SV_NOTYPE, - VF_REAL | VF_PERMANENT, - 3 * nfreqs, NULL); + if (foursave) { + /* create a vector for THD */ + n = dvec_alloc(tprintf("thd%d%d", callstof, newveccount), + SV_NOTYPE, + VF_REAL | VF_PERMANENT, + 1, NULL); - n->v_numdims = 2; - n->v_dims[0] = 3; - n->v_dims[1] = nfreqs; + n->v_numdims = 1; - vec_new(n); + vec_new(n); - /* store data in vector: freq, mag, phase */ - for (i = 0; i < nfreqs; i++) { - n->v_realdata[i] = freq[i]; - n->v_realdata[i + nfreqs] = mag[i]; - n->v_realdata[i + 2 * nfreqs] = phase[i]; + n->v_realdata[0] = thd; + + /* create and assign a new vector n */ + /* with size 3 * nfreqs in current plot */ + /* generate name for new vector, using vec->name */ + n = dvec_alloc(tprintf("fourier%d%d", callstof, newveccount), + SV_NOTYPE, + VF_REAL | VF_PERMANENT, + 3 * nfreqs, NULL); + + n->v_numdims = 2; + n->v_dims[0] = 3; + n->v_dims[1] = nfreqs; + + vec_new(n); + + /* store data in vector: freq, mag, phase */ + for (i = 0; i < nfreqs; i++) { + n->v_realdata[i] = freq[i]; + n->v_realdata[i + nfreqs] = mag[i]; + n->v_realdata[i + 2 * nfreqs] = phase[i]; + } + newveccount++; + + if (polydegree) { + tfree(timescale); + tfree(data); + } + timescale = NULL; + data = NULL; } - newveccount++; - - if (polydegree) { - tfree(timescale); - tfree(data); - } - timescale = NULL; - data = NULL; } } diff --git a/src/frontend/inpcompat.c b/src/frontend/inpcompat.c index 4813c03b4..d1c22f5a2 100644 --- a/src/frontend/inpcompat.c +++ b/src/frontend/inpcompat.c @@ -751,9 +751,9 @@ struct card *pspice_compat(struct card *oldcard) /* .model xxx NMOS/PMOS level=6 --> level = 8, version=3.2.4 .model xxx NMOS/PMOS level=7 --> level = 8, version=3.2.4 - .model xxx NMOS/PMOS level=5 --> level = 44 + .model xxx NMOS/PMOS level=5 --> only available per Veriloga, OpenVAF and OSDI .model xxx NMOS/PMOS level=8 --> level = 14, version=4.5.0 - .model xxx NPN/PNP level=2 --> level = 6 + .model xxx NPN/PNP level=2 --> only available per Veriloga, OpenVAF and OSDI .model xxx LPNP level=n --> level = 1 subs=-1 Remove any Monte - Carlo variation parameters from .model cards.*/ for (card = newcard; card; card = card->nextcard) { @@ -783,10 +783,11 @@ struct card *pspice_compat(struct card *oldcard) switch (ll) { case 5: { - /* EKV 2.6 in the adms branch */ - char* newline = tprintf(".model %s %s level=44 %s", modname, modtype, lv); - tfree(card->line); - card->line = curr_line = newline; + /* EKV 2.6 only per OSDI and OpenVAF */ + fprintf(stderr, "Error: MOS model level 5, EKV 2.6, is not available as an intrinsic model.\n"); + fprintf(stderr, " Please consider using a Verilog-A model, OpenVAF compilation,\n"); + fprintf(stderr, " and the ngspice OSDI interface (see ngspice manual chapter 9).\n"); + controlled_exit(EXIT_BAD); } break; case 6: @@ -822,10 +823,11 @@ struct card *pspice_compat(struct card *oldcard) switch (ll) { case 2: { - /* MEXTRAM 504.12.1 in the adms branch */ - char* newline = tprintf(".model %s %s level=6 %s", modname, modtype, lv); - tfree(card->line); - card->line = curr_line = newline; + /* MEXTRAM 504.12.1 only per OSDI and OpenVAF */ + fprintf(stderr, "Error: Bipolar model level 2, MEXTRAM 504.12.1, is not available as an intrinsic model.\n"); + fprintf(stderr, " Please consider using a Verilog-A model, OpenVAF compilation,\n"); + fprintf(stderr, " and the ngspice OSDI interface (see ngspice manual chapter 9).\n"); + controlled_exit(EXIT_BAD); } break; default: diff --git a/src/spicelib/analysis/noisean.c b/src/spicelib/analysis/noisean.c index 99e0a393b..5115f854f 100644 --- a/src/spicelib/analysis/noisean.c +++ b/src/spicelib/analysis/noisean.c @@ -411,6 +411,65 @@ NOISEan(CKTcircuit* ckt, int restart) job->NsavInoise = data->inNoise; return (E_PAUSE); } + + /* Update opertating point, if variable 'hertz' is given */ + if (ckt->CKTvarHertz) { + +#ifdef KLU + if (ckt->CKTmatrix->CKTkluMODE) + { + /* Conversion from Complex Matrix to Real Matrix */ + for (i = 0; i < DEVmaxnum; i++) + if (DEVices[i] && DEVices[i]->DEVbindCSCComplexToReal && ckt->CKThead[i]) + DEVices[i]->DEVbindCSCComplexToReal(ckt->CKThead[i], ckt); + + ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUmatrixReal; + } +#endif + +#ifdef XSPICE + /* Call EVTop if event-driven instances exist */ + + if (ckt->evt->counts.num_insts != 0) { + error = EVTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter, + MIF_TRUE); + EVTdump(ckt, IPC_ANAL_DCOP, 0.0); + EVTop_save(ckt, MIF_TRUE, 0.0); + } + else +#endif + // If no event-driven instances, do what SPICE normally does + error = CKTop(ckt, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, + ckt->CKTdcMaxIter); + + if (error) { + fprintf(stderr, "\nError: AC operating point with variable 'Hertz' for noise sim failed -\n"); + CKTncDump(ckt); + return(error); + } + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG; + error = CKTload(ckt); + if (error) return(error); + +#ifdef KLU + if (ckt->CKTmatrix->CKTkluMODE) + { + /* Conversion from Real Matrix to Complex Matrix */ + for (i = 0; i < DEVmaxnum; i++) + if (DEVices[i] && DEVices[i]->DEVbindCSCComplex && ckt->CKThead[i]) + DEVices[i]->DEVbindCSCComplex(ckt->CKThead[i], ckt); + + ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUMatrixComplex; + } +#endif + + } + ckt->CKTomega = 2.0 * M_PI * data->freq; ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEAC | MODEACNOISE; ckt->noise_input = inst;