Merge branch 'master' into netgen-1.5
This commit is contained in:
commit
65b542f0ab
|
|
@ -1112,13 +1112,17 @@ void FreeObjectAndHash(struct objlist *ob, struct nlist *ptr)
|
||||||
|
|
||||||
/*************** GENERAL UTILITIES ****************************/
|
/*************** GENERAL UTILITIES ****************************/
|
||||||
|
|
||||||
int NumberOfPorts(char *cellname)
|
int NumberOfPorts(char *cellname, int file)
|
||||||
{
|
{
|
||||||
struct nlist *tp;
|
struct nlist *tp;
|
||||||
struct objlist *ob;
|
struct objlist *ob;
|
||||||
int ports;
|
int ports;
|
||||||
|
|
||||||
tp = LookupCell(cellname);
|
if (file == -1)
|
||||||
|
tp = LookupCell(cellname);
|
||||||
|
else
|
||||||
|
tp = LookupCellFile(cellname, file);
|
||||||
|
|
||||||
if (tp == NULL) return(0);
|
if (tp == NULL) return(0);
|
||||||
ports = 0;
|
ports = 0;
|
||||||
for (ob = tp->cell; ob != NULL; ob = ob->next)
|
for (ob = tp->cell; ob != NULL; ob = ob->next)
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,7 @@ extern void FreeObjectAndHash(struct objlist *ob, struct nlist *ptr);
|
||||||
extern void FreePorts(char *cellname);
|
extern void FreePorts(char *cellname);
|
||||||
extern struct IgnoreList *ClassIgnore;
|
extern struct IgnoreList *ClassIgnore;
|
||||||
|
|
||||||
extern int NumberOfPorts(char *cellname);
|
extern int NumberOfPorts(char *cellname, int file);
|
||||||
extern struct objlist *InstanceNumber(struct nlist *tp, int inst);
|
extern struct objlist *InstanceNumber(struct nlist *tp, int inst);
|
||||||
|
|
||||||
extern struct objlist *List(char *list_template);
|
extern struct objlist *List(char *list_template);
|
||||||
|
|
|
||||||
|
|
@ -929,7 +929,7 @@ void ToggleDebug(void)
|
||||||
void DescribeCell(char *name, int detail)
|
void DescribeCell(char *name, int detail)
|
||||||
{
|
{
|
||||||
Printf("Cell: %s contains %d instances, %d nodes and %d ports\n", name,
|
Printf("Cell: %s contains %d instances, %d nodes and %d ports\n", name,
|
||||||
NumberOfInstances(name), RenumberNodes(name), NumberOfPorts(name));
|
NumberOfInstances(name), RenumberNodes(name), NumberOfPorts(name, -1));
|
||||||
PrintEmbeddingTree(stdout,name,detail);
|
PrintEmbeddingTree(stdout,name,detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -907,7 +907,7 @@ void PrintLeavesInCell(char *cellname, int filenum)
|
||||||
np->dumped = 1;
|
np->dumped = 1;
|
||||||
|
|
||||||
if (np->class != CLASS_SUBCKT) {
|
if (np->class != CLASS_SUBCKT) {
|
||||||
Printf("%s; %d ports; Primitive.\n", cellname, NumberOfPorts(cellname));
|
Printf("%s; %d ports; Primitive.\n", cellname, NumberOfPorts(cellname, filenum));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -920,7 +920,7 @@ void PrintLeavesInCell(char *cellname, int filenum)
|
||||||
am_a_leaf = 0;
|
am_a_leaf = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (am_a_leaf) Printf("%s; %d ports\n", cellname, NumberOfPorts(cellname));
|
if (am_a_leaf) Printf("%s; %d ports\n", cellname, NumberOfPorts(cellname, filenum));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1532,23 +1532,24 @@ int
|
||||||
_netgen_model(ClientData clientData,
|
_netgen_model(ClientData clientData,
|
||||||
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
|
||||||
{
|
{
|
||||||
struct nlist *tp;
|
struct nlist *tp, *tp2;
|
||||||
char *model, *retclass;
|
char *model, *retclass;
|
||||||
unsigned char class;
|
unsigned char class;
|
||||||
int fnum = -1;
|
int fnum = -1;
|
||||||
int result, index, nports;
|
int result, index, nports, nports2;
|
||||||
|
|
||||||
char *modelclasses[] = {
|
char *modelclasses[] = {
|
||||||
"undefined", "nmos", "pmos", "pnp", "npn",
|
"undefined", "nmos", "pmos", "pnp", "npn",
|
||||||
"resistor", "capacitor", "diode",
|
"resistor", "capacitor", "diode",
|
||||||
"inductor", "module", "blackbox", "xline",
|
"inductor", "module", "blackbox", "xline",
|
||||||
"moscap", "mosfet", "bjt", "subcircuit", NULL
|
"moscap", "mosfet", "bjt", "subcircuit", "copy",
|
||||||
|
NULL
|
||||||
};
|
};
|
||||||
enum OptionIdx {
|
enum OptionIdx {
|
||||||
UNDEF_IDX, NMOS_IDX, PMOS_IDX, PNP_IDX, NPN_IDX,
|
UNDEF_IDX, NMOS_IDX, PMOS_IDX, PNP_IDX, NPN_IDX,
|
||||||
RES_IDX, CAP_IDX, DIODE_IDX, INDUCT_IDX,
|
RES_IDX, CAP_IDX, DIODE_IDX, INDUCT_IDX,
|
||||||
MODULE_IDX, BLACKBOX_IDX, XLINE_IDX, MOSCAP_IDX,
|
MODULE_IDX, BLACKBOX_IDX, XLINE_IDX, MOSCAP_IDX,
|
||||||
MOSFET_IDX, BJT_IDX, SUBCKT_IDX
|
MOSFET_IDX, BJT_IDX, SUBCKT_IDX, COPY_IDX
|
||||||
};
|
};
|
||||||
|
|
||||||
if (objc != 3 && objc != 2) {
|
if (objc != 3 && objc != 2) {
|
||||||
|
|
@ -1580,7 +1581,7 @@ _netgen_model(ClientData clientData,
|
||||||
|
|
||||||
if (objc == 3) {
|
if (objc == 3) {
|
||||||
model = Tcl_GetString(objv[2]);
|
model = Tcl_GetString(objv[2]);
|
||||||
nports = NumberOfPorts(model);
|
nports = NumberOfPorts(model, fnum);
|
||||||
|
|
||||||
if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)modelclasses,
|
if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)modelclasses,
|
||||||
"class", 0, &index) != TCL_OK) {
|
"class", 0, &index) != TCL_OK) {
|
||||||
|
|
@ -1644,6 +1645,40 @@ _netgen_model(ClientData clientData,
|
||||||
break;
|
break;
|
||||||
case SUBCKT_IDX:
|
case SUBCKT_IDX:
|
||||||
class = CLASS_SUBCKT;
|
class = CLASS_SUBCKT;
|
||||||
|
break;
|
||||||
|
case COPY_IDX:
|
||||||
|
/* "copy" is not a class, but indicates that the cell, */
|
||||||
|
/* if undefined or a module, should have its class */
|
||||||
|
/* taken from the other circuit, if that circuit has a */
|
||||||
|
/* cell of the same name. */
|
||||||
|
if (Circuit1 == NULL || Circuit2 == NULL) {
|
||||||
|
Tcl_SetResult(interp, "Circuits have not been queued for comparison.",
|
||||||
|
NULL);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
if (tp == Circuit1) {
|
||||||
|
tp2 = LookupCellFile(tp->name, Circuit2->file);
|
||||||
|
nports2 = NumberOfPorts(tp2->name, Circuit2->file);
|
||||||
|
}
|
||||||
|
else if (tp == Circuit2) {
|
||||||
|
tp2 = LookupCellFile(tp->name, Circuit1->file);
|
||||||
|
nports2 = NumberOfPorts(tp2->name, Circuit1->file);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Tcl_SetResult(interp, "The referenced netlist is not being compared.",
|
||||||
|
NULL);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
/* Should a non-matching number of ports be considered a fatal error? */
|
||||||
|
// if (nports2 != nports) {
|
||||||
|
// Tcl_SetResult(interp, "The number of ports for this cell does not "
|
||||||
|
// "match between netlists.", NULL);
|
||||||
|
// return TCL_ERROR;
|
||||||
|
// }
|
||||||
|
|
||||||
|
class = tp2->class;
|
||||||
|
/* To do (maybe): Rename tp ports to match tp2? */
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tp->class = class;
|
tp->class = class;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue