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; MagWindow *w;
TxCommand *cmd; TxCommand *cmd;
{ {
TileType type, rtype; TileType type, rtype, ctype;
TileTypeBitMask *rmask, smask; TileTypeBitMask *rmask, smask;
CCStruct ccs; CCStruct ccs;
Rect area; Rect area;
LinkedRect *lr = NULL;
int cmdContactFunc(); /* Forward declaration */ int cmdContactFunc(); /* Forward declaration */
int cmdContactEraseFunc(); /* Forward declaration */
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID)) if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
@ -2251,13 +2253,78 @@ CmdContact(w, cmd)
return; 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]); TxError("Usage: %s <contact_type>\n", cmd->tx_argv[0]);
return; return;
} }
if (!ToolGetEditBox(&area)) 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]); type = DBTechNoisyNameType(cmd->tx_argv[1]);
if (type >= 0) if (type >= 0)
{ {
@ -2345,6 +2412,27 @@ cmdContactFunc2(tile, ccs)
return 0; 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> <H3>Usage:</H3>
<BLOCKQUOTE> <BLOCKQUOTE>
<B>contact</B> <I>type</I><BR><BR> <B>contact</B> [<B>erase</B>] <I>type</I><BR><BR>
</BLOCKQUOTE> </BLOCKQUOTE>
<H3>Summary:</H3> <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 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 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 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> </BLOCKQUOTE>
<H3>Implementation Notes:</H3> <H3>Implementation Notes:</H3>
<BLOCKQUOTE> <BLOCKQUOTE>
<B>contact</B> is implemented as a built-in layout command in <B>magic</B>. <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> </BLOCKQUOTE>
<H3>See Also:</H3> <H3>See Also:</H3>
<BLOCKQUOTE> <BLOCKQUOTE>
<A HREF=paint.html><B>paint</B></A> <BR> <A HREF=paint.html><B>paint</B></A> <BR>
<A HREF=erase.html><B>erase</B></A> <BR>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><IMG SRC=graphics/line1.gif><P> <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 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 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> </BLOCKQUOTE>
<H3>Implementation Notes:</H3> <H3>Implementation Notes:</H3>
@ -71,6 +76,7 @@ Erase paint from the layout inside the bounds of the cursor box.
<H3>See Also:</H3> <H3>See Also:</H3>
<BLOCKQUOTE> <BLOCKQUOTE>
<A HREF=paint.html><B>paint</B></A> <BR> <A HREF=paint.html><B>paint</B></A> <BR>
<A HREF=contact.html><B>contact</B></A> <BR>
</BLOCKQUOTE> </BLOCKQUOTE>
<P><IMG SRC=graphics/line1.gif><P> <P><IMG SRC=graphics/line1.gif><P>