Browse Source

S parameter simulation

Command '.sp'
arbitrary number of ports
ports made with modified VSRC

Patch provided by Alessio Cacciatori
https://sourceforge.net/p/ngspice/discussion/127605/thread/7a2655c86f/
pre-master-46
Alessio Cacciatori 4 years ago
committed by Holger Vogt
parent
commit
2c10c4aebd
  1. 21
      examples/sp/sp1.cir
  2. 8
      src/frontend/commands.c
  3. 11
      src/frontend/runcoms.c
  4. 3
      src/frontend/runcoms.h
  5. 81
      src/frontend/shyu.c
  6. 9
      src/frontend/spiceif.c
  7. 10
      src/include/ngspice/acdefs.h
  8. 41
      src/include/ngspice/cktdefs.h
  9. 3
      src/include/ngspice/ipc.h
  10. 51
      src/include/ngspice/spdefs.h
  11. 1325
      src/maths/dense/dense.c
  12. 103
      src/maths/dense/dense.h
  13. 76
      src/maths/ni/niaciter.c
  14. 15
      src/spicelib/analysis/analysis.c
  15. 10
      src/spicelib/analysis/cktdest.c
  16. 108
      src/spicelib/analysis/cktspdum.c
  17. 736
      src/spicelib/analysis/span.c
  18. 73
      src/spicelib/analysis/spaskq.c
  19. 114
      src/spicelib/analysis/spsetp.c
  20. 9
      src/spicelib/devices/cktinit.c
  21. 7
      src/spicelib/devices/vsrc/vsrc.c
  22. 136
      src/spicelib/devices/vsrc/vsrcacld.c
  23. 17
      src/spicelib/devices/vsrc/vsrcask.c
  24. 44
      src/spicelib/devices/vsrc/vsrcdefs.h
  25. 4
      src/spicelib/devices/vsrc/vsrcext.h
  26. 41
      src/spicelib/devices/vsrc/vsrcload.c
  27. 45
      src/spicelib/devices/vsrc/vsrcpar.c
  28. 43
      src/spicelib/devices/vsrc/vsrcset.c
  29. 90
      src/spicelib/devices/vsrc/vsrctemp.c
  30. 114
      src/spicelib/parser/inp2dot.c
  31. 19
      visualc/vngspice.vcxproj

21
examples/sp/sp1.cir

@ -0,0 +1,21 @@
Example of VSRC as power ports
*
*
V1 in 0 dc 0 ac 1 portnum 1 z0 100 pwr 0.001 freq 2.3e9
*V1 in 0 dc 1 ac 1
Rpt in x 100
C1 x 0 1e-9
*Vx x 0 0
R2 x out 10
V2 out 0 dc 0 ac 0 portnum 2 z0 50 pwr 0.002 freq 3.2e9
*V2 out 0 dc 0 ac 0
.sp lin 100 1e8 1e9 1
.control
run
plot S_1_1 S_1_2 S_2_1
plot S_2_2
.endc
.end

8
src/frontend/commands.c

@ -305,6 +305,14 @@ struct comm spcp_coms[] = {
NULL, NULL,
"[.pss line args] : Do a periodic state analysis." } , "[.pss line args] : Do a periodic state analysis." } ,
/* SP */ /* SP */
#endif
#ifdef RFSPICE
/* SP: S parameter Analysis */
{ "sp", com_sp, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,
NULL,
"[.sp line args] : Do a S parameter analysis." },
/* SP */
#endif #endif
{ "ac", com_ac, TRUE, TRUE, { "ac", com_ac, TRUE, TRUE,
{ 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS,

11
src/frontend/runcoms.c

@ -177,15 +177,22 @@ com_noise(wordlist *wl)
#ifdef WITH_PSS #ifdef WITH_PSS
/* SP: Steady State Analysis */
/* Steady State Analysis */
void void
com_pss(wordlist *wl) com_pss(wordlist *wl)
{ {
dosim("pss", wl); dosim("pss", wl);
} }
/* SP */
#endif #endif
#ifdef RFSPICE
/* S parameter Analysis*/
void
com_sp(wordlist* wl)
{
dosim("sp", wl);
}
#endif
static int dosim( static int dosim(
char *what, /* in: command char *what, /* in: command

3
src/frontend/runcoms.h

@ -20,6 +20,9 @@ void com_sens(wordlist *wl);
void com_disto(wordlist *wl); void com_disto(wordlist *wl);
void com_noise(wordlist *wl); void com_noise(wordlist *wl);
void com_run(wordlist *wl); void com_run(wordlist *wl);
#ifdef RFSPICE
void com_sp(wordlist* wl);
#endif
extern FILE *rawfileFp; extern FILE *rawfileFp;
extern bool rawfileBinary; extern bool rawfileBinary;

81
src/frontend/shyu.c

@ -314,6 +314,87 @@ if_sens_run(CKTcircuit *ckt, wordlist *args, INPtables *tab)
} }
#endif #endif
#ifdef RFSPICE
if (strcmp(token, "sp") == 0) {
JOB* spJob;
which = ft_find_analysis("SP");
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("S-Param analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis(ft_curckt->ci_ckt, which, "span",
&spJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createSP"); /* or similar error message */
return (0); /* temporary */
}
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
ptemp.iValue = 1;
error = INPapName(ckt, which, spJob, steptype, &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab);/* number of points*/
error = INPapName(ckt, which, spJob, "numsteps", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
error = INPapName(ckt, which, spJob, "start", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */
error = INPapName(ckt, which, spJob, "stop", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* fstop */
error = INPapName(ckt, which, spJob, "donoise", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
}
#ifdef WITH_HB
if (strcmp(token, "hb") == 0) {
JOB* spJob;
which = ft_find_analysis("HB");
if (which == -1) {
current->error = INPerrCat
(current->error,
INPmkTemp("S-Param analysis unsupported\n"));
return (0); /* temporary */
}
err = ft_sim->newAnalysis(ft_curckt->ci_ckt, which, "hban",
&spJob, ft_curckt->ci_specTask);
if (err) {
ft_sperror(err, "createHB"); /* or similar error message */
return (0); /* temporary */
}
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
ptemp.iValue = 1;
error = INPapName(ckt, which, spJob, steptype, &ptemp);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab);/* number of points*/
error = INPapName(ckt, which, spJob, "numsteps", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
error = INPapName(ckt, which, spJob, "start", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */
error = INPapName(ckt, which, spJob, "stop", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* fstop */
error = INPapName(ckt, which, spJob, "donoise", parm);
if (error)
current->error = INPerrCat(current->error, INPerror(error));
}
#endif
#endif
next: next:
while (*line) { /* read the entire line */ while (*line) { /* read the entire line */

9
src/frontend/spiceif.c

@ -220,9 +220,14 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab)
eq(what, "tf") || eq(what, "tf") ||
eq(what, "noise") eq(what, "noise")
#ifdef WITH_PSS #ifdef WITH_PSS
/* SP: Steady State Analysis */
/* Steady State Analysis */
|| eq(what, "pss") || eq(what, "pss")
/* SP */
#endif
#ifdef RFSPICE
|| eq(what, "sp")
#ifdef WITH_HB
|| eq(what, "hb")
#endif
#endif #endif
) )
{ {

10
src/include/ngspice/acdefs.h

@ -25,11 +25,21 @@ typedef struct {
/* available step types: XXX should be somewhere else */ /* available step types: XXX should be somewhere else */
#ifdef RFSPICE
#ifndef ngspice_SPDEFS_H
enum { enum {
DECADE = 1, DECADE = 1,
OCTAVE, OCTAVE,
LINEAR, LINEAR,
}; };
#endif
#else
enum {
DECADE = 1,
OCTAVE,
LINEAR,
};
#endif
enum { enum {
AC_DEC = 1, AC_DEC = 1,

41
src/include/ngspice/cktdefs.h

@ -32,6 +32,9 @@
#include "ngspice/noisedef.h" #include "ngspice/noisedef.h"
#include "ngspice/hash.h" #include "ngspice/hash.h"
#ifdef RFSPICE
#include "../maths/dense/dense.h"
#endif
struct CKTnode { struct CKTnode {
@ -187,6 +190,11 @@ struct CKTcircuit {
#define MODEINITTRAN 0x1000 #define MODEINITTRAN 0x1000
#define MODEINITPRED 0x2000 #define MODEINITPRED 0x2000
#ifdef RFSPICE
#define MODESP 0x4000
#define MODESPNOISE 0x8000
#endif
/* old 'nosolv' paramater */ /* old 'nosolv' paramater */
#define MODEUIC 0x10000l #define MODEUIC 0x10000l
@ -274,7 +282,17 @@ struct CKTcircuit {
Enh_Ckt_Data_t *enh; /* data used by general enhancements */ Enh_Ckt_Data_t *enh; /* data used by general enhancements */
#endif #endif
/* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */ /* gtri - evt - wbk - 5/20/91 - add event-driven and enhancements data */
#ifdef RFSPICE
unsigned int CKTactivePort;/* Identify active port during S-Param analysis*/
unsigned int CKTportCount; /* Number of RF ports */
int CKTVSRCid; /* Place holder for VSRC Devices id*/
GENinstance** CKTrfPorts; /* List of all RF ports (HB & SP) */
CMat* CKTAmat;
CMat* CKTBmat;
CMat* CKTSmat;
CMat* CKTYmat;
CMat* CKTZmat;
#endif
#ifdef WITH_PSS #ifdef WITH_PSS
/* SP: Periodic Steady State Analysis - 100609 */ /* SP: Periodic Steady State Analysis - 100609 */
double CKTstabTime; /* PSS stab time */ double CKTstabTime; /* PSS stab time */
@ -356,6 +374,9 @@ extern int CKTmodAsk(CKTcircuit *, GENmodel *, int , IFvalue *, IFvalue *);
extern int CKTmodCrt(CKTcircuit *, int , GENmodel **, IFuid); extern int CKTmodCrt(CKTcircuit *, int , GENmodel **, IFuid);
extern int CKTmodParam(CKTcircuit *, GENmodel *, int , IFvalue *, IFvalue *); extern int CKTmodParam(CKTcircuit *, GENmodel *, int , IFvalue *, IFvalue *);
extern int CKTnames(CKTcircuit *, int *, IFuid **); extern int CKTnames(CKTcircuit *, int *, IFuid **);
#ifdef RFSPICE
extern int CKTSPnames(CKTcircuit*, int*, IFuid**);
#endif
extern int CKTdnames(CKTcircuit *); extern int CKTdnames(CKTcircuit *);
extern int CKTnewAnal(CKTcircuit *, int , IFuid , JOB **, TSKtask *); extern int CKTnewAnal(CKTcircuit *, int , IFuid , JOB **, TSKtask *);
extern int CKTnewEq(CKTcircuit *, CKTnode **, IFuid); extern int CKTnewEq(CKTcircuit *, CKTnode **, IFuid);
@ -423,12 +444,22 @@ extern int TRANsetParm(CKTcircuit *, JOB *, int , IFvalue *);
extern int TRANinit(CKTcircuit *, JOB *); extern int TRANinit(CKTcircuit *, JOB *);
#ifdef WITH_PSS #ifdef WITH_PSS
/* SP: Steady State Analysis */
/* Steady State Analysis */
extern int PSSaskQuest(CKTcircuit *, JOB *, int , IFvalue *); extern int PSSaskQuest(CKTcircuit *, JOB *, int , IFvalue *);
extern int PSSsetParm(CKTcircuit *, JOB *, int , IFvalue *); extern int PSSsetParm(CKTcircuit *, JOB *, int , IFvalue *);
extern int PSSinit(CKTcircuit *, JOB *); extern int PSSinit(CKTcircuit *, JOB *);
extern int DCpss(CKTcircuit *, int); extern int DCpss(CKTcircuit *, int);
/* SP */
#endif
#ifdef RFSPICE
extern int SPan(CKTcircuit*, int);
extern int SPaskQuest(CKTcircuit*, JOB*, int, IFvalue*);
extern int SPsetParm(CKTcircuit*, JOB*, int, IFvalue*);
extern int CKTspDump(CKTcircuit*, double, runDesc*);
extern int CKTspLoad(CKTcircuit*);
extern unsigned int CKTmatrixIndex(CKTcircuit*, unsigned int, unsigned int);
extern int CKTspCalcPowerWave(CKTcircuit* ckt);
extern int CKTspCalcSMatrix(CKTcircuit* ckt);
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -452,6 +483,10 @@ extern int NIreinit(CKTcircuit *);
extern int NIsenReinit(CKTcircuit *); extern int NIsenReinit(CKTcircuit *);
extern int NIdIter (CKTcircuit *); extern int NIdIter (CKTcircuit *);
extern void NInzIter(CKTcircuit *, int, int); extern void NInzIter(CKTcircuit *, int, int);
#ifdef RFSPICE
extern int NIspPreload(CKTcircuit*);
extern int NIspSolve(CKTcircuit*);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

3
src/include/ngspice/ipc.h

@ -112,6 +112,9 @@ typedef enum {
IPC_ANAL_DCTRCURVE, IPC_ANAL_DCTRCURVE,
IPC_ANAL_AC, IPC_ANAL_AC,
IPC_ANAL_TRAN, IPC_ANAL_TRAN,
#ifdef RFSPICE
IPC_ANAL_SP
#endif
} Ipc_Anal_t; } Ipc_Anal_t;

51
src/include/ngspice/spdefs.h

@ -0,0 +1,51 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#ifndef ngspice_SPDEFS_H
#define ngspice_SPDEFS_H
#include "ngspice/jobdefs.h"
#ifdef RFSPICE
/* structure used to describe an AC analysis to be performed */
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*/
unsigned int SPnoiseInput;
unsigned int SPnoiseOutput;
} SPAN;
/* available step types: XXX should be somewhere else */
#ifndef ngspice_ACDEFS_H
enum {
DECADE = 1,
OCTAVE,
LINEAR,
};
#endif
enum {
SP_DEC = 1,
SP_OCT,
SP_LIN,
SP_START,
SP_STOP,
SP_STEPS,
SP_DONOISE,
};
#endif
#endif

1325
src/maths/dense/dense.c
File diff suppressed because it is too large
View File

103
src/maths/dense/dense.h

@ -0,0 +1,103 @@
#ifndef ngspice_DENSE_MATRIX_H
#define ngspice_DENSE_MATRIX_H
typedef struct cplx
{
double re;
double im;
}cplx;
typedef struct Mat{
double** d;
int row;
int col;
}Mat;
typedef struct CMat {
cplx** d;
int row;
int col;
}CMat;
typedef struct MatList{
Mat* mat;
struct MatList* next;
}MatList;
extern void showmat(Mat* A);
extern void showcmat(CMat* A);
extern CMat* newcmat(int r, int c, double dr, double di);
extern CMat* newcmatnoinit(int r, int c);
extern Mat* newmat(int r, int c, double d);
extern Mat* newmatnoinit(int r, int c);
extern void freecmat(CMat* A);
extern void freemat(Mat* A);
extern CMat* ceye(int n);
extern Mat* eye(int n);
extern Mat* zeros(int r, int c);
extern CMat* czeros(int r, int c);
extern Mat* ones(int r, int c);
extern CMat* cones(int r, int c);
extern Mat* randm(int r, int c, double l, double u);
extern CMat* randcm(int r, int c, double l, double u);
extern double get(Mat* M, int r, int c);
extern cplx getcplx(CMat* M, int r, int c);
extern void set(Mat* M, int r, int c, double d);
extern void setc(CMat* M, int r, int c, cplx d);
extern Mat* scalarmultiply(Mat* M, double c);
extern CMat* cscalarmultiply(CMat* M, double c);
extern CMat* complexmultiply(CMat* M, cplx c);
extern Mat* sum(Mat* A, Mat* B);
extern CMat* csum(CMat* A, CMat* B);
extern Mat* minus(Mat* A, Mat* B);
extern CMat* cminus(CMat* A, CMat* B);
extern Mat* submat(Mat* A, int r1, int r2, int c1, int c2);
extern void submat2(Mat* A, Mat* B, int r1, int r2, int c1, int c2);
extern CMat* subcmat(CMat* A, int r1, int r2, int c1, int c2);
extern void subcmat2(CMat* A, CMat* B, int r1, int r2, int c1, int c2);
extern Mat* multiply(Mat* A, Mat* B);
extern CMat* cmultiply(CMat* A, CMat* B);
extern Mat* removerow(Mat* A, int r);
extern Mat* removecol(Mat* A, int c);
extern void removerow2(Mat* A, Mat* B, int r);
extern void removecol2(Mat* A, Mat* B, int c);
extern CMat* cremoverow(CMat* A, int r);
extern CMat* cremovecol(CMat* A, int c);
extern void cremoverow2(CMat* A, CMat* B, int r);
extern void cremovecol2(CMat* A, CMat* B, int c);
extern Mat* transpose(Mat* A);
extern CMat* ctranspose(CMat* A);
extern double trace(Mat* A);
extern cplx ctrace(CMat* A);
extern Mat* adjoint(Mat* A);
extern CMat* cadjoint(CMat* A);
extern Mat* inverse(Mat* A);
extern CMat* cinverse(CMat* A);
extern Mat* copyvalue(Mat* A);
extern CMat* copycvalue(CMat* A);
extern Mat* copyvalue(Mat* A);
extern CMat* copycvalue(CMat* A);
extern Mat* triinverse(Mat* A);
extern CMat* ctriinverse(CMat* A);
extern Mat* rowechelon(Mat* A);
extern CMat* crowechelon(CMat* A);
extern Mat* hconcat(Mat* A, Mat* B);
extern CMat* chconcat(CMat* A, CMat* B);
extern Mat* vconcat(Mat* A, Mat* B);
extern CMat* cvconcat(CMat* A, CMat* B);
extern double norm(Mat* A);
extern double cnorm(CMat* A);
extern Mat* nullmat(Mat* A);
extern MatList* lu(Mat* A);
extern double innermultiply(Mat* a, Mat* b);
extern MatList* qr(Mat* A);
extern int complexmultiplydest(CMat* M, cplx c, CMat* dest);
extern int cinversedest(CMat* A, CMat* dest);
extern int copycvaluedest(CMat* A, CMat* dest);
extern int cmultiplydest(CMat* A, CMat* B, CMat* dest);
#endif

76
src/maths/ni/niaciter.c

@ -19,6 +19,82 @@ Modified 1999 Emmanuel Rouat
#include "ngspice/cktdefs.h" #include "ngspice/cktdefs.h"
#include "ngspice/sperror.h" #include "ngspice/sperror.h"
#ifdef RFSPICE
// We don't need to reload the AC matrix for every port analysis
// So we split the NIacIter in two functions
int NIspPreload(CKTcircuit* ckt)
{
int error;
int ignore;
double startTime;
retry:
ckt->CKTnoncon = 0;
error = CKTacLoad(ckt);
if (error) return(error);
if (ckt->CKTniState & NIACSHOULDREORDER) {
startTime = SPfrontEnd->IFseconds();
error = SMPcReorder(ckt->CKTmatrix, ckt->CKTpivotAbsTol,
ckt->CKTpivotRelTol, &ignore);
ckt->CKTstat->STATreorderTime +=
SPfrontEnd->IFseconds() - startTime;
ckt->CKTniState &= ~NIACSHOULDREORDER;
if (error != 0) {
/* either singular equations or no memory, in either case,
* let caller handle problem
*/
return(error);
}
}
else {
startTime = SPfrontEnd->IFseconds();
error = SMPcLUfac(ckt->CKTmatrix, ckt->CKTpivotAbsTol);
ckt->CKTstat->STATdecompTime +=
SPfrontEnd->IFseconds() - startTime;
if (error != 0) {
if (error == E_SINGULAR) {
/* the problem is that the matrix can't be solved with the
* current LU factorization. Maybe if we reload and
* try to reorder again it will help...
*/
ckt->CKTniState |= NIACSHOULDREORDER;
goto retry;
}
return(error); /* can't handle E_BADMATRIX, so let caller */
}
}
return (OK);
};
int NIspSolve(CKTcircuit* ckt)
{
double startTime;
startTime = SPfrontEnd->IFseconds();
SMPcSolve(ckt->CKTmatrix, ckt->CKTrhs,
ckt->CKTirhs, ckt->CKTrhsSpare,
ckt->CKTirhsSpare);
ckt->CKTstat->STATsolveTime += SPfrontEnd->IFseconds() - startTime;
ckt->CKTrhs[0] = 0;
ckt->CKTrhsSpare[0] = 0;
ckt->CKTrhsOld[0] = 0;
ckt->CKTirhs[0] = 0;
ckt->CKTirhsSpare[0] = 0;
ckt->CKTirhsOld[0] = 0;
SWAP(double*, ckt->CKTirhs, ckt->CKTirhsOld);
SWAP(double*, ckt->CKTrhs, ckt->CKTrhsOld);
return (OK);
};
#endif
int int
NIacIter(CKTcircuit *ckt) NIacIter(CKTcircuit *ckt)

15
src/spicelib/analysis/analysis.c

@ -16,6 +16,15 @@ extern SPICEanalysis DISTOinfo;
extern SPICEanalysis NOISEinfo; extern SPICEanalysis NOISEinfo;
extern SPICEanalysis SENSinfo; extern SPICEanalysis SENSinfo;
#ifdef RFSPICE
extern SPICEanalysis SPinfo;
#ifdef WITH_HB
extern SPICEanalysis HBinfo;
#endif
#endif
#ifdef WITH_PSS #ifdef WITH_PSS
extern SPICEanalysis PSSinfo; extern SPICEanalysis PSSinfo;
#endif #endif
@ -41,6 +50,12 @@ SPICEanalysis *analInfo[] = {
#ifdef WANT_SENSE2 #ifdef WANT_SENSE2
&SEN2info, &SEN2info,
#endif #endif
#ifdef RFSPICE
& SPinfo,
#ifdef WITH_HB
& HBinfo,
#endif
#endif
}; };

10
src/spicelib/analysis/cktdest.c

@ -104,6 +104,16 @@ CKTdestroy(CKTcircuit *ckt)
nghash_free(ckt->DEVnameHash, NULL, NULL); nghash_free(ckt->DEVnameHash, NULL, NULL);
nghash_free(ckt->MODnameHash, NULL, NULL); nghash_free(ckt->MODnameHash, NULL, NULL);
#ifdef RFSPICE
FREE(ckt->CKTrfPorts);
freecmat(ckt->CKTAmat); ckt->CKTAmat = NULL;
freecmat(ckt->CKTBmat); ckt->CKTBmat = NULL;
freecmat(ckt->CKTSmat); ckt->CKTSmat = NULL;
freecmat(ckt->CKTYmat); ckt->CKTYmat = NULL;
freecmat(ckt->CKTZmat); ckt->CKTZmat = NULL;
#endif
FREE(ckt); FREE(ckt);
#ifdef XSPICE #ifdef XSPICE

108
src/spicelib/analysis/cktspdum.c

@ -0,0 +1,108 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/* CKTspDump(ckt,freq,file)
* this is a simple program to dump the complex rhs vector
* into the rawfile.
*/
#include "ngspice/ngspice.h"
#include "ngspice/smpdefs.h"
#include "ngspice/cktdefs.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/ifsim.h"
#include "vsrc/vsrcdefs.h"
unsigned int CKTmatrixIndex(CKTcircuit* ckt, unsigned int source, unsigned int dest)
{
return source * ckt->CKTportCount + dest;
};
int CKTspCalcSMatrix(CKTcircuit* ckt)
{
CMat* Ainv = cinverse(ckt->CKTAmat);
if (Ainv == NULL) return (E_NOMEM);
cmultiplydest(ckt->CKTBmat, Ainv, ckt->CKTSmat);
freecmat(Ainv);
return (OK);
}
int CKTspCalcPowerWave(CKTcircuit* ckt)
{
double* rhsold = ckt->CKTrhsOld;
double* irhsold = ckt->CKTirhsOld;
int col = ckt->CKTactivePort - 1;
for (int port = 0; port < ckt->CKTportCount; port++)
{
VSRCinstance* pSrc = (VSRCinstance*)(ckt->CKTrfPorts[port]);
int row = pSrc->VSRCportNum - 1;
double zi = pSrc->VSRCportZ0;
double iReal = -rhsold[pSrc->VSRCbranch];
double iImag = -irhsold[pSrc->VSRCbranch];
double vReal = rhsold[pSrc->VSRCposNode] - rhsold[pSrc->VSRCnegNode];
double vImag = irhsold[pSrc->VSRCposNode] - irhsold[pSrc->VSRCnegNode];
// Forward wave (a) of i-th port, real (r) and imag (i)
cplx a;
a.re = pSrc->VSRCki * (vReal + zi * iReal);
a.im = pSrc->VSRCki * (vImag + zi * iImag);
// Scattered wave (b) of i-th port, real (r) and imag (i)
cplx b;
b.re = pSrc->VSRCki * (vReal - zi * iReal);
b.im = pSrc->VSRCki * (vImag - zi * iImag);
// fill in A and B matrices
setc(ckt->CKTAmat, row, col, a);
setc(ckt->CKTBmat, row, col, b);
}
return (OK);
}
int
CKTspDump(CKTcircuit *ckt, double freq, runDesc *plot)
{
double *rhsold;
double *irhsold;
int i;
IFcomplex *data;
IFvalue freqData;
IFvalue valueData;
rhsold = ckt->CKTrhsOld;
irhsold = ckt->CKTirhsOld;
freqData.rValue = freq;
unsigned int extraSPdataCount = ckt->CKTportCount * ckt->CKTportCount;
valueData.v.numValue = ckt->CKTmaxEqNum - 1 + extraSPdataCount;
data = TMALLOC(IFcomplex, ckt->CKTmaxEqNum - 1 + extraSPdataCount);
valueData.v.vec.cVec = data;
for (i=0;i<ckt->CKTmaxEqNum-1;i++) {
data[i].real = rhsold[i+1];
data[i].imag = irhsold[i+1];
}
if (ckt->CKTrfPorts )
{
// Cycle thru all ports
for (unsigned int pdest = 0; pdest < ckt->CKTportCount; pdest++)
{
for (unsigned int psource = 0; psource < ckt->CKTportCount; psource++)
{
unsigned int nPlot = ckt->CKTmaxEqNum - 1 + CKTmatrixIndex(ckt, pdest, psource);
cplx sij = ckt->CKTSmat->d[pdest][psource];
data[nPlot].real = sij.re;
data[nPlot].imag = sij.im;
}
}
}
SPfrontEnd->OUTpData(plot, &freqData, &valueData);
FREE(data);
return(OK);
}

736
src/spicelib/analysis/span.c

@ -0,0 +1,736 @@
/*
****
* Alessio Cacciatori 2021
****
*/
#include "ngspice/ngspice.h"
#include "ngspice/cktdefs.h"
#include "ngspice/spdefs.h"
#include "ngspice/devdefs.h"
#include "ngspice/sperror.h"
#ifdef XSPICE
#include "ngspice/evt.h"
#include "ngspice/enh.h"
/* gtri - add - wbk - 12/19/90 - Add headers */
#include "ngspice/mif.h"
#include "ngspice/evtproto.h"
#include "ngspice/ipctiein.h"
/* gtri - end - wbk */
#endif
#ifdef RFSPICE
#include "vsrc/vsrcext.h"
#include "../maths/dense/dense.h"
#define INIT_STATS() \
do { \
startTime = SPfrontEnd->IFseconds(); \
startdTime = ckt->CKTstat->STATdecompTime; \
startsTime = ckt->CKTstat->STATsolveTime; \
startlTime = ckt->CKTstat->STATloadTime; \
startkTime = ckt->CKTstat->STATsyncTime; \
} while(0)
#define UPDATE_STATS(analysis) \
do { \
ckt->CKTcurrentAnalysis = analysis; \
ckt->CKTstat->STATacTime += SPfrontEnd->IFseconds() - startTime; \
ckt->CKTstat->STATacDecompTime += ckt->CKTstat->STATdecompTime - startdTime; \
ckt->CKTstat->STATacSolveTime += ckt->CKTstat->STATsolveTime - startsTime; \
ckt->CKTstat->STATacLoadTime += ckt->CKTstat->STATloadTime - startlTime; \
ckt->CKTstat->STATacSyncTime += ckt->CKTstat->STATsyncTime - startkTime; \
} while(0)
int
CKTspnoise(CKTcircuit * ckt, int mode, int operation, Ndata * data)
{
NOISEAN* job = (NOISEAN*)ckt->CKTcurJob;
double outNdens;
int i;
IFvalue outData; /* output variable (points to list of outputs)*/
IFvalue refVal; /* reference variable (always 0)*/
int error;
outNdens = 0.0;
/* let each device decide how many and what type of noise sources it has */
for (i = 0; i < DEVmaxnum; i++) {
if (DEVices[i] && DEVices[i]->DEVnoise && ckt->CKThead[i]) {
error = DEVices[i]->DEVnoise(mode, operation, ckt->CKThead[i],
ckt, data, &outNdens);
if (error) return (error);
}
}
switch (operation) {
case N_OPEN:
/* take care of the noise for the circuit as a whole */
switch (mode) {
case N_DENS:
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
SPfrontEnd->IFnewUid(ckt, &(data->namelist[data->numPlots++]),
NULL, "onoise_spectrum", UID_OTHER, NULL);
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
SPfrontEnd->IFnewUid(ckt, &(data->namelist[data->numPlots++]),
NULL, "inoise_spectrum", UID_OTHER, NULL);
/* we've added two more plots */
data->outpVector =
TMALLOC(double, data->numPlots);
data->squared_value =
data->squared ? NULL : TMALLOC(char, data->numPlots);
break;
case INT_NOIZ:
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
SPfrontEnd->IFnewUid(ckt, &(data->namelist[data->numPlots++]),
NULL, "onoise_total", UID_OTHER, NULL);
data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1);
SPfrontEnd->IFnewUid(ckt, &(data->namelist[data->numPlots++]),
NULL, "inoise_total", UID_OTHER, NULL);
/* we've added two more plots */
data->outpVector =
TMALLOC(double, data->numPlots);
data->squared_value =
data->squared ? NULL : TMALLOC(char, data->numPlots);
break;
default:
return (E_INTERN);
}
break;
case N_CALC:
switch (mode) {
case N_DENS:
if ((job->NStpsSm == 0)
|| data->prtSummary)
{
data->outpVector[data->outNumber++] = outNdens;
data->outpVector[data->outNumber++] =
(outNdens * data->GainSqInv);
refVal.rValue = data->freq; /* the reference is the freq */
if (!data->squared)
for (i = 0; i < data->outNumber; i++)
if (data->squared_value[i])
data->outpVector[i] = sqrt(data->outpVector[i]);
outData.v.numValue = data->outNumber; /* vector number */
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
SPfrontEnd->OUTpData(data->NplotPtr, &refVal, &outData);
}
break;
case INT_NOIZ:
data->outpVector[data->outNumber++] = data->outNoiz;
data->outpVector[data->outNumber++] = data->inNoise;
if (!data->squared)
for (i = 0; i < data->outNumber; i++)
if (data->squared_value[i])
data->outpVector[i] = sqrt(data->outpVector[i]);
outData.v.vec.rVec = data->outpVector; /* vector of outputs */
outData.v.numValue = data->outNumber; /* vector number */
SPfrontEnd->OUTpData(data->NplotPtr, &refVal, &outData);
break;
default:
return (E_INTERN);
}
break;
case N_CLOSE:
SPfrontEnd->OUTendPlot(data->NplotPtr);
FREE(data->namelist);
FREE(data->outpVector);
FREE(data->squared_value);
break;
default:
return (E_INTERN);
}
return (OK);
}
void
NInspIter(CKTcircuit * ckt, int posDrive, int negDrive)
{
int i;
/* clear out the right hand side vector */
for (i = 0; i <= SMPmatSize(ckt->CKTmatrix); i++) {
ckt->CKTrhs[i] = 0.0;
ckt->CKTirhs[i] = 0.0;
}
ckt->CKTrhs[posDrive] = 1.0; /* apply unit current excitation */
ckt->CKTrhs[negDrive] = -1.0;
SMPcaSolve(ckt->CKTmatrix, ckt->CKTrhs, ckt->CKTirhs, ckt->CKTrhsSpare,
ckt->CKTirhsSpare);
ckt->CKTrhs[0] = 0.0;
ckt->CKTirhs[0] = 0.0;
}
int
SPan(CKTcircuit *ckt, int restart)
{
SPAN *job = (SPAN *) ckt->CKTcurJob;
double freq;
double freqTol; /* tolerence parameter for finding final frequency */
double startdTime;
double startsTime;
double startlTime;
double startkTime;
double startTime;
int error;
int numNames;
int i;
IFuid *nameList; /* va: tmalloc'ed list of names */
IFuid freqUid;
static runDesc *spPlot = NULL;
runDesc *plot = NULL;
double* rhswoPorts = NULL;
double* irhswoPorts = NULL;
int* portPosNodes = NULL;
int* portNegNodes = NULL;
if (ckt->CKTportCount == 0)
{
fprintf(stderr, "No RF Port is present\n");
return (E_PARMVAL);
}
if (ckt->CKTAmat != NULL) freecmat(ckt->CKTAmat);
if (ckt->CKTBmat != NULL) freecmat(ckt->CKTBmat);
if (ckt->CKTSmat != NULL) freecmat(ckt->CKTSmat);
ckt->CKTAmat = newcmat(ckt->CKTportCount, ckt->CKTportCount, 0.0, 0.0);
if (ckt->CKTAmat == NULL)
return (E_NOMEM);
ckt->CKTBmat = newcmat(ckt->CKTportCount, ckt->CKTportCount, 0.0, 0.0);
if (ckt->CKTBmat == NULL)
return (3);
ckt->CKTSmat = newcmat(ckt->CKTportCount, ckt->CKTportCount, 0.0, 0.0);
if (ckt->CKTSmat == NULL)
return (E_NOMEM);
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff and anal_init and anal_type */
/* Tell the beginPlot routine what mode we're in */
// For now, let's keep this as IPC_ANAL_AC (TBD)
g_ipc.anal_type = IPC_ANAL_AC;
/* Tell the code models what mode we're in */
g_mif_info.circuit.anal_type = MIF_DC;
g_mif_info.circuit.anal_init = MIF_TRUE;
/* gtri - end - wbk */
#endif
/* start at beginning */
if (job->SPsaveFreq == 0 || restart) {
if (job->SPnumberSteps < 1)
job->SPnumberSteps = 1;
switch (job->SPstepType) {
case DECADE:
if (job->SPstartFreq <= 0) {
fprintf(stderr, "ERROR: AC startfreq <= 0\n");
return E_PARMVAL;
}
job->SPfreqDelta =
exp(log(10.0)/job->SPnumberSteps);
break;
case OCTAVE:
if (job->SPstartFreq <= 0) {
fprintf(stderr, "ERROR: AC startfreq <= 0\n");
return E_PARMVAL;
}
job->SPfreqDelta =
exp(log(2.0)/job->SPnumberSteps);
break;
case LINEAR:
if (job->SPnumberSteps-1 > 1)
job->SPfreqDelta =
(job->SPstopFreq -
job->SPstartFreq) /
(job->SPnumberSteps - 1);
else
/* Patch from: Richard McRoberts
* This patch is for a rather pathological case:
* a linear step with only one point */
job->SPfreqDelta = 0;
break;
default:
return(E_BADPARM);
}
#ifdef XSPICE
/* gtri - begin - wbk - 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 */
if (!ckt->CKTnoopac) { /* skip OP if option NOOPAC is set and circuit is linear */
error = CKTop(ckt,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT,
(ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT,
ckt->CKTdcMaxIter);
if(error){
fprintf(stdout,"\nAC operating point failed -\n");
CKTncDump(ckt);
return(error);
}
}
else
fprintf(stdout,"\n Linear circuit, option noopac given: no OP analysis\n");
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Add IPC stuff */
/* Send the operating point results for Mspice compatibility */
if(g_ipc.enabled)
{
/* Call CKTnames to get names of nodes/branches used by
BeginPlot */
/* Probably should free nameList after this block since
called again... */
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
/* We have to do a beginPlot here since the data to return is
* different for the DCOP than it is for the AC analysis.
* Moreover the begin plot has not even been done yet at this
* point...
*/
SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,
NULL, IF_REAL,
numNames, nameList, IF_REAL,
&spPlot);
txfree(nameList);
ipc_send_dcop_prefix();
CKTdump(ckt, 0.0, spPlot);
ipc_send_dcop_suffix();
SPfrontEnd->OUTendPlot (spPlot);
}
/* gtri - end - wbk */
#endif
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if(error) return(error);
error = CKTnames(ckt,&numNames,&nameList);
if(error) return(error);
if (ckt->CKTkeepOpInfo) {
/* Dump operating point. */
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
"AC Operating Point",
NULL, IF_REAL,
numNames, nameList, IF_REAL,
&plot);
if(error) return(error);
CKTdump(ckt, 0.0, plot);
SPfrontEnd->OUTendPlot (plot);
plot = NULL;
}
unsigned int extraSPdataLength = ckt->CKTportCount * ckt->CKTportCount;
nameList = (IFuid*)TREALLOC(IFuid, nameList, numNames + extraSPdataLength);
// Create UIDs
for (unsigned int dest = 1; dest <= ckt->CKTportCount; dest++)
for (unsigned int j = 1; j <= ckt->CKTportCount; j++)
{
char tmpBuf[32];
sprintf(tmpBuf, "S_%d_%d", dest, j);
SPfrontEnd->IFnewUid(ckt, &(nameList[numNames++]), NULL, tmpBuf, UID_OTHER, NULL);
}
SPfrontEnd->IFnewUid (ckt, &freqUid, NULL, "frequency", UID_OTHER, NULL);
error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob,
ckt->CKTcurJob->JOBname,
freqUid, IF_REAL,
numNames, nameList, IF_COMPLEX,
&spPlot);
tfree(nameList);
if(error) return(error);
if (job->SPstepType != LINEAR) {
SPfrontEnd->OUTattributes (spPlot, NULL, OUT_SCALE_LOG, NULL);
}
freq = job->SPstartFreq;
} else { /* continue previous analysis */
freq = job->SPsaveFreq;
job->SPsaveFreq = 0; /* clear the 'old' frequency */
/* fix resume? saj, indeed !*/
error = SPfrontEnd->OUTpBeginPlot (NULL, NULL,
NULL,
NULL, 0,
666, NULL, 666,
&spPlot);
/* saj*/
}
switch (job->SPstepType) {
case DECADE:
case OCTAVE:
freqTol = job->SPfreqDelta *
job->SPstopFreq * ckt->CKTreltol;
break;
case LINEAR:
freqTol = job->SPfreqDelta * ckt->CKTreltol;
break;
default:
return(E_BADPARM);
}
#ifdef XSPICE
/* gtri - add - wbk - 12/19/90 - Set anal_init and anal_type */
g_mif_info.circuit.anal_init = MIF_TRUE;
/* Tell the code models what mode we're in */
g_mif_info.circuit.anal_type = MIF_AC;
/* gtri - end - wbk */
#endif
INIT_STATS();
ckt->CKTcurrentAnalysis = DOING_AC;
ckt->CKTactivePort = 0;
/* main loop through all scheduled frequencies */
while (freq <= job->SPstopFreq + freqTol) {
unsigned int activePort = 0;
//
if (SPfrontEnd->IFpauseTest()) {
/* user asked us to pause via an interrupt */
job->SPsaveFreq = freq;
return(E_PAUSE);
}
ckt->CKTomega = 2.0 * M_PI * freq;
/* Update opertating point, if variable 'hertz' is given */
if (ckt->CKTvarHertz) {
#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(stdout, "\nAC operating point failed -\n");
CKTncDump(ckt);
return(error);
}
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
error = CKTload(ckt);
if (error) return(error);
}
// Let's sweep thru all available ports to build Y matrix
// Y_ij = I_i / V_j | V_k!=j = 0
// (we have only to modify rhs)
int vsrcLookupType = CKTtypelook("Vsource");
int vsrcRoot = -1;
// Get VSRCs root model
if (ckt->CKTVSRCid == -1)
{
for (i = 0; i < DEVmaxnum; i++) {
if (DEVices[i] && DEVices[i]->DEVacLoad && ckt->CKThead[i] && ckt->CKThead[i]->GENmodType == vsrcLookupType) {
vsrcRoot = i;
break;
}
}
if (vsrcRoot == -1)
return (E_NOMOD);
ckt->CKTVSRCid = vsrcRoot;
}
else
vsrcRoot = ckt->CKTVSRCid;
if (rhswoPorts == NULL)
rhswoPorts = (double*)TREALLOC(double, rhswoPorts, ckt->CKTmaxEqNum);
if (irhswoPorts == NULL)
irhswoPorts = (double*)TREALLOC(double, irhswoPorts, ckt->CKTmaxEqNum);
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODESP;
// Pre-load everything but RF Ports (these will be updated in the next cycle).
error = NIspPreload(ckt);
if (error) return (error);
// error = VSRCsaveNPData(ckt->CKThead[vsrcRoot]);
// if (error) return (error);
//Keep a backup copy
memcpy(rhswoPorts, ckt->CKTrhs, ckt->CKTmaxEqNum * sizeof(double));
memcpy(rhswoPorts, ckt->CKTirhs, ckt->CKTmaxEqNum * sizeof(double));
for (activePort = 1; activePort <= ckt->CKTportCount; activePort++)
{
// Copy the backup RHS into CKT's RHS
memcpy(ckt->CKTrhs, rhswoPorts, ckt->CKTmaxEqNum * sizeof(double));
memcpy(ckt->CKTirhs, irhswoPorts, ckt->CKTmaxEqNum * sizeof(double));
ckt->CKTactivePort = activePort;
// Update only VSRCs
error = VSRCspupdate(ckt->CKThead[vsrcRoot], ckt);
if (error)
{
tfree(rhswoPorts);
tfree(irhswoPorts);
return(error);
}
error = NIspSolve(ckt);
if (error) {
tfree(rhswoPorts);
tfree(irhswoPorts);
UPDATE_STATS(DOING_AC);
return(error);
}
#ifdef WANT_SENSE2
if (ckt->CKTsenInfo && (ckt->CKTsenInfo->SENmode & ACSEN)) {
long save;
int save1;
save = ckt->CKTmode;
ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG;
save1 = ckt->CKTsenInfo->SENmode;
ckt->CKTsenInfo->SENmode = ACSEN;
if (freq == job->SPstartFreq) {
ckt->CKTsenInfo->SENacpertflag = 1;
}
else {
ckt->CKTsenInfo->SENacpertflag = 0;
}
error = CKTsenAC(ckt);
if (error)
return (error);
ckt->CKTmode = save;
ckt->CKTsenInfo->SENmode = save1;
}
#endif
// We have done 1 activated port.
error = CKTspCalcPowerWave(ckt);
} //active ports cycle
// Now we can calculate the full S-Matrix
CKTspCalcSMatrix(ckt);
#ifdef XSPICE
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
if (g_ipc.enabled)
ipc_send_data_prefix(freq);
error = CKTspDump(ckt, freq, spPlot);
if (g_ipc.enabled)
ipc_send_data_suffix();
/* gtri - modify - wbk - 12/19/90 - Send IPC stuff */
#else
error = CKTspDump(ckt, freq, acPlot);
#endif
if (error) {
UPDATE_STATS(DOING_AC);
tfree(rhswoPorts);
tfree(irhswoPorts);
return(error);
}
/*
* Now go with noise cycle, if required
*/
#ifdef NOISE_AVAILABLE
// To be completed
if (job->SPdoNoise)
{
if (portPosNodes == NULL)
{
portPosNodes = TMALLOC(int, ckt->CKTportCount);
portNegNodes = TMALLOC(int, ckt->CKTportCount);
VSRCgetActivePortNodes(ckt->CKThead[vsrcRoot], ckt, portPosNodes, portNegNodes);
}
static Ndata* data;
double realVal;
double imagVal;
int error;
int posOutNode;
int negOutNode;
//Keep a backup copy
memcpy(rhswoPorts, ckt->CKTrhs, ckt->CKTmaxEqNum * sizeof(double));
memcpy(rhswoPorts, ckt->CKTirhs, ckt->CKTmaxEqNum * sizeof(double));
for (activePort = 0; activePort < ckt->CKTportCount; activePort++)
{
/* the frequency will NOT be stored in array[0] as before; instead,
* it will be given in refVal.rValue (see later)
*/
// Copy the backup RHS into CKT's RHS
memcpy(ckt->CKTrhs, rhswoPorts, ckt->CKTmaxEqNum * sizeof(double));
memcpy(ckt->CKTirhs, irhswoPorts, ckt->CKTmaxEqNum * sizeof(double));
ckt->CKTactivePort = activePort+1;
posOutNode = portPosNodes[activePort];
negOutNode = portNegNodes[activePort];
NInspIter(ckt, posOutNode, negOutNode); /* solve the adjoint system */
/* now we use the adjoint system to calculate the noise
* contributions of each generator in the circuit
*/
error = CKTspnoise(ckt, N_DENS, N_CALC, data);
if (error)
{
tfree(portPosNodes); tfree(portNegNodes);
return(error);
}
}
}
#endif
/* increment frequency */
switch (job->SPstepType) {
case DECADE:
case OCTAVE:
/* inserted again 14.12.2001 */
#ifdef HAS_PROGREP
{
double endfreq = job->SPstopFreq;
double startfreq = job->SPstartFreq;
endfreq = log(endfreq);
if (startfreq == 0.0)
startfreq = 1e-12;
startfreq = log(startfreq);
if (freq > 0.0)
SetAnalyse("sp", (int)((log(freq) - startfreq) * 1000.0 / (endfreq - startfreq)));
}
#endif
freq *= job->SPfreqDelta;
if (job->SPfreqDelta == 1) goto endsweep;
break;
case LINEAR:
#ifdef HAS_PROGREP
{
double endfreq = job->SPstopFreq;
double startfreq = job->SPstartFreq;
SetAnalyse("sp", (int)((freq - startfreq) * 1000.0 / (endfreq - startfreq)));
}
#endif
freq += job->SPfreqDelta;
if (job->SPfreqDelta == 0) goto endsweep;
break;
default:
tfree(rhswoPorts);
tfree(irhswoPorts);
tfree(portPosNodes); tfree(portNegNodes);
return(E_INTERN);
}
}
endsweep:
SPfrontEnd->OUTendPlot (spPlot);
spPlot = NULL;
UPDATE_STATS(0);
tfree(rhswoPorts);
tfree(irhswoPorts);
tfree(portPosNodes); tfree(portNegNodes);
return(0);
}
#endif

73
src/spicelib/analysis/spaskq.c

@ -0,0 +1,73 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
/*
*/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/spdefs.h"
#include "ngspice/cktdefs.h"
/* ARGSUSED */
int
SPaskQuest(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value)
{
SPAN *job = (SPAN *) anal;
NG_IGNORE(ckt);
switch(which) {
case SP_START:
value->rValue = job->SPstartFreq;
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;
break;
default:
return(E_BADPARM);
}
return(OK);
}

114
src/spicelib/analysis/spsetp.c

@ -0,0 +1,114 @@
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "ngspice/iferrmsg.h"
#include "ngspice/spdefs.h"
#include "ngspice/cktdefs.h"
#include "analysis.h"
/* ARGSUSED */
int
SPsetParm(CKTcircuit *ckt, JOB *anal, int which, IFvalue *value)
{
SPAN *job = (SPAN *) anal;
NG_IGNORE(ckt);
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;
}
}
break;
case SP_OCT:
if(value->iValue) {
job->SPstepType = OCTAVE;
} else {
if (job->SPstepType == OCTAVE) {
job->SPstepType = 0;
}
}
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);
}
return(OK);
}
static IFparm SPparms[] = {
{ "start", SP_START, IF_SET|IF_ASK|IF_REAL, "starting frequency" },
{ "stop", SP_STOP, IF_SET|IF_ASK|IF_REAL, "ending frequency" },
{ "numsteps", SP_STEPS,IF_SET|IF_ASK|IF_INTEGER, "number of frequencies"},
{ "dec", SP_DEC, IF_SET|IF_FLAG, "step by decades" },
{ "oct", SP_OCT, IF_SET|IF_FLAG, "step by octaves" },
{ "lin", SP_LIN, IF_SET|IF_FLAG, "step linearly" },
{"donoise", SP_DONOISE, IF_SET | IF_FLAG | IF_INTEGER, "do SP noise"}
};
SPICEanalysis SPinfo = {
{
"SP",
"S-Parameters analysis",
NUMELEMS(SPparms),
SPparms
},
sizeof(SPAN),
FREQUENCYDOMAIN,
1,
SPsetParm,
SPaskQuest,
NULL,
SPan
};

9
src/spicelib/devices/cktinit.c

@ -134,5 +134,14 @@ CKTinit(CKTcircuit **ckt) /* new circuit to create */
g_mif_info.auto_partial.local = MIF_FALSE; g_mif_info.auto_partial.local = MIF_FALSE;
/* gtri - end - wbk - 01/12/91 */ /* gtri - end - wbk - 01/12/91 */
#endif #endif
#ifdef RFSPICE
sckt->CKTportCount = 0;
sckt->CKTactivePort = 0;
sckt->CKTVSRCid = -1;
sckt->CKTrfPorts = NULL;
sckt->CKTSmat = sckt->CKTAmat = sckt->CKTBmat = sckt->CKTYmat = sckt->CKTZmat = NULL;
#endif
return OK; return OK;
} }

7
src/spicelib/devices/vsrc/vsrc.c

@ -25,6 +25,13 @@ IFparm VSRCpTable[] = { /* parameters */
IOP ("trrandom", VSRC_TRRANDOM, IF_REALVEC,"random source description"), IOP ("trrandom", VSRC_TRRANDOM, IF_REALVEC,"random source description"),
#ifdef SHARED_MODULE #ifdef SHARED_MODULE
IOP ("external", VSRC_EXTERNAL, IF_STRING,"external source description"), IOP ("external", VSRC_EXTERNAL, IF_STRING,"external source description"),
#endif
#ifdef RFSPICE
IOP("portnum", VSRC_PORTNUM, IF_INTEGER,"Port index"),
IOP("z0", VSRC_PORTZ0, IF_REAL, "Port impedance"),
IOP("pwr", VSRC_PORTPWR, IF_REAL, "Port Power"),
IOP("freq", VSRC_PORTFREQ, IF_REAL, "Port frequency"),
IOP("phase", VSRC_PORTPHASE, IF_REAL, "Phase of the source"),
#endif #endif
OPU ("pos_node",VSRC_POS_NODE, IF_INTEGER,"Positive node of source"), OPU ("pos_node",VSRC_POS_NODE, IF_INTEGER,"Positive node of source"),
OPU ("neg_node",VSRC_NEG_NODE, IF_INTEGER,"Negative node of source"), OPU ("neg_node",VSRC_NEG_NODE, IF_INTEGER,"Negative node of source"),

136
src/spicelib/devices/vsrc/vsrcacld.c

@ -9,40 +9,150 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/sperror.h" #include "ngspice/sperror.h"
#include "ngspice/suffix.h" #include "ngspice/suffix.h"
#ifdef RFSPICE
int VSRCspupdate(GENmodel* inModel, CKTcircuit* ckt)
{
if (!(ckt->CKTmode & MODESP))
return (OK);
VSRCmodel* model = (VSRCmodel*)inModel;
VSRCinstance* here;
for (; model != NULL; model = VSRCnextModel(model)) {
/* loop through all the instances of the model */
for (here = VSRCinstances(model); here != NULL;
here = VSRCnextInstance(here)) {
if (here->VSRCisPort)
{
double acReal = here->VSRCportNum == ckt->CKTactivePort ? 1.0 : 0.0;
*(ckt->CKTrhs + (here->VSRCbranch)) += acReal;
}
}
}
return (OK);
}
int VSRCgetActivePortNodes(GENmodel* inModel, CKTcircuit* ckt, int* posNodes, int* negNodes)
{
if (!(ckt->CKTmode & MODESP))
return (OK);
for (int n = 0; n < ckt->CKTportCount; n++)
posNodes[n] = negNodes[n] = 0;
VSRCmodel* model = (VSRCmodel*)inModel;
VSRCinstance* here;
for (; model != NULL; model = VSRCnextModel(model)) {
/* loop through all the instances of the model */
for (here = VSRCinstances(model); here != NULL;
here = VSRCnextInstance(here)) {
if (here->VSRCisPort)
{
int id = here->VSRCportNum - 1;
posNodes[id] = here->VSRCposNode;
negNodes[id] = here->VSRCnegNode;
}
}
}
return (OK);
}
#endif
int int
VSRCacLoad(GENmodel *inModel, CKTcircuit *ckt)
VSRCacLoad(GENmodel* inModel, CKTcircuit* ckt)
{ {
VSRCmodel *model = (VSRCmodel *) inModel;
VSRCinstance *here;
VSRCmodel* model = (VSRCmodel*)inModel;
VSRCinstance* here;
for( ; model != NULL; model = VSRCnextModel(model)) {
for (; model != NULL; model = VSRCnextModel(model)) {
/* loop through all the instances of the model */ /* loop through all the instances of the model */
for (here = VSRCinstances(model); here != NULL ;
here=VSRCnextInstance(here)) {
for (here = VSRCinstances(model); here != NULL;
here = VSRCnextInstance(here)) {
double acReal, acImag; double acReal, acImag;
#ifdef RFSPICE
double g0;
g0 = 0;
acReal = 0.0;
acImag = 0.0;
/*
* TBD: Verify that MODESPNOISE require also noise from source port
* In any case, activate only the required noise input to build
* noise matrix properly
*/
if ((ckt->CKTmode & MODEACNOISE) || (ckt->CKTmode & MODESPNOISE))
{
if ((GENinstance*)here == ckt->noise_input) {
acReal = 1.0;
acImag = 0.0;
}
}
else
if (ckt->CKTmode & MODESP) // In SP Analysis, shut down all AC sources off except the current port
{
// During SP load, no port must excite the circuit before the SPAN procedure.
// They will be turned on & off in the inner cycle of SPAN.
// Also, AC Source must be switched off (<--- Check this against ADS).
{
acReal = 0.0;
acImag = 0.0;
}
}
else // AC Analysis
{
/*
* For AC analysis, AC mag is leading parameter for ports.
*/
acReal = here->VSRCacReal;
acImag = here->VSRCacImag;
};
*(here->VSRCposIbrPtr) += 1.0;
*(here->VSRCnegIbrPtr) -= 1.0;
*(here->VSRCibrPosPtr) += 1.0;
*(here->VSRCibrNegPtr) -= 1.0;
*(ckt->CKTrhs + (here->VSRCbranch)) += acReal;
*(ckt->CKTirhs + (here->VSRCbranch)) += acImag;
if (here->VSRCisPort)
{
g0 = here->VSRCportY0;
*(here->VSRCposPosPtr) += g0;
*(here->VSRCnegNegPtr) += g0;
*(here->VSRCposNegPtr) -= g0;
*(here->VSRCnegPosPtr) -= g0;
}
#else
if (ckt->CKTmode & MODEACNOISE) { if (ckt->CKTmode & MODEACNOISE) {
if ((GENinstance *) here == ckt->noise_input) {
if ((GENinstance*)here == ckt->noise_input) {
acReal = 1.0; acReal = 1.0;
acImag = 0.0; acImag = 0.0;
} else {
}
else {
acReal = 0.0; acReal = 0.0;
acImag = 0.0; acImag = 0.0;
} }
} else {
}
else {
acReal = here->VSRCacReal; acReal = here->VSRCacReal;
acImag = here->VSRCacImag; acImag = here->VSRCacImag;
} }
*(here->VSRCposIbrPtr) += 1.0 ;
*(here->VSRCnegIbrPtr) -= 1.0 ;
*(here->VSRCibrPosPtr) += 1.0 ;
*(here->VSRCibrNegPtr) -= 1.0 ;
*(here->VSRCposIbrPtr) += 1.0;
*(here->VSRCnegIbrPtr) -= 1.0;
*(here->VSRCibrPosPtr) += 1.0;
*(here->VSRCibrNegPtr) -= 1.0;
*(ckt->CKTrhs + (here->VSRCbranch)) += acReal; *(ckt->CKTrhs + (here->VSRCbranch)) += acReal;
*(ckt->CKTirhs + (here->VSRCbranch)) += acImag; *(ckt->CKTirhs + (here->VSRCbranch)) += acImag;
#endif
} }
} }

17
src/spicelib/devices/vsrc/vsrcask.c

@ -110,6 +110,23 @@ VSRCask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, IFvalue *
*(ckt->CKTrhsOld + here->VSRCbranch); *(ckt->CKTrhsOld + here->VSRCbranch);
} }
return(OK); return(OK);
#ifdef RFSPICE
case VSRC_PORTNUM:
value->rValue = here->VSRCportNum;
return (OK);
case VSRC_PORTZ0:
value->rValue = here->VSRCportZ0;
return (OK);
case VSRC_PORTPWR:
value->rValue = here->VSRCportPower;
return (OK);
case VSRC_PORTFREQ:
value->rValue = here->VSRCportFreq;
return (OK);
case VSRC_PORTPHASE:
value->rValue = here->VSRCportPhase;
return (OK);
#endif
#ifdef SHARED_MODULE #ifdef SHARED_MODULE
case VSRC_EXTERNAL: case VSRC_EXTERNAL:
/* Don't do anything */ /* Don't do anything */

44
src/spicelib/devices/vsrc/vsrcdefs.h

@ -32,6 +32,19 @@ typedef struct sVSRCinstance {
const int VSRCposNode; /* number of positive node of source */ const int VSRCposNode; /* number of positive node of source */
const int VSRCnegNode; /* number of negative node of source */ const int VSRCnegNode; /* number of negative node of source */
#ifdef RFSPICE
int VSRCresNode; /* number of internal node of source (ZSeries) */
double* VSRCposPosPtr; /* pointer to sparse matrix diagonal at
* (positive,positive) */
double* VSRCnegNegPtr; /* pointer to sparse matrix diagonal at
* (negative,negative) */
double* VSRCposNegPtr; /* pointer to sparse matrix offdiagonal at
* (positive,negative) */
double* VSRCnegPosPtr; /* pointer to sparse matrix offdiagonal at
* (negative,positive) */
#endif
int VSRCbranch; /* equation number of branch equation added for source */ int VSRCbranch; /* equation number of branch equation added for source */
int VSRCfunctionType; /* code number of function type for source */ int VSRCfunctionType; /* code number of function type for source */
@ -77,6 +90,24 @@ typedef struct sVSRCinstance {
unsigned VSRCdF1given :1 ; /* flag to indicate source is an f1 distortion input */ unsigned VSRCdF1given :1 ; /* flag to indicate source is an f1 distortion input */
unsigned VSRCdF2given :1 ; /* flag to indicate source is an f2 distortion input */ unsigned VSRCdF2given :1 ; /* flag to indicate source is an f2 distortion input */
unsigned VSRCrGiven :1 ; /* flag to indicate repeating pwl */ unsigned VSRCrGiven :1 ; /* flag to indicate repeating pwl */
#ifdef RFSPICE
unsigned VSRCportNumGiven : 1; /* Flag to indicate Port Num is given */
unsigned VSRCportZ0Given : 1; /* Flag to indicate Port Z0 is given */
unsigned VSRCportPowerGiven : 1; /* Flag to indicate Port Power is given*/
unsigned VSRCportFreqGiven : 1; /* Flag to indicate Port Frequency is given*/
unsigned VSRCportPhaseGiven : 1; /* Flag to indicate Port Phase is given*/
unsigned VSRCisPort : 1; /* Flag indicating if this is a port*/
double VSRCVAmplitude; /* Support variable: Open Circuit Port Voltage */
double VSRC2pifreq; /* Calculate 2*pi*freq once */
unsigned int VSRCportNum; /* Port index*/
double VSRCportZ0; /* Port internal impedance*/
double VSRCportY0; /* Port internal admittance*/
double VSRCportPower; /* Port power (W) for HB analysis */
double VSRCportFreq; /* Port frequency */
double VSRCportPhase; /* Port Initial Phase */
double VSRCportPhaseRad; /* Port Initial Phase (rad) */
double VSRCki; /* Normalization Factor for Kurosawa power wave*/
#endif
} VSRCinstance ; } VSRCinstance ;
@ -105,7 +136,11 @@ enum {
AM, AM,
TRNOISE, TRNOISE,
TRRANDOM, TRRANDOM,
EXTERNAL,
EXTERNAL
#ifdef RFSPICE
,
PORT
#endif
}; };
#endif #endif
@ -136,6 +171,13 @@ enum {
VSRC_AM, VSRC_AM,
VSRC_R, VSRC_R,
VSRC_TD, VSRC_TD,
#ifdef RFSPICE
VSRC_PORTNUM,
VSRC_PORTZ0,
VSRC_PORTFREQ,
VSRC_PORTPWR,
VSRC_PORTPHASE,
#endif
VSRC_TRNOISE, VSRC_TRNOISE,
VSRC_TRRANDOM, VSRC_TRRANDOM,
VSRC_EXTERNAL, VSRC_EXTERNAL,

4
src/spicelib/devices/vsrc/vsrcext.h

@ -16,3 +16,7 @@ extern int VSRCsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int VSRCunsetup(GENmodel*,CKTcircuit*); extern int VSRCunsetup(GENmodel*,CKTcircuit*);
extern int VSRCpzSetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int VSRCpzSetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int VSRCtemp(GENmodel*,CKTcircuit*); extern int VSRCtemp(GENmodel*,CKTcircuit*);
#ifdef RFSPICE
extern int VSRCspupdate(GENmodel*, CKTcircuit*);
extern int VSRCgetActivePortNodes(GENmodel* inModel, CKTcircuit* ckt, int* posNodes, int* negNodes);
#endif

41
src/spicelib/devices/vsrc/vsrcload.c

@ -40,10 +40,36 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
for (here = VSRCinstances(model); here != NULL ; for (here = VSRCinstances(model); here != NULL ;
here=VSRCnextInstance(here)) { here=VSRCnextInstance(here)) {
*(here->VSRCposIbrPtr) += 1.0 ;
*(here->VSRCnegIbrPtr) -= 1.0 ;
*(here->VSRCibrPosPtr) += 1.0 ;
*(here->VSRCibrNegPtr) -= 1.0 ;
#ifndef RFSPICE
*(here->VSRCposIbrPtr) += 1.0;
*(here->VSRCnegIbrPtr) -= 1.0;
*(here->VSRCibrPosPtr) += 1.0;
*(here->VSRCibrNegPtr) -= 1.0;
#else
if (here->VSRCisPort)
{
// here->VSRCcurrent = (*(ckt->CKTrhs[Old] + (here->VSRCbranch))
*(here->VSRCposIbrPtr) += 1.0;
*(here->VSRCnegIbrPtr) -= 1.0;
*(here->VSRCibrPosPtr) += 1.0;
*(here->VSRCibrNegPtr) -= 1.0;
double g0 = here->VSRCportY0;
*(here->VSRCposPosPtr) += g0;
*(here->VSRCnegNegPtr) += g0;
*(here->VSRCposNegPtr) -= g0;
*(here->VSRCnegPosPtr) -= g0;
}
else
{
*(here->VSRCposIbrPtr) += 1.0;
*(here->VSRCnegIbrPtr) -= 1.0;
*(here->VSRCibrPosPtr) += 1.0;
*(here->VSRCibrNegPtr) -= 1.0;
}
#endif
if( (ckt->CKTmode & (MODEDCOP | MODEDCTRANCURVE)) && if( (ckt->CKTmode & (MODEDCOP | MODEDCTRANCURVE)) &&
here->VSRCdcGiven ) { here->VSRCdcGiven ) {
/* load using DC value */ /* load using DC value */
@ -367,6 +393,13 @@ VNoi3 3 0 DC 0 TRNOISE(0 0 0 0 15m 22u 50u) : generate RTS noise
} }
break; break;
#endif #endif
#ifdef RFSPICE
case PORT:
{
value += here->VSRCVAmplitude * cos(time * here->VSRC2pifreq);
}
#endif
} // switch } // switch
} // else (line 48) } // else (line 48)

45
src/spicelib/devices/vsrc/vsrcpar.c

@ -288,7 +288,52 @@ VSRCparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
} }
break; break;
#endif #endif
#ifdef RFSPICE
/*
* NB If either Freq or Power are given, the Function type is overridden
* If not, we have a passive port: can be used for AC/SP/Noise but the time
* domain value is given by preceding Function definition (if present).
*/
case VSRC_PORTNUM:
{
here->VSRCportNum = value->iValue;
here->VSRCportNumGiven = TRUE;
here->VSRCisPort = ((here->VSRCportNumGiven) & (here->VSRCportNum > 0) & (here->VSRCportZ0 > 0.0));
break;
}
case VSRC_PORTZ0:
{
here->VSRCportZ0 = value->rValue;
here->VSRCVAmplitude = sqrt(here->VSRCportPower * 4.0 * here->VSRCportZ0);
here->VSRCisPort = ((here->VSRCportNumGiven) & (here->VSRCportNum > 0) & (here->VSRCportZ0 > 0.0));
here->VSRCportZ0Given = TRUE;
break;
}
case VSRC_PORTPWR:
{
here->VSRCportPower = value->rValue;
here->VSRCportPowerGiven = TRUE;
here->VSRCfunctionType = PORT;
break;
}
case VSRC_PORTFREQ:
{
here->VSRCportFreq = value->rValue;
here->VSRCportFreqGiven = TRUE;
here->VSRCfunctionType = PORT;
break;
}
case VSRC_PORTPHASE:
{
here->VSRCportPhase = value->rValue;
here->VSRCportPhaseGiven = TRUE;
}
break;
#endif
default: default:
return(E_BADPARM); return(E_BADPARM);
} }

43
src/spicelib/devices/vsrc/vsrcset.c

@ -49,10 +49,47 @@ do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
return(E_NOMEM);\ return(E_NOMEM);\
} } while(0) } } while(0)
#ifdef RFSPICE
if (here->VSRCisPort)
{
error = CKTmkVolt(ckt, &tmp, here->VSRCname, "res");
if (error) return(error);
here->VSRCresNode = tmp->number;
if (ckt->CKTcopyNodesets) {
CKTnode* tmpNode;
IFuid tmpName;
if (CKTinst2Node(ckt, here, 1, &tmpNode, &tmpName) == OK) {
if (tmpNode->nsGiven) {
tmp->nodeset = tmpNode->nodeset;
tmp->nsGiven = tmpNode->nsGiven;
}
}
}
TSTALLOC(VSRCposPosPtr, VSRCposNode, VSRCposNode);
TSTALLOC(VSRCnegNegPtr, VSRCresNode, VSRCresNode);
TSTALLOC(VSRCposNegPtr, VSRCposNode, VSRCresNode);
TSTALLOC(VSRCnegPosPtr, VSRCresNode, VSRCposNode);
TSTALLOC(VSRCposIbrPtr, VSRCresNode, VSRCbranch);
TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch);
TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode);
TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCresNode);
}
else
{
TSTALLOC(VSRCposIbrPtr, VSRCposNode, VSRCbranch);
TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch);
TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode);
TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode);
}
#else
TSTALLOC(VSRCposIbrPtr, VSRCposNode, VSRCbranch); TSTALLOC(VSRCposIbrPtr, VSRCposNode, VSRCbranch);
TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch); TSTALLOC(VSRCnegIbrPtr, VSRCnegNode, VSRCbranch);
TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode); TSTALLOC(VSRCibrNegPtr, VSRCbranch, VSRCnegNode);
TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode); TSTALLOC(VSRCibrPosPtr, VSRCbranch, VSRCposNode);
#endif
} }
} }
return(OK); return(OK);
@ -73,6 +110,12 @@ VSRCunsetup(GENmodel *inModel, CKTcircuit *ckt)
if (here->VSRCbranch > 0) if (here->VSRCbranch > 0)
CKTdltNNum(ckt, here->VSRCbranch); CKTdltNNum(ckt, here->VSRCbranch);
here->VSRCbranch = 0; here->VSRCbranch = 0;
#ifdef RFSPICE
if ((here->VSRCresNode > 0) & (here->VSRCisPort))
CKTdltNNum(ckt, here->VSRCresNode);
here->VSRCresNode = 0;
#endif
} }
} }
return OK; return OK;

90
src/spicelib/devices/vsrc/vsrctemp.c

@ -22,6 +22,12 @@ VSRCtemp(GENmodel *inModel, CKTcircuit *ckt)
NG_IGNORE(ckt); NG_IGNORE(ckt);
#ifdef RFSPICE
ckt->CKTportCount = 0;
unsigned int* portIDs;
unsigned int prevPort;
#endif
/* loop through all the voltage source models */ /* loop through all the voltage source models */
for( ; model != NULL; model = VSRCnextModel(model)) { for( ; model != NULL; model = VSRCnextModel(model)) {
@ -50,8 +56,92 @@ VSRCtemp(GENmodel *inModel, CKTcircuit *ckt)
radians = here->VSRCacPhase * M_PI / 180.0; radians = here->VSRCacPhase * M_PI / 180.0;
here->VSRCacReal = here->VSRCacMag * cos(radians); here->VSRCacReal = here->VSRCacMag * cos(radians);
here->VSRCacImag = here->VSRCacMag * sin(radians); here->VSRCacImag = here->VSRCacMag * sin(radians);
#ifdef RFSPICE
// To have a power port, we need to define its index value
// AND a proper port impedance
if (here->VSRCportNumGiven)
{
if (!here->VSRCportZ0Given)
here->VSRCportZ0 = 50.0;
here->VSRCisPort = here->VSRCportZ0 > 0.0;
}
else
here->VSRCisPort = FALSE;
if (here->VSRCisPort)
{
if (!here->VSRCportFreqGiven)
here->VSRCportFreq = 1.0e9;
if (!here->VSRCportPowerGiven)
here->VSRCportPower = 0.001; // 1mW (0dBm) default RF power
if (!here->VSRCportPhaseGiven)
here->VSRCportPhase = 0.0;
here->VSRC2pifreq = 2.0 * M_PI * here->VSRCportFreq;
here->VSRCVAmplitude = sqrt(here->VSRCportPower * 4.0 * here->VSRCportZ0);
here->VSRCportY0 = 1.0 / here->VSRCportZ0;
here->VSRCportPhaseRad = here->VSRCportPhase * M_PI / 180.0;
here->VSRCki = 0.5 / sqrt(here->VSRCportZ0);
ckt->CKTportCount++;
ckt->CKTrfPorts = (GENinstance**)TREALLOC(GENinstance*, ckt->CKTrfPorts, ckt->CKTportCount);
ckt->CKTrfPorts[ckt->CKTportCount - 1] = (GENinstance*)here;
}
#endif
}
}
#ifdef RFSPICE
portIDs = (unsigned int*)malloc(ckt->CKTportCount * sizeof(unsigned int));
if (portIDs == NULL)
return (E_NOMEM);
unsigned int curport = 0;
// Sweep thru all ports to check for correct indexing
/* loop through all the voltage source models */
for (model = (VSRCmodel*)inModel; model != NULL; model = VSRCnextModel(model)) {
/* loop through all the instances of the model */
for (here = VSRCinstances(model); here != NULL;
here = VSRCnextInstance(here)) {
if (!here->VSRCisPort) continue;
unsigned int curId = here->VSRCportNum;
// If port Index > port Count then we have either a duplicate number or a missing number
if (curId > ckt->CKTportCount)
{
SPfrontEnd->IFerrorf(ERR_FATAL,
"%s: incorrect port ordering",
here->VSRCname);
free(portIDs);
return (E_BADPARM);
}
// Check if we have already defined the "curId"
for (prevPort = 0; prevPort < curport; prevPort++)
{
if (portIDs[prevPort] == curId)
{
SPfrontEnd->IFerrorf(ERR_FATAL,
"%s: duplicate port Index",
here->VSRCname);
free(portIDs);
return (E_BADPARM);
}
}
portIDs[curport++] = curId;
} }
} }
free(portIDs);
#endif
return(OK); return(OK);
} }

114
src/spicelib/parser/inp2dot.c

@ -614,6 +614,106 @@ dot_pss(char *line, void *ckt, INPtables *tab, struct card *current,
/* SP */ /* SP */
#endif #endif
#ifdef RFSPICE
/* S Parameter Analyis */
static int
dot_sp(char* line, void* ckt, INPtables* tab, struct card* current,
void* task, void* gnode, JOB* foo)
{
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue* parm; /* a pointer to a value struct for function returns */
int which; /* which analysis we are performing */
char* steptype; /* ac analysis, type of stepping function */
NG_IGNORE(gnode);
/* .ac {DEC OCT LIN} NP FSTART FSTOP */
which = ft_find_analysis("SP");
if (which == -1) {
LITERR("S-Params analysis unsupported.\n");
return (0);
}
IFC(newAnalysis, (ckt, which, "SP Analysis", &foo, task));
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
ptemp.iValue = 1;
GCA(INPapName, (ckt, which, foo, steptype, &ptemp));
tfree(steptype);
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */
GCA(INPapName, (ckt, which, foo, "numsteps", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
GCA(INPapName, (ckt, which, foo, "start", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */
GCA(INPapName, (ckt, which, foo, "stop", parm));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* fstop */
GCA(INPapName, (ckt, which, foo, "donoise", parm));
return (0);
}
#ifdef WITH_HB
/* HB */
static int
dot_hb(char* line, void* ckt, INPtables* tab, struct card* current,
void* task, void* gnode, JOB* foo)
{
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue* parm; /* a pointer to a value struct for function returns */
char* nname; /* the oscNode name */
CKTnode* nnode; /* the oscNode node */
int which; /* which analysis we are performing */
char* word; /* something to stick a word of input into */
NG_IGNORE(gnode);
/* .pss Fguess StabTime OscNode <UIC>*/
which = ft_find_analysis("PSS");
if (which == -1) {
LITERR("Periodic steady state analysis unsupported.\n");
return (0);
}
IFC(newAnalysis, (ckt, which, "Harmonic Balance State Analysis", &foo, task));
parm = INPgetValue(ckt, &line, IF_REALVEC, tab); /* Fguess */
GCA(INPapName, (ckt, which, foo, "freq", parm));
parm = INPgetValue(ckt, &line, IF_INTVEC, tab); /* StabTime */
GCA(INPapName, (ckt, which, foo, "harmonics", parm));
INPgetNetTok(&line, &nname, 0);
INPtermInsert(ckt, &nname, tab, &nnode);
ptemp.nValue = nnode;
GCA(INPapName, (ckt, which, foo, "oscnode", &ptemp)); /* OscNode given as string */
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS points */
GCA(INPapName, (ckt, which, foo, "points", parm));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* PSS harmonics */
GCA(INPapName, (ckt, which, foo, "harmonics", parm));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* SC iterations */
GCA(INPapName, (ckt, which, foo, "sc_iter", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Steady coefficient */
GCA(INPapName, (ckt, which, foo, "steady_coeff", parm));
if (*line) {
INPgetTok(&line, &word, 1); /* uic? */
if (strcmp(word, "uic") == 0) {
ptemp.iValue = 1;
GCA(INPapName, (ckt, which, foo, "uic", &ptemp));
}
else {
fprintf(stderr, "Error: unknown parameter %s on .pss - ignored\n", word);
}
}
return (0);
}
#endif
#endif
static int static int
dot_options(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current, dot_options(char *line, CKTcircuit *ckt, INPtables *tab, struct card *current,
TSKtask *task, CKTnode *gnode, JOB *foo) TSKtask *task, CKTnode *gnode, JOB *foo)
@ -699,6 +799,20 @@ INP2dot(CKTcircuit *ckt, INPtables *tab, struct card *current, TSKtask *task, CK
rtn = dot_pss(line, ckt, tab, current, task, gnode, foo); rtn = dot_pss(line, ckt, tab, current, task, gnode, foo);
goto quit; goto quit;
/* SP */ /* SP */
#endif
#ifdef RFSPICE
}
else if ((strcmp(token, ".sp") == 0)) {
rtn = dot_sp(line, ckt, tab, current, task, gnode, foo);
goto quit;
/* SP */
#ifdef WITH_HB
}
else if ((strcmp(token, ".hb") == 0)) {
rtn = dot_hb(line, ckt, tab, current, task, gnode, foo);
goto quit;
/* SP */
#endif
#endif #endif
} else if ((strcmp(token, ".subckt") == 0) || } else if ((strcmp(token, ".subckt") == 0) ||
(strcmp(token, ".ends") == 0)) { (strcmp(token, ".ends") == 0)) {

19
visualc/vngspice.vcxproj

@ -311,7 +311,7 @@
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);NGDEBUG;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);NGDEBUG;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -363,7 +363,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -511,7 +511,7 @@
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);NGDEBUG;CONSOLE;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);NGDEBUG;CONSOLE;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -563,7 +563,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONSOLE;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONSOLE;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -669,7 +669,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);USE_OMP;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);USE_OMP;CONFIG64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -778,7 +778,7 @@
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\src\maths\poly;..\src\frontend;..\src\spicelib\devices;tmp-bison;src\include;..\src\spicelib\parser;..\src\include;..\src\include\cppduals;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONSOLE;CONFIG64;USE_OMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>RFSPICE;_CRT_SECURE_NO_DEPRECATE;SIMULATOR;XSPICE;_MSC_PLATFORM_TOOLSET=$(PlatformToolsetVersion);CONSOLE;CONFIG64;USE_OMP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<ExceptionHandling> <ExceptionHandling>
</ExceptionHandling> </ExceptionHandling>
@ -952,6 +952,7 @@
<ClInclude Include="..\src\include\ngspice\cmconstants.h" /> <ClInclude Include="..\src\include\ngspice\cmconstants.h" />
<ClInclude Include="..\src\include\ngspice\cmproto.h" /> <ClInclude Include="..\src\include\ngspice\cmproto.h" />
<ClInclude Include="..\src\include\ngspice\cmtypes.h" /> <ClInclude Include="..\src\include\ngspice\cmtypes.h" />
<ClInclude Include="..\src\include\ngspice\spdefs.h" />
<ClInclude Include="..\src\include\ngspice\wincolornames.h" /> <ClInclude Include="..\src\include\ngspice\wincolornames.h" />
<ClInclude Include="..\src\include\ngspice\compatmode.h" /> <ClInclude Include="..\src\include\ngspice\compatmode.h" />
<ClInclude Include="..\src\include\ngspice\complex.h" /> <ClInclude Include="..\src\include\ngspice\complex.h" />
@ -1065,6 +1066,7 @@
<ClInclude Include="..\src\maths\cmaths\cmath2.h" /> <ClInclude Include="..\src\maths\cmaths\cmath2.h" />
<ClInclude Include="..\src\maths\cmaths\cmath3.h" /> <ClInclude Include="..\src\maths\cmaths\cmath3.h" />
<ClInclude Include="..\src\maths\cmaths\cmath4.h" /> <ClInclude Include="..\src\maths\cmaths\cmath4.h" />
<ClInclude Include="..\src\maths\dense\dense.h" />
<ClInclude Include="..\src\maths\fft\fftlib.h" /> <ClInclude Include="..\src\maths\fft\fftlib.h" />
<ClInclude Include="..\src\maths\fft\matlib.h" /> <ClInclude Include="..\src\maths\fft\matlib.h" />
<ClInclude Include="..\src\maths\misc\accuracy.h" /> <ClInclude Include="..\src\maths\misc\accuracy.h" />
@ -1562,6 +1564,7 @@
<ClCompile Include="..\src\maths\cmaths\cmath2.c" /> <ClCompile Include="..\src\maths\cmaths\cmath2.c" />
<ClCompile Include="..\src\maths\cmaths\cmath3.c" /> <ClCompile Include="..\src\maths\cmaths\cmath3.c" />
<ClCompile Include="..\src\maths\cmaths\cmath4.c" /> <ClCompile Include="..\src\maths\cmaths\cmath4.c" />
<ClCompile Include="..\src\maths\dense\dense.c" />
<ClCompile Include="..\src\maths\deriv\atander.c" /> <ClCompile Include="..\src\maths\deriv\atander.c" />
<ClCompile Include="..\src\maths\deriv\cosderiv.c" /> <ClCompile Include="..\src\maths\deriv\cosderiv.c" />
<ClCompile Include="..\src\maths\deriv\cubeder.c" /> <ClCompile Include="..\src\maths\deriv\cubeder.c" />
@ -1682,6 +1685,7 @@
<ClCompile Include="..\src\spicelib\analysis\cktsetup.c" /> <ClCompile Include="..\src\spicelib\analysis\cktsetup.c" />
<ClCompile Include="..\src\spicelib\analysis\cktsgen.c" /> <ClCompile Include="..\src\spicelib\analysis\cktsgen.c" />
<ClCompile Include="..\src\spicelib\analysis\cktsopt.c" /> <ClCompile Include="..\src\spicelib\analysis\cktsopt.c" />
<ClCompile Include="..\src\spicelib\analysis\cktspdum.c" />
<ClCompile Include="..\src\spicelib\analysis\ckttemp.c" /> <ClCompile Include="..\src\spicelib\analysis\ckttemp.c" />
<ClCompile Include="..\src\spicelib\analysis\cktterr.c" /> <ClCompile Include="..\src\spicelib\analysis\cktterr.c" />
<ClCompile Include="..\src\spicelib\analysis\ckttroub.c" /> <ClCompile Include="..\src\spicelib\analysis\ckttroub.c" />
@ -1715,6 +1719,9 @@
<ClCompile Include="..\src\spicelib\analysis\pzsetp.c" /> <ClCompile Include="..\src\spicelib\analysis\pzsetp.c" />
<ClCompile Include="..\src\spicelib\analysis\sensaskq.c" /> <ClCompile Include="..\src\spicelib\analysis\sensaskq.c" />
<ClCompile Include="..\src\spicelib\analysis\senssetp.c" /> <ClCompile Include="..\src\spicelib\analysis\senssetp.c" />
<ClCompile Include="..\src\spicelib\analysis\span.c" />
<ClCompile Include="..\src\spicelib\analysis\spaskq.c" />
<ClCompile Include="..\src\spicelib\analysis\spsetp.c" />
<ClCompile Include="..\src\spicelib\analysis\tfanal.c" /> <ClCompile Include="..\src\spicelib\analysis\tfanal.c" />
<ClCompile Include="..\src\spicelib\analysis\tfaskq.c" /> <ClCompile Include="..\src\spicelib\analysis\tfaskq.c" />
<ClCompile Include="..\src\spicelib\analysis\tfsetp.c" /> <ClCompile Include="..\src\spicelib\analysis\tfsetp.c" />

Loading…
Cancel
Save