Added two new features: (1) Default substrate name: Added an
optional name field to the "substrate" line in the extract section of the techfile. This is the default name of the substrate if not connected to anything labeled. It may use a Tcl variable (preferred). (2) Added command option "instance orientation [-def]" that returns the orientation of the named or selected instance. The -def option returns the orientation using DEF naming convention; otherwise, the naming used with "getcell" is generated.
This commit is contained in:
parent
336a7aa209
commit
15f1c82bc9
|
|
@ -579,6 +579,8 @@ outputCalma:
|
|||
* cellname [list] filepath [path|"default"]
|
||||
* or
|
||||
* cellname property [name] [property_key [property_value]]
|
||||
* or
|
||||
* instance orientation [name] [-def]
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -597,7 +599,9 @@ CmdCellname(w, cmd)
|
|||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
{
|
||||
bool is_cellname;
|
||||
bool dolist = FALSE;
|
||||
bool dodef = FALSE;
|
||||
int option;
|
||||
int locargc = cmd->tx_argc;
|
||||
char *cellname = NULL;
|
||||
|
|
@ -623,6 +627,7 @@ CmdCellname(w, cmd)
|
|||
"lock lock the named cell (prevent changes to cell use)",
|
||||
"unlock unlock the named cell (allow changes to cell use)",
|
||||
"property list or set cell definition properties",
|
||||
"orientation list or set instance orientation",
|
||||
"rename rename the indicated cell",
|
||||
"writeable make the cell definition read-only or read-write",
|
||||
"modified true if modified, false if not",
|
||||
|
|
@ -632,13 +637,15 @@ CmdCellname(w, cmd)
|
|||
IDX_INSTANCE, IDX_CHILDINST, IDX_CELLDEF, IDX_ALLCELLS,
|
||||
IDX_TOPCELLS, IDX_IN_WINDOW, IDX_CREATE,
|
||||
IDX_DELETE, IDX_FILEPATH, IDX_FLAGS, IDX_LOCK, IDX_UNLOCK,
|
||||
IDX_PROPERTY, IDX_RENAME, IDX_READWRITE,
|
||||
IDX_MODIFIED } optionType;
|
||||
IDX_PROPERTY, IDX_ORIENTATION, IDX_RENAME,
|
||||
IDX_READWRITE, IDX_MODIFIED } optionType;
|
||||
|
||||
if (strstr(cmd->tx_argv[0], "in"))
|
||||
func = DBUsePrint;
|
||||
is_cellname = FALSE;
|
||||
else
|
||||
func = DBCellPrint;
|
||||
is_cellname = TRUE;
|
||||
|
||||
func = (is_cellname) ? DBCellPrint : DBUsePrint;
|
||||
|
||||
if (locargc > 1)
|
||||
{
|
||||
|
|
@ -647,6 +654,21 @@ CmdCellname(w, cmd)
|
|||
locargc--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for option at end of option list */
|
||||
|
||||
if (*cmd->tx_argv[cmd->tx_argc - 1] == '-') {
|
||||
char *option = cmd->tx_argv[cmd->tx_argc - 1] + 1;
|
||||
if (!strcmp(option, "list")) {
|
||||
dolist = TRUE;
|
||||
locargc--;
|
||||
}
|
||||
else if (!strcmp(option, "def")) {
|
||||
dodef = TRUE;
|
||||
locargc--;
|
||||
}
|
||||
}
|
||||
|
||||
if (locargc > 5 || locargc < 2) goto badusage;
|
||||
|
||||
option = Lookup(cmd->tx_argv[1 + ((dolist) ? 1 : 0)], cmdCellOption);
|
||||
|
|
@ -672,7 +694,7 @@ CmdCellname(w, cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (func != DBUsePrint)
|
||||
if (is_cellname)
|
||||
{
|
||||
/* These functions only work with cell uses (instances) */
|
||||
switch (option) {
|
||||
|
|
@ -681,6 +703,10 @@ CmdCellname(w, cmd)
|
|||
TxError("Cell definitions cannot be locked. Use \"instance\"?\n");
|
||||
TxError(" or do you mean \"cellname writeable\"?\n");
|
||||
return;
|
||||
case IDX_ORIENTATION:
|
||||
TxError("Cell definitions do not have orientations."
|
||||
" Use \"instance\"?\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -721,16 +747,16 @@ CmdCellname(w, cmd)
|
|||
(*func)(cellname, SELF, dolist);
|
||||
break;
|
||||
case IDX_CELLDEF:
|
||||
(*func)(cellname, ((func == DBUsePrint) ? OTHER : SELF), dolist);
|
||||
(*func)(cellname, ((is_cellname == FALSE) ? OTHER : SELF), dolist);
|
||||
break;
|
||||
case IDX_INSTANCE:
|
||||
(*func)(cellname, ((func == DBUsePrint) ? SELF : OTHER), dolist);
|
||||
(*func)(cellname, ((is_cellname == FALSE) ? SELF : OTHER), dolist);
|
||||
break;
|
||||
case IDX_CHILDREN:
|
||||
(*func)(cellname, CHILDREN, dolist);
|
||||
break;
|
||||
case IDX_CHILDINST:
|
||||
(*func)(cellname, ((func == DBUsePrint) ? CHILDREN : CHILDINST), dolist);
|
||||
(*func)(cellname, ((is_cellname == FALSE) ? CHILDREN : CHILDINST), dolist);
|
||||
break;
|
||||
case IDX_PARENTS:
|
||||
(*func)(cellname, PARENTS, dolist);
|
||||
|
|
@ -958,6 +984,9 @@ CmdCellname(w, cmd)
|
|||
DBCellSetAvail(newDef);
|
||||
}
|
||||
break;
|
||||
case IDX_ORIENTATION:
|
||||
DBOrientUse(cellname, dodef);
|
||||
break;
|
||||
case IDX_LOCK:
|
||||
DBLockUse(cellname, TRUE);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1154,7 +1154,7 @@ DBLockUse(UseName, bval)
|
|||
CellDef *celldef;
|
||||
CellUse *celluse;
|
||||
|
||||
int dbUseLockFunc();
|
||||
int dbLockUseFunc();
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
@ -1199,6 +1199,169 @@ DBLockUse(UseName, bval)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBOrientUse --
|
||||
*
|
||||
* This routine sets or reports a cell instance's orientation
|
||||
* UseName is the name of a specific CellUse. If NULL, then the
|
||||
* operation applies to all selected cell uses. "orient" is a
|
||||
* string in the form used by "getcell" (e.g., "180", "270v",
|
||||
* etc.), unless "dodef" is true, in which case the output is
|
||||
* given in the form used by DEF ("N", "FN", etc.).
|
||||
* reported.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* cu_transform changed for indicated cell use.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBOrientUse(UseName, dodef)
|
||||
char *UseName;
|
||||
bool dodef;
|
||||
{
|
||||
int found;
|
||||
HashSearch hs;
|
||||
HashEntry *entry;
|
||||
CellDef *celldef;
|
||||
CellUse *celluse;
|
||||
|
||||
int dbOrientUseFunc();
|
||||
|
||||
/*
|
||||
*
|
||||
* Check to see if a cell name was specified. If not, then search
|
||||
* for selected cells.
|
||||
*
|
||||
*/
|
||||
|
||||
if (UseName == NULL)
|
||||
{
|
||||
if (EditCellUse == NULL)
|
||||
TxError("Cannot set orientation of a non-edit cell!\n");
|
||||
else
|
||||
SelEnumCells(TRUE, (int *)NULL, (SearchContext *)NULL,
|
||||
dbOrientUseFunc, (ClientData)&dodef);
|
||||
}
|
||||
else
|
||||
{
|
||||
SearchContext scx;
|
||||
|
||||
bzero(&scx, sizeof(SearchContext));
|
||||
found = 0;
|
||||
|
||||
HashStartSearch(&hs);
|
||||
while( (entry = HashNext(&dbCellDefTable, &hs)) != NULL)
|
||||
{
|
||||
celldef = (CellDef *) HashGetValue(entry);
|
||||
if (celldef != (CellDef *) NULL)
|
||||
{
|
||||
celluse = celldef->cd_parents; /* only need one */
|
||||
if (celluse != (CellUse *)NULL) {
|
||||
DBTreeFindUse(UseName, celluse, &scx);
|
||||
if (scx.scx_use != NULL) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scx.scx_use == NULL)
|
||||
TxError("Cell %s is not currently loaded.\n", UseName);
|
||||
else
|
||||
dbOrientUseFunc(NULL, scx.scx_use, NULL, (ClientData)&dodef);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dbOrientUseFunc()
|
||||
*/
|
||||
|
||||
/* For corresponding enumerations, see GeoTransOrient() */
|
||||
enum def_orient {ORIENT_NORTH, ORIENT_SOUTH, ORIENT_EAST, ORIENT_WEST,
|
||||
ORIENT_FLIPPED_NORTH, ORIENT_FLIPPED_SOUTH, ORIENT_FLIPPED_EAST,
|
||||
ORIENT_FLIPPED_WEST};
|
||||
|
||||
int
|
||||
dbOrientUseFunc(selUse, use, transform, data)
|
||||
CellUse *selUse; /* Use from selection cell */
|
||||
CellUse *use; /* Use from layout corresponding to selection */
|
||||
Transform *transform;
|
||||
ClientData data;
|
||||
{
|
||||
bool *dodef = (bool *)data;
|
||||
|
||||
if (EditCellUse && !DBIsChild(use, EditCellUse))
|
||||
{
|
||||
TxError("Cell %s (%s) isn't a child of the edit cell.\n",
|
||||
use->cu_id, use->cu_def->cd_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (selUse != NULL)
|
||||
{
|
||||
switch (GeoTransOrient(&selUse->cu_transform)) {
|
||||
#ifdef MAGIC_WRAPPER
|
||||
case ORIENT_NORTH:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "N" : "0");
|
||||
break;
|
||||
case ORIENT_EAST:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "E" : "90");
|
||||
break;
|
||||
case ORIENT_SOUTH:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "S" : "180");
|
||||
break;
|
||||
case ORIENT_WEST:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "W" : "270");
|
||||
break;
|
||||
case ORIENT_FLIPPED_NORTH:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "FN" : "0h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_EAST:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "FE" : "90h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_SOUTH:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "FS" : "180h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_WEST:
|
||||
Tcl_AppendElement(magicinterp, (*dodef) ? "FW" : "270h");
|
||||
break;
|
||||
#else
|
||||
case ORIENT_NORTH:
|
||||
TxPrintf((*dodef) ? "N" : "0");
|
||||
break;
|
||||
case ORIENT_EAST:
|
||||
TxPrintf((*dodef) ? "E" : "90");
|
||||
break;
|
||||
case ORIENT_SOUTH:
|
||||
TxPrintf((*dodef) ? "S" : "180");
|
||||
break;
|
||||
case ORIENT_WEST:
|
||||
TxPrintf((*dodef) ? "W" : "270");
|
||||
break;
|
||||
case ORIENT_FLIPPED_NORTH:
|
||||
TxPrintf((*dodef) ? "FN" : "0h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_EAST:
|
||||
TxPrintf((*dodef) ? "FE" : "90h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_SOUTH:
|
||||
TxPrintf((*dodef) ? "FS" : "180h");
|
||||
break;
|
||||
case ORIENT_FLIPPED_WEST:
|
||||
TxPrintf((*dodef) ? "FW" : "270h");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -772,6 +772,9 @@ extern int DBCellSrDefs();
|
|||
extern CellUse *DBCellNewUse();
|
||||
extern bool DBCellDeleteUse();
|
||||
extern CellUse *DBCellFindDup();
|
||||
extern void DBLockUse();
|
||||
extern void DBUnlockUse();
|
||||
extern void DBOrientUse();
|
||||
|
||||
/* Cell selection */
|
||||
extern CellUse *DBSelectCell();
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ extBasic(def, outFile)
|
|||
|
||||
/* Output each node, along with its resistance and capacitance to substrate */
|
||||
if (!SigInterruptPending)
|
||||
extOutputNodes(nodeList, outFile);
|
||||
extOutputNodes(nodeList, outFile, glob_subsnode);
|
||||
|
||||
/* Output coupling capacitances */
|
||||
if (!SigInterruptPending && (ExtOptions&EXT_DOCOUPLING) && (!propfound))
|
||||
|
|
@ -862,6 +862,28 @@ extNodeName(node)
|
|||
if (extLabType(ll->ll_label->lab_text, LABTYPE_NAME))
|
||||
return (ll->ll_label->lab_text);
|
||||
|
||||
/* If the techfile specifies a global name for the substrate, use */
|
||||
/* that in preference to the default "p_x_y#" name. */
|
||||
|
||||
if ((NodeRegion *)node == glob_subsnode)
|
||||
{
|
||||
if (ExtCurStyle->exts_globSubstrateName != NULL)
|
||||
{
|
||||
if (ExtCurStyle->exts_globSubstrateName[0] == '$' &&
|
||||
ExtCurStyle->exts_globSubstrateName[1] != '$')
|
||||
{
|
||||
// If subsName is a Tcl variable (begins with "$"), make the
|
||||
// variable substitution, if one exists. Ignore double-$.
|
||||
|
||||
char *varsub = (char *)Tcl_GetVar(magicinterp,
|
||||
&ExtCurStyle->exts_globSubstrateName[1],
|
||||
TCL_GLOBAL_ONLY);
|
||||
return (varsub != NULL) ? varsub : ExtCurStyle->exts_globSubstrateName;
|
||||
}
|
||||
else
|
||||
return ExtCurStyle->exts_globSubstrateName;
|
||||
}
|
||||
}
|
||||
extMakeNodeNumPrint(namebuf, node->lreg_pnum, node->lreg_ll);
|
||||
return (namebuf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ static keydesc keyTable[] = {
|
|||
"style", STYLE, 2, 4,
|
||||
"stylename",
|
||||
|
||||
"substrate", SUBSTRATE, 3, 4,
|
||||
"types plane",
|
||||
"substrate", SUBSTRATE, 3, 5,
|
||||
"types plane [subs-node]",
|
||||
|
||||
"units", UNITS, 2, 2,
|
||||
"lambda|microns",
|
||||
|
|
@ -786,6 +786,7 @@ extTechStyleInit(style)
|
|||
style->exts_globSubstratePlane = -1;
|
||||
TTMaskZero(&style->exts_globSubstrateTypes);
|
||||
TTMaskZero(&style->exts_globSubstrateShieldTypes);
|
||||
style->exts_globSubstrateName = (char *)NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2834,6 +2835,11 @@ ExtTechLine(sectionName, argc, argv)
|
|||
TTMaskSetMask(&ExtCurStyle->exts_globSubstrateTypes, &types1);
|
||||
ExtCurStyle->exts_globSubstrateShieldTypes = idTypes;
|
||||
ExtCurStyle->exts_globSubstratePlane = DBTechNoisyNamePlane(argv[2]);
|
||||
|
||||
/* Handle optional substrate node name */
|
||||
if (argc == 4)
|
||||
ExtCurStyle->exts_globSubstrateName = StrDup((char **)NULL, argv[3]);
|
||||
|
||||
break;
|
||||
case NOPLANEORDER: {
|
||||
if ( ExtCurStyle->exts_planeOrderStatus == seenPlaneOrder )
|
||||
|
|
|
|||
|
|
@ -530,6 +530,64 @@ GeoTransPos(t, pos)
|
|||
return pos;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* GeoTransOrient --
|
||||
* This routine returns the orientation corresponding to a transform.
|
||||
*
|
||||
* Results:
|
||||
* The return value is an orientation as defined by the enumeration
|
||||
* below (which is also used by the LEF read routine). It has to
|
||||
* agree with the enumeration used by dbOrientUseFunc.
|
||||
*
|
||||
* Side Effects: None.
|
||||
*-------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
enum def_orient {ORIENT_NORTH, ORIENT_SOUTH, ORIENT_EAST, ORIENT_WEST,
|
||||
ORIENT_FLIPPED_NORTH, ORIENT_FLIPPED_SOUTH, ORIENT_FLIPPED_EAST,
|
||||
ORIENT_FLIPPED_WEST};
|
||||
|
||||
int
|
||||
GeoTransOrient(t)
|
||||
Transform *t; /* Transform to be applied. */
|
||||
|
||||
{
|
||||
int pidx;
|
||||
|
||||
if ((t->t_b == 0) && (t->t_d == 0))
|
||||
{
|
||||
pidx = ((t->t_a) > 0) ? 1 : 0;
|
||||
pidx += ((t->t_e) > 0) ? 2 : 0;
|
||||
|
||||
switch (pidx) {
|
||||
case 0:
|
||||
return ORIENT_SOUTH;
|
||||
case 1:
|
||||
return ORIENT_FLIPPED_SOUTH;
|
||||
case 2:
|
||||
return ORIENT_FLIPPED_NORTH;
|
||||
case 3:
|
||||
return ORIENT_NORTH;
|
||||
}
|
||||
}
|
||||
else if ((t->t_a == 0) && (t->t_e == 0))
|
||||
{
|
||||
pidx = ((t->t_b) > 0) ? 1 : 0;
|
||||
pidx += ((t->t_d) > 0) ? 2 : 0;
|
||||
|
||||
switch (pidx) {
|
||||
case 0:
|
||||
return ORIENT_FLIPPED_EAST;
|
||||
case 1:
|
||||
return ORIENT_EAST;
|
||||
case 2:
|
||||
return ORIENT_WEST;
|
||||
case 3:
|
||||
return ORIENT_FLIPPED_WEST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* GeoInvertTrans --
|
||||
|
|
|
|||
Loading…
Reference in New Issue