2017-04-25 14:41:48 +02:00
|
|
|
/*
|
|
|
|
|
* ext2spice.h --
|
|
|
|
|
* Definitions for ext2spice.c and ext2hier.c
|
|
|
|
|
*/
|
|
|
|
|
|
2024-10-16 08:38:41 +02:00
|
|
|
#ifndef _MAGIC__EXT2SPICE__EXT2SPICE_H
|
|
|
|
|
#define _MAGIC__EXT2SPICE__EXT2SPICE_H
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/* cache list used to find parallel devs */
|
|
|
|
|
typedef struct _devMerge {
|
|
|
|
|
float l, w;
|
|
|
|
|
EFNode *g, *s, *d, *b;
|
|
|
|
|
Dev * dev;
|
|
|
|
|
int esFMIndex;
|
|
|
|
|
HierName *hierName;
|
2025-07-24 15:36:22 +02:00
|
|
|
const struct _devMerge *next;
|
2017-04-25 14:41:48 +02:00
|
|
|
} devMerge;
|
|
|
|
|
|
2025-07-18 23:02:48 +02:00
|
|
|
#include "extflat/EFint.h" /* HierContext */
|
|
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Forward declarations */
|
2025-07-18 14:41:44 +02:00
|
|
|
extern void CmdExtToSpice(MagWindow *w, TxCommand *cmd);
|
|
|
|
|
extern int spcParseArgs(int *pargc, char ***pargv);
|
2025-07-18 23:02:48 +02:00
|
|
|
extern int spccapVisit(HierName *hierName1, HierName *hierName2, double cap, ClientData cdata); /* @typedef cb_extflat_visitcaps_t (UNUSED) */
|
|
|
|
|
extern int spcdevVisit(Dev *dev, HierContext *hc, float scale, Transform *trans, ClientData cdata); /* @typedef cb_extflat_visitdevs_t (UNUSED) */
|
|
|
|
|
extern int spcnodeVisit(EFNode *node, int res, double cap, ClientData cdata); /* @typedef cb_extflat_visitnodes_t (UNUSED) */
|
|
|
|
|
extern int subcktVisit(Use *use, HierName *hierName, bool is_top); /* @typedef cb_extflat_visitsubcircuits_t */
|
2025-07-20 17:09:08 +02:00
|
|
|
extern int spcresistVisit(const HierName *hierName1, const HierName *hierName2, float res, ClientData cdata); /* @typedef cb_extflat_visitresists_t (UNUSED) */
|
2025-07-18 23:02:48 +02:00
|
|
|
extern int devMergeVisit(Dev *dev, HierContext *hc, float scale, Transform *trans, ClientData cdata); /* @typedef cb_extflat_visitdevs_t (UNUSED) */
|
|
|
|
|
extern int devDistJunctVisit(Dev *dev, HierContext *hc, float scale, Transform *trans, ClientData cdata); /* @typedef cb_extflat_visitdevs_t (UNUSED) */
|
|
|
|
|
extern int spcsubVisit(EFNode *node, int res, double cap, ClientData cdata); /* @typedef cb_extflat_visitnodes_t (char** resstr) */
|
|
|
|
|
extern int subcktUndef(Use *use, HierName *hierName, bool is_top); /* @typedef cb_extflat_visitsubcircuits_t */
|
2025-07-18 14:41:44 +02:00
|
|
|
extern EFNode *spcdevSubstrate(HierName *prefix, HierName *suffix, int type, FILE *outf);
|
2025-07-21 23:46:03 +02:00
|
|
|
extern const char *nodeSpiceName(const HierName *hname, EFNode **rnode);
|
2025-07-18 23:02:48 +02:00
|
|
|
extern int nodeVisitDebug(EFNode *node, int res, double cap, ClientData cdata); /* @typedef cb_extflat_visitnodes_t (UNUSED) */
|
2025-07-18 14:41:44 +02:00
|
|
|
extern void topVisit(Def *def, bool doStub);
|
|
|
|
|
extern void swapDrainSource(Dev *dev);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
2025-07-21 23:49:52 +02:00
|
|
|
extern const char *nodeSpiceHierName(HierContext *hc, const HierName *hname);
|
2025-07-18 14:41:44 +02:00
|
|
|
extern devMerge *mkDevMerge(float l, float w, EFNode *g, EFNode *s, EFNode *d, EFNode *b, HierName *hn, Dev *dev);
|
|
|
|
|
extern bool extHierSDAttr(DevTerm *term);
|
2017-04-25 14:41:48 +02:00
|
|
|
|
2025-07-18 14:41:44 +02:00
|
|
|
extern bool devIsKilled(int n);
|
|
|
|
|
extern float getCurDevMult(void);
|
|
|
|
|
extern void addDevMult(float f);
|
|
|
|
|
extern void setDevMult(int i, float f);
|
2019-10-23 15:33:37 +02:00
|
|
|
|
2022-10-10 11:50:15 +02:00
|
|
|
/* C99 compat */
|
2025-07-18 14:41:44 +02:00
|
|
|
extern int EFHNSprintf(char *str, HierName *hierName);
|
|
|
|
|
extern int printSubcktDict(void);
|
2025-07-23 21:10:03 +02:00
|
|
|
extern int spcdevOutNode(const HierName *prefix, const HierName *suffix, const char *name, FILE *outf);
|
2025-07-18 14:41:44 +02:00
|
|
|
extern int spcnAP(DevTerm *dterm, EFNode *node, int resClass, float scale, char *asterm, char *psterm, float m, FILE *outf, int w);
|
2025-07-24 15:36:22 +02:00
|
|
|
extern int parallelDevs(const devMerge *f1, const devMerge *f2);
|
2025-07-18 14:41:44 +02:00
|
|
|
extern int nodeHspiceName(char *s);
|
2025-07-20 13:52:23 +02:00
|
|
|
extern int devDistJunctHierVisit(HierContext *hc, Dev *dev, float scale, ClientData cdata); /* @typedef cb_extflat_hiervisitdevs_t (UNUSED) */
|
2025-07-18 14:41:44 +02:00
|
|
|
extern int spcnAPHier(DevTerm *dterm, HierName *hierName, int resClass, float scale, char *asterm, char *psterm, float m, FILE *outf);
|
|
|
|
|
extern void mergeAttr(char **a1, char **a2);
|
|
|
|
|
extern int update_w(short resClass, int w, EFNode *n);
|
|
|
|
|
extern void esSIvalue(FILE *file, float value);
|
2022-10-10 11:50:15 +02:00
|
|
|
|
2017-04-25 14:41:48 +02:00
|
|
|
/* Options specific to ext2spice */
|
|
|
|
|
extern bool esDoExtResis;
|
|
|
|
|
extern bool esDoPorts;
|
|
|
|
|
extern bool esDoHierarchy;
|
2017-08-02 04:14:42 +02:00
|
|
|
extern bool esDoBlackBox;
|
2017-04-25 14:41:48 +02:00
|
|
|
extern bool esDoResistorTee;
|
|
|
|
|
extern int esDoSubckt;
|
|
|
|
|
extern bool esDevNodesOnly;
|
|
|
|
|
extern bool esNoAttrs;
|
|
|
|
|
extern bool esHierAP;
|
|
|
|
|
extern char spcesDefaultOut[FNSIZE];
|
2025-07-24 15:20:12 +02:00
|
|
|
extern const char *esSpiceCapNode;
|
|
|
|
|
extern const char esSpiceDefaultGnd[];
|
2017-04-25 14:41:48 +02:00
|
|
|
extern char *spcesOutName;
|
|
|
|
|
extern FILE *esSpiceF;
|
|
|
|
|
extern float esScale; /* negative if hspice the EFScale/100 otherwise */
|
|
|
|
|
|
|
|
|
|
extern unsigned short esFormat;
|
2021-05-27 22:13:06 +02:00
|
|
|
extern TileTypeBitMask initMask;
|
2017-04-25 14:41:48 +02:00
|
|
|
|
2025-07-18 14:43:44 +02:00
|
|
|
extern int esCapNum;
|
|
|
|
|
extern int esDevNum;
|
|
|
|
|
extern int esResNum;
|
|
|
|
|
extern int esDiodeNum;
|
|
|
|
|
extern int esVoltNum;
|
2017-04-25 14:41:48 +02:00
|
|
|
extern int esNodeNum; /* just in case we're extracting spice2 */
|
|
|
|
|
extern int esSbckNum; /* used in hspice node name shortening */
|
|
|
|
|
extern int esNoModelType; /* index for device type "None" (model-less device) */
|
|
|
|
|
|
|
|
|
|
extern bool esMergeDevsA; /* aggressive merging of devs L1=L2 merge them */
|
|
|
|
|
extern bool esMergeDevsC; /* conservative merging of devs L1=L2 and W1=W2 */
|
|
|
|
|
/* used with the hspice multiplier */
|
|
|
|
|
extern bool esDistrJunct;
|
|
|
|
|
|
|
|
|
|
extern float *esFMult; /* the array itself */
|
|
|
|
|
extern int esFMIndex; /* current index to it */
|
|
|
|
|
extern int esFMSize; /* its current size (growable) */
|
|
|
|
|
|
|
|
|
|
extern int esSpiceDevsMerged;
|
2025-07-24 15:36:22 +02:00
|
|
|
extern const devMerge *devMergeList;
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
/*
|
2020-05-23 23:13:14 +02:00
|
|
|
* The following hash table and associated functions are used only if
|
|
|
|
|
* the format is hspice, to keep the translation between the hierarchical
|
|
|
|
|
* prefix of a node and the x num that we use to output valid hspice
|
2017-04-25 14:41:48 +02:00
|
|
|
* which also are meaningful.
|
|
|
|
|
*/
|
|
|
|
|
extern HashTable subcktNameTable ; /* the hash table itself */
|
|
|
|
|
extern DQueue subcktNameQueue ; /* q used to print it sorted at the end*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
2020-09-11 23:29:12 +02:00
|
|
|
short resClassSource ; /* the resistance class of the source of the dev */
|
|
|
|
|
short resClassDrain ; /* the resistance class of the drain of the dev */
|
2017-04-25 14:41:48 +02:00
|
|
|
short resClassSub ; /* the resistance class of the substrate of the dev */
|
|
|
|
|
char *defSubs ; /* the default substrate node */
|
|
|
|
|
} fetInfoList;
|
|
|
|
|
|
2021-05-27 22:13:06 +02:00
|
|
|
extern fetInfoList esFetInfo[TT_MAXTYPES];
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#define MAX_STR_SIZE (1<<11) /* 2K should be enough for keeping temp
|
|
|
|
|
names even of the most complicated design */
|
|
|
|
|
|
|
|
|
|
/* Node clients for figuring out areas and perimeters of sources and drains */
|
|
|
|
|
|
|
|
|
|
typedef union {
|
2021-05-27 22:13:06 +02:00
|
|
|
TileTypeBitMask visitMask; /* mask for normal visits */
|
2017-04-25 14:41:48 +02:00
|
|
|
float *widths; /* width used for distributing area perim */
|
|
|
|
|
} maskOrWidth ;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
char *spiceNodeName;
|
|
|
|
|
maskOrWidth m_w;
|
|
|
|
|
} nodeClient;
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
HierName *lastPrefix;
|
|
|
|
|
maskOrWidth m_w;
|
|
|
|
|
} nodeClientHier;
|
|
|
|
|
|
|
|
|
|
#define NO_RESCLASS -1
|
|
|
|
|
|
|
|
|
|
#define markVisited(client, rclass) \
|
2021-05-27 22:13:06 +02:00
|
|
|
{ TTMaskSetType(&((client)->m_w.visitMask), rclass); }
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#define clearVisited(client) \
|
2021-05-27 22:13:06 +02:00
|
|
|
{ TTMaskZero(&((client)->m_w.visitMask)); }
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#define beenVisited(client, rclass) \
|
2021-05-27 22:13:06 +02:00
|
|
|
( TTMaskHasType(&((client)->m_w.visitMask), rclass) )
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#define initNodeClient(node) \
|
|
|
|
|
{ \
|
|
|
|
|
(node)->efnode_client = (ClientData) mallocMagic((unsigned) (sizeof(nodeClient))); \
|
2021-06-11 22:53:23 +02:00
|
|
|
(( nodeClient *)(node)->efnode_client)->spiceNodeName = NULL; \
|
|
|
|
|
TTMaskZero (&((nodeClient *) (node)->efnode_client)->m_w.visitMask); \
|
2021-05-27 22:13:06 +02:00
|
|
|
TTMaskSetMask(&(((nodeClient *)(node)->efnode_client)->m_w.visitMask), &initMask);\
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define initNodeClientHier(node) \
|
|
|
|
|
{ \
|
|
|
|
|
(node)->efnode_client = (ClientData) mallocMagic((unsigned)(sizeof(nodeClientHier))); \
|
2021-05-27 22:13:06 +02:00
|
|
|
TTMaskZero (&((nodeClientHier *) (node)->efnode_client)->m_w.visitMask); \
|
2017-04-25 14:41:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* attributes controlling the Area/Perimeter extraction of dev terminals */
|
|
|
|
|
#define ATTR_FLATAP "*[Ee][Xx][Tt]:[Aa][Pp][Ff]*"
|
|
|
|
|
#define ATTR_HIERAP "*[Ee][Xx][Tt]:[Aa][Pp][Hh]*"
|
|
|
|
|
#define ATTR_SUBSAP "*[Ee][Xx][Tt]:[Aa][Pp][Ss]*"
|
|
|
|
|
|
|
|
|
|
#define SPICE2 0
|
|
|
|
|
#define SPICE3 1
|
|
|
|
|
#define HSPICE 2
|
|
|
|
|
#define NGSPICE 3
|
|
|
|
|
|
|
|
|
|
#define AUTO 2 /* TRUE | FALSE | AUTO for esDoSubckt */
|
|
|
|
|
|
|
|
|
|
#define NOT_PARALLEL 0
|
|
|
|
|
#define PARALLEL 1
|
|
|
|
|
#define ANTIPARALLEL 2
|
|
|
|
|
|
2020-05-23 23:13:14 +02:00
|
|
|
/*
|
2017-04-25 14:41:48 +02:00
|
|
|
*---------------------------------------------------------
|
2020-05-23 23:13:14 +02:00
|
|
|
* Variables used for merging parallel devs
|
|
|
|
|
* The merging of devs is based on the fact that spcdevVisit
|
|
|
|
|
* visits the devs in the same order all the time so the
|
2017-04-25 14:41:48 +02:00
|
|
|
* value of esFMult[i] keeps the multiplier for the ith dev
|
|
|
|
|
*---------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
#define DEV_KILLED ((float) -1.0)
|
|
|
|
|
#define FMULT_SIZE (1<<10)
|
|
|
|
|
#define DEV_KILLED ((float) -1.0)
|
|
|
|
|
|
|
|
|
|
#ifdef MAGIC_WRAPPER
|
|
|
|
|
#define atoCap(s) ((EFCapValue)atof(s))
|
|
|
|
|
#endif
|
|
|
|
|
|
2025-07-18 14:48:07 +02:00
|
|
|
extern int esFreeNodeClient(nodeClient *client);
|
|
|
|
|
|
2024-10-16 08:38:41 +02:00
|
|
|
#endif /* _MAGIC__EXT2SPICE__EXT2SPICE_H */
|