Added a new command option "contact erase". This provides a way to

remove contact cuts from a layout without affecting the surrounding
metals, which is something that the "erase" command does not do.
This commit is contained in:
Tim Edwards 2022-04-07 11:10:24 -04:00
parent 44df4fc125
commit 9402b0dcdd
4 changed files with 107 additions and 9 deletions

View File

@ -1 +1 @@
8.3.288
8.3.289

View File

@ -2238,11 +2238,13 @@ CmdContact(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
TileType type, rtype;
TileType type, rtype, ctype;
TileTypeBitMask *rmask, smask;
CCStruct ccs;
Rect area;
LinkedRect *lr = NULL;
int cmdContactFunc(); /* Forward declaration */
int cmdContactEraseFunc(); /* Forward declaration */
windCheckOnlyWindow(&w, DBWclientID);
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
@ -2251,13 +2253,78 @@ CmdContact(w, cmd)
return;
}
if (cmd->tx_argc != 2)
if ((cmd->tx_argc != 2) && (cmd->tx_argc != 3))
{
TxError("Usage: %s <contact_type>\n", cmd->tx_argv[0]);
return;
}
if (!ToolGetEditBox(&area)) return;
if (EditCellUse == NULL)
{
TxError("The cell in the window is not editable.\n");
return;
}
if (cmd->tx_argc == 3)
{
if (!strcmp(cmd->tx_argv[1], "erase"))
{
/* Erase a contact from the area of the box. This acts */
/* differently from the "erase" command. "erase" will */
/* remove the contact and leave nothing behind. "contact */
/* erase" will remove the contact and leave the residues */
/* behind. The main difference is that this action cannot */
/* be done on a whole area; the individual contacts need */
/* to be enumerated and the erase/paint done on each one. */
type = DBTechNoisyNameType(cmd->tx_argv[2]);
if (!DBIsContact(type))
{
TxError("Error: tile type \"%s\" is not a contact.\n",
cmd->tx_argv[2]);
return;
}
TTMaskSetOnlyType(&smask, type);
/* Add all stacked contact types containing "type" */
for (ctype = DBNumUserLayers; ctype < DBNumTypes; ctype++)
{
rmask = DBResidueMask(ctype);
if (TTMaskHasType(rmask, ctype))
TTMaskSetMask(&smask, rmask);
}
/* Enumerate all tiles inside the box area containing contact "type" */
DBSrPaintArea((Tile *) NULL, EditCellUse->cu_def->cd_planes[DBPlane(type)],
&area, &smask, cmdContactEraseFunc, (ClientData)&lr);
rmask = DBResidueMask(type);
while (lr != NULL)
{
GeoClip(&lr->r_r, &area);
/* Erase contact type "type" and repaint with the residues */
DBErase(EditCellUse->cu_def, &lr->r_r, type);
for (rtype = 0; rtype < DBNumUserLayers; rtype++)
if (TTMaskHasType(rmask, rtype))
DBPaint(EditCellUse->cu_def, &lr->r_r, rtype);
freeMagic(lr);
lr = lr->r_next;
}
/* Refresh the layout drawing */
DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask);
DRCCheckThis (EditCellUse->cu_def, TT_CHECKPAINT, &area);
}
else
TxError("Usage: %s erase <contact_type>\n", cmd->tx_argv[0]);
return;
}
type = DBTechNoisyNameType(cmd->tx_argv[1]);
if (type >= 0)
{
@ -2345,6 +2412,27 @@ cmdContactFunc2(tile, ccs)
return 0;
}
/* For each contact tile found, attach the area to a LinkedRect structure
*/
int
cmdContactEraseFunc(tile, lr)
Tile *tile;
LinkedRect **lr;
{
LinkedRect *newlr;
Rect area;
newlr = (LinkedRect *)mallocMagic(sizeof(LinkedRect));
newlr->r_type = TiGetType(tile);
TiToRect(tile, &newlr->r_r);
newlr->r_next = *lr;
*lr = newlr;
return 0;
}
/*
* ----------------------------------------------------------------------------
*

View File

@ -25,7 +25,7 @@ Paint a contact at the intersection of two layers.
<H3>Usage:</H3>
<BLOCKQUOTE>
<B>contact</B> <I>type</I><BR><BR>
<B>contact</B> [<B>erase</B>] <I>type</I><BR><BR>
</BLOCKQUOTE>
<H3>Summary:</H3>
@ -33,20 +33,24 @@ Paint a contact at the intersection of two layers.
The <B>contact</B> command computes the intersection area (inside the
cursor box) of the two (or more) residue types that make up the contact
type <I>type</I>, and paints the contact type <I>type</I> on top of the
area of intersection.
area of intersection. <P>
Option <B>contact erase</B> erases contacts from the area of the cursor
box without affecting the metal layers (or stacked contacts) surrounding
the contact being erased. (Note that the <B>erase</B> command will
remove both the contact type and the surrounding metal layers.)
</BLOCKQUOTE>
<H3>Implementation Notes:</H3>
<BLOCKQUOTE>
<B>contact</B> is implemented as a built-in layout command in <B>magic</B>.
As of magic version 7.3.115 this command does not correctly translate the
cursor box for edit cells and may paint outside of the cursor box, with
random results.
</BLOCKQUOTE>
<H3>See Also:</H3>
<BLOCKQUOTE>
<A HREF=paint.html><B>paint</B></A> <BR>
<A HREF=erase.html><B>erase</B></A> <BR>
</BLOCKQUOTE>
<P><IMG SRC=graphics/line1.gif><P>

View File

@ -60,7 +60,12 @@ Erase paint from the layout inside the bounds of the cursor box.
The option "<B>erase cursor</B>" picks the layers at the position
of the (X11) cursor and erases these from the area of the cursor
box.
box. <P>
Note that when applied to contact types, "<B>erase</B>" will erase
the entire contact, including the top and bottom metal types
comprising the contact. To remove the contact cuts without affecting
the surrounding material, use the "<B>contact erase</B>" command. <P>
</BLOCKQUOTE>
<H3>Implementation Notes:</H3>
@ -71,6 +76,7 @@ Erase paint from the layout inside the bounds of the cursor box.
<H3>See Also:</H3>
<BLOCKQUOTE>
<A HREF=paint.html><B>paint</B></A> <BR>
<A HREF=contact.html><B>contact</B></A> <BR>
</BLOCKQUOTE>
<P><IMG SRC=graphics/line1.gif><P>