From a8d23dc199be03bb1b9a07df3ce51bf22defb411 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 5 Dec 2025 17:13:25 +0100 Subject: [PATCH] More on the frame for HB Enable for gcc Set two params f1 and f2 for .HB Some fixes --- configure.ac | 16 +++++++ src/include/ngspice/hbardefs.h | 21 ++-------- src/spicelib/analysis/analysis.c | 3 +- src/spicelib/analysis/hban.c | 9 ++-- src/spicelib/analysis/hbaskq.c | 43 ++----------------- src/spicelib/analysis/hbsetp.c | 71 ++++++++------------------------ src/spicelib/parser/inp2dot.c | 8 ++-- 7 files changed, 53 insertions(+), 118 deletions(-) diff --git a/configure.ac b/configure.ac index 1c5f7aafc..28065883c 100644 --- a/configure.ac +++ b/configure.ac @@ -158,6 +158,10 @@ AC_ARG_ENABLE([pss], AC_ARG_ENABLE([sp], [AS_HELP_STRING([--disable-sp], [Disable S parameter Analysis])]) +# --disable-hb: disable Harmonic Balance Analysis +AC_ARG_ENABLE([hb], + [AS_HELP_STRING([--disable-hb], [Disable Harmonic Balance Analysis])]) + # --enable-relpath: Relative path for binary and data. Default is "no". # ngspice shared may want relative paths for spinit etc. AC_ARG_ENABLE([relpath], @@ -1226,6 +1230,18 @@ fi AM_CONDITIONAL([SP_WANTED], [test "x$has_sp" = xtrue]) +# Add harmonic balance analysis to ngspice. +if test "x$enable_hb" = xno; then + AC_MSG_RESULT([Harmonic Balance analysis disabled]) + has_hb=false +else + AC_MSG_RESULT([Harmonic Balance analysis enabled]) + AC_DEFINE([WITH_HB], [1], [HB analysis]) + has_hb=true +fi + +AM_CONDITIONAL([HB_WANTED], [test "x$has_hb" = xtrue]) + AM_CONDITIONAL([CIDER_WANTED], [test "x$enable_cider" = xyes]) AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes]) diff --git a/src/include/ngspice/hbardefs.h b/src/include/ngspice/hbardefs.h index 12917e10b..5b0145099 100644 --- a/src/include/ngspice/hbardefs.h +++ b/src/include/ngspice/hbardefs.h @@ -15,16 +15,8 @@ typedef struct { int JOBtype; JOB *JOBnextJob; /* pointer to next thing to do */ char *JOBname; /* name of this job */ - double SPstartFreq; - double SPstopFreq; - double SPfreqDelta; /* multiplier for decade/octave stepping, */ - /* step for linear steps. */ - double SPsaveFreq; /* frequency at which we left off last time*/ - int SPstepType; /* values described below */ - int SPnumberSteps; - - unsigned SPdoNoise : 1; /* Flag to indicate if SP noise must be calculated*/ - + double HBFreq1; + double HBFreq2; int SPnoiseInput; int SPnoiseOutput; } HBAN; @@ -39,13 +31,8 @@ enum { #endif enum { - SP_DEC = 1, - SP_OCT, - SP_LIN, - SP_START, - SP_STOP, - SP_STEPS, - SP_DONOISE, + HB_F1 = 1, + HB_F2 }; #endif #endif diff --git a/src/spicelib/analysis/analysis.c b/src/spicelib/analysis/analysis.c index 8a4097bd8..f3c8f9aa9 100644 --- a/src/spicelib/analysis/analysis.c +++ b/src/spicelib/analysis/analysis.c @@ -18,13 +18,12 @@ extern SPICEanalysis SENSinfo; #ifdef RFSPICE extern SPICEanalysis SPinfo; +#endif #ifdef WITH_HB extern SPICEanalysis HBinfo; #endif -#endif - #ifdef WITH_PSS extern SPICEanalysis PSSinfo; #endif diff --git a/src/spicelib/analysis/hban.c b/src/spicelib/analysis/hban.c index d32ade3d5..08befd034 100644 --- a/src/spicelib/analysis/hban.c +++ b/src/spicelib/analysis/hban.c @@ -373,7 +373,7 @@ HBan(CKTcircuit* ckt, int restart) // Noise analysis is performed at each freq of the SP Analysis // A temporary dummy job is therefore created - +#if(0) /* variable must be static, for continuation of interrupted (Ctrl-C), longer lasting noise anlysis */ static Ndata* data = NULL; @@ -769,10 +769,10 @@ HBan(CKTcircuit* ckt, int restart) return (E_NOMOD); ckt->CKTVSRCid = vsrcRoot; -#if (0) + // Now that we have found the model, we may init the Zref and Gn ports VSRCspinit(ckt->CKThead[vsrcRoot], ckt, zref, gn, gninv); -#endif + } else vsrcRoot = ckt->CKTVSRCid; @@ -982,6 +982,9 @@ endsweep: ckt->CKTmatrix->SMPkluMatrix->KLUmatrixIsComplex = KLUmatrixReal; } #endif + +#endif + return(0); } diff --git a/src/spicelib/analysis/hbaskq.c b/src/spicelib/analysis/hbaskq.c index f53be0336..086702032 100644 --- a/src/spicelib/analysis/hbaskq.c +++ b/src/spicelib/analysis/hbaskq.c @@ -23,47 +23,12 @@ HBaskQuest(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) switch(which) { - case SP_START: - value->rValue = job->SPstartFreq; + case HB_F1: + value->rValue = job->HBFreq1; break; - case SP_STOP: - value->rValue = job->SPstopFreq ; - break; - - case SP_STEPS: - value->iValue = job->SPnumberSteps; - break; - - case SP_DEC: - if (job->SPstepType == DECADE) { - value->iValue=1; - } else { - value->iValue=0; - } - break; - - case SP_OCT: - if (job->SPstepType == OCTAVE) { - value->iValue=1; - } else { - value->iValue=0; - } - break; - - case SP_LIN: - if (job->SPstepType == LINEAR) { - value->iValue=1; - } else { - value->iValue=0; - } - break; - - case SP_DONOISE: - if (job->SPdoNoise) - value->iValue = 1; - else - value->iValue = 0; + case HB_F2: + value->rValue = job->HBFreq2; break; default: diff --git a/src/spicelib/analysis/hbsetp.c b/src/spicelib/analysis/hbsetp.c index 2a69db138..f046011a5 100644 --- a/src/spicelib/analysis/hbsetp.c +++ b/src/spicelib/analysis/hbsetp.c @@ -11,7 +11,7 @@ Author: 1985 Thomas L. Quarles #include "analysis.h" -#ifdef RFSPICE +#ifdef WITH_HB /* ARGSUSED */ int @@ -23,63 +23,28 @@ HBsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) switch(which) { - case SP_START: - if (value->rValue < 0.0) { - errMsg = copy("Frequency of < 0 is invalid for AC start"); - job->SPstartFreq = 1.0; - return(E_PARMVAL); - } - - job->SPstartFreq = value->rValue; - break; - - case SP_STOP: - if (value->rValue < 0.0) { - errMsg = copy("Frequency of < 0 is invalid for AC stop"); - job->SPstartFreq = 1.0; - return(E_PARMVAL); - } - - job->SPstopFreq = value->rValue; - break; - - case SP_STEPS: - job->SPnumberSteps = value->iValue; - break; - - case SP_DEC: - if(value->iValue) { - job->SPstepType = DECADE; - } else { - if (job->SPstepType == DECADE) { - job->SPstepType = 0; - } + case HB_F1: + if (value->rValue < 0.0) { + errMsg = copy("Frequency 1 less than 0 is invalid for HB"); + job->HBFreq1 = 1.0; + return(E_PARMVAL); } + + job->HBFreq1 = value->rValue; break; - case SP_OCT: - if(value->iValue) { - job->SPstepType = OCTAVE; - } else { - if (job->SPstepType == OCTAVE) { - job->SPstepType = 0; - } + + case HB_F2: + if (value->rValue < 0.0) { + errMsg = copy("Frequency 2 less than 0 is invalid for HB"); + job->HBFreq2 = 1.0; + return(E_PARMVAL); } + + job->HBFreq2 = value->rValue; break; - case SP_LIN: - if(value->iValue) { - job->SPstepType = LINEAR; - } else { - if (job->SPstepType == LINEAR) { - job->SPstepType = 0; - } - } - break; - case SP_DONOISE: - job->SPdoNoise = value->iValue == 1; - break; default: return(E_BADPARM); @@ -89,8 +54,8 @@ HBsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) static IFparm HBparms[] = { - { "f1", SP_START, IF_SET|IF_ASK|IF_REAL, "fundamental frequency" }, - { "f2", SP_STOP, IF_SET|IF_ASK|IF_REAL, "second frequency" } + { "f1", HB_F1, IF_SET|IF_ASK|IF_REAL, "fundamental frequency" }, + { "f2", HB_F2, IF_SET|IF_ASK|IF_REAL, "second frequency" } }; SPICEanalysis HBinfo = { diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c index 6bc65f0a8..c24648c4d 100644 --- a/src/spicelib/parser/inp2dot.c +++ b/src/spicelib/parser/inp2dot.c @@ -763,11 +763,11 @@ dot_hb(char* line, void* ckt, INPtables* tab, struct card* current, } IFC(newAnalysis, (ckt, which, "Harmonic Balance Analysis", &foo, task)); - parm = INPgetValue(ckt, &line, IF_REALVEC, tab); /* Fguess */ - GCA(INPapName, (ckt, which, foo, "freq1", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* F1 */ + GCA(INPapName, (ckt, which, foo, "f1", parm)); - parm = INPgetValue(ckt, &line, IF_REALVEC, tab); /* Fguess */ - GCA(INPapName, (ckt, which, foo, "freq2", parm)); + parm = INPgetValue(ckt, &line, IF_REAL, tab); /* F2 */ + GCA(INPapName, (ckt, which, foo, "f2", parm)); if (*line) { fprintf(stderr, "Error: unknown parameter %s on .hb - ignored\n", word);