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
|
A number of changes:
1) Corrected spurious error messages about cells already existing
in GDS when using "flatten" or "flatglob".
2) Fixed handling of resistance as a subcircuit parameter
3) Added area and perimeter resistance for a device; this is done
through the "devresist" statement in the tech file, which is an
extension of the original "fetresist" statement. Where "fetresist"
only supported type "linear", "devresist" supports types "area"
and "perimeter".
4) Support for CDL syntax, including generating subcircuit-like
parameters for components starting with SPICE-standard prefixes
like M, R, C, etc., adding "/" between pins and subcircuit name,
and saving the file as ".cdl" instead of ".spice".
5) Estimated L and W for devices whose geometry is complex and do not
reduce to a simple rectangle. L and W are estimated as the square
root of the area.
6) Changed the method of extracting L and W for diodes to use the same
method as capacitors. Note that diodes are not usually specified
by L and W, but if they are, this will produce the right result.
7) Corrected the reported filename and line number when printing error
messages related to errors inside a technology file, when the
technology file uses "include" to combine multiple files.
2025-10-01 21:17:49 +02:00
|
|
|
#define CDL 4
|
2017-04-25 14:41:48 +02:00
|
|
|
|
|
|
|
|
#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 */
|