Extended the wiring section definition to add wire extensions in
addition to wire overlaps, and added a method when painting contacts to draw the necessary wire extension past the contact. Since the wiring method draws single contacts by default, this wiring method assumes a change in direction between layers. But the main point is to generate wire contacts without DRC errors.
This commit is contained in:
parent
5e9f274f65
commit
9ec23203fb
|
|
@ -723,7 +723,8 @@ WireAddContact(newType, newWidth)
|
||||||
CellDef *boxRootDef;
|
CellDef *boxRootDef;
|
||||||
TileType oldType;
|
TileType oldType;
|
||||||
TileTypeBitMask mask, allmask;
|
TileTypeBitMask mask, allmask;
|
||||||
int oldOverlap, newOverlap, i, totalSize, oldDir;
|
int oldOverlap, newOverlap, oldExtend, newExtend;
|
||||||
|
int i, totalSize, oldDir;
|
||||||
Contact *contact;
|
Contact *contact;
|
||||||
SearchContext scx;
|
SearchContext scx;
|
||||||
|
|
||||||
|
|
@ -769,6 +770,8 @@ WireAddContact(newType, newWidth)
|
||||||
{
|
{
|
||||||
oldOverlap = contact->con_surround1;
|
oldOverlap = contact->con_surround1;
|
||||||
newOverlap = contact->con_surround2;
|
newOverlap = contact->con_surround2;
|
||||||
|
oldExtend = contact->con_extend1;
|
||||||
|
newExtend = contact->con_extend2;
|
||||||
goto gotContact;
|
goto gotContact;
|
||||||
}
|
}
|
||||||
if ((contact->con_layer2 == oldType) &&
|
if ((contact->con_layer2 == oldType) &&
|
||||||
|
|
@ -776,10 +779,12 @@ WireAddContact(newType, newWidth)
|
||||||
{
|
{
|
||||||
oldOverlap = contact->con_surround2;
|
oldOverlap = contact->con_surround2;
|
||||||
newOverlap = contact->con_surround1;
|
newOverlap = contact->con_surround1;
|
||||||
|
oldExtend = contact->con_extend2;
|
||||||
|
newExtend = contact->con_extend1;
|
||||||
goto gotContact;
|
goto gotContact;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TxError("Sorry, but the technology file doesn't define a contact\n");
|
TxError("The technology file doesn't define a contact\n");
|
||||||
TxError(" between \"%s\" and \"%s\".\n", DBTypeLongName(oldType),
|
TxError(" between \"%s\" and \"%s\".\n", DBTypeLongName(oldType),
|
||||||
DBTypeLongName(WireType));
|
DBTypeLongName(WireType));
|
||||||
return;
|
return;
|
||||||
|
|
@ -793,18 +798,18 @@ WireAddContact(newType, newWidth)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gotContact:
|
gotContact:
|
||||||
totalSize = contact->con_size + 2*oldOverlap;
|
totalSize = contact->con_size + 2 * oldOverlap;
|
||||||
contactArea = oldLeg;
|
contactArea = oldLeg;
|
||||||
if ((contactArea.r_xtop - contactArea.r_xbot) < totalSize)
|
if ((contactArea.r_xtop - contactArea.r_xbot) < totalSize)
|
||||||
{
|
{
|
||||||
contactArea.r_xbot -= (totalSize - (contactArea.r_xtop
|
contactArea.r_xbot -= (totalSize - (contactArea.r_xtop
|
||||||
- contactArea.r_xbot))/2;
|
- contactArea.r_xbot)) / 2;
|
||||||
contactArea.r_xtop = contactArea.r_xbot + totalSize;
|
contactArea.r_xtop = contactArea.r_xbot + totalSize;
|
||||||
}
|
}
|
||||||
if ((contactArea.r_ytop - contactArea.r_ybot) < totalSize)
|
if ((contactArea.r_ytop - contactArea.r_ybot) < totalSize)
|
||||||
{
|
{
|
||||||
contactArea.r_ybot -= (totalSize - (contactArea.r_ytop
|
contactArea.r_ybot -= (totalSize - (contactArea.r_ytop
|
||||||
- contactArea.r_ybot))/2;
|
- contactArea.r_ybot)) / 2;
|
||||||
contactArea.r_ytop = contactArea.r_ybot + totalSize;
|
contactArea.r_ytop = contactArea.r_ybot + totalSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -855,6 +860,48 @@ WireAddContact(newType, newWidth)
|
||||||
(void) GeoInclude(&tmp2, &editArea);
|
(void) GeoInclude(&tmp2, &editArea);
|
||||||
DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0);
|
DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0);
|
||||||
}
|
}
|
||||||
|
if (contact->con_extend1 != 0)
|
||||||
|
{
|
||||||
|
TTMaskSetOnlyType(&mask, contact->con_layer1);
|
||||||
|
TTMaskSetType(&allmask, contact->con_layer1);
|
||||||
|
tmp2 = tmp;
|
||||||
|
switch(oldDir)
|
||||||
|
{
|
||||||
|
case GEO_NORTH:
|
||||||
|
case GEO_SOUTH:
|
||||||
|
tmp2.r_ybot -= contact->con_extend1;
|
||||||
|
tmp2.r_ytop += contact->con_extend1;
|
||||||
|
break;
|
||||||
|
case GEO_EAST:
|
||||||
|
case GEO_WEST:
|
||||||
|
tmp2.r_xbot -= contact->con_extend1;
|
||||||
|
tmp2.r_xtop += contact->con_extend1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) GeoInclude(&tmp2, &editArea);
|
||||||
|
DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0);
|
||||||
|
}
|
||||||
|
if (contact->con_extend2 != 0)
|
||||||
|
{
|
||||||
|
TTMaskSetOnlyType(&mask, contact->con_layer2);
|
||||||
|
TTMaskSetType(&allmask, contact->con_layer2);
|
||||||
|
tmp2 = tmp;
|
||||||
|
switch(oldDir)
|
||||||
|
{
|
||||||
|
case GEO_NORTH:
|
||||||
|
case GEO_SOUTH:
|
||||||
|
tmp2.r_xbot -= contact->con_extend2;
|
||||||
|
tmp2.r_xtop += contact->con_extend2;
|
||||||
|
break;
|
||||||
|
case GEO_EAST:
|
||||||
|
case GEO_WEST:
|
||||||
|
tmp2.r_ybot -= contact->con_extend2;
|
||||||
|
tmp2.r_ytop += contact->con_extend2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) GeoInclude(&tmp2, &editArea);
|
||||||
|
DBPaintValid(EditCellUse->cu_def, &tmp2, &mask, 0);
|
||||||
|
}
|
||||||
|
|
||||||
DBAdjustLabels(EditCellUse->cu_def, &editArea);
|
DBAdjustLabels(EditCellUse->cu_def, &editArea);
|
||||||
DBWAreaChanged(EditCellUse->cu_def, &editArea, DBW_ALLWINDOWS, &allmask);
|
DBWAreaChanged(EditCellUse->cu_def, &editArea, DBW_ALLWINDOWS, &allmask);
|
||||||
|
|
|
||||||
|
|
@ -91,22 +91,25 @@ WireTechLine(sectionName, argc, argv)
|
||||||
char *argv[]; /* Pointers to fields of line. */
|
char *argv[]; /* Pointers to fields of line. */
|
||||||
{
|
{
|
||||||
Contact *new;
|
Contact *new;
|
||||||
|
int hasExtend = 0;
|
||||||
|
|
||||||
if (strcmp(argv[0], "contact") != 0)
|
if (strcmp(argv[0], "contact") != 0)
|
||||||
{
|
{
|
||||||
TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]);
|
TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (argc != 7)
|
if ((argc != 7) && (argc != 9))
|
||||||
{
|
{
|
||||||
TechError("\"contact\" lines must have exactly 7 arguments.\n");
|
TechError("\"contact\" lines must have exactly 7 or 9 arguments.\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
if (argc == 9) hasExtend = 1;
|
||||||
|
|
||||||
new = (Contact *) mallocMagic(sizeof(Contact));
|
new = (Contact *) mallocMagic(sizeof(Contact));
|
||||||
new->con_type = DBTechNoisyNameType(argv[1]);
|
new->con_type = DBTechNoisyNameType(argv[1]);
|
||||||
new->con_layer1 = DBTechNoisyNameType(argv[3]);
|
new->con_layer1 = DBTechNoisyNameType(argv[3]);
|
||||||
new->con_layer2 = DBTechNoisyNameType(argv[5]);
|
new->con_layer2 = DBTechNoisyNameType(argv[5 + hasExtend]);
|
||||||
|
new->con_extend1 = new->con_extend2 = 0;
|
||||||
if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0))
|
if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0))
|
||||||
{
|
{
|
||||||
errorReturn:
|
errorReturn:
|
||||||
|
|
@ -116,22 +119,38 @@ WireTechLine(sectionName, argc, argv)
|
||||||
|
|
||||||
if (!StrIsInt(argv[2]))
|
if (!StrIsInt(argv[2]))
|
||||||
{
|
{
|
||||||
TechError("3rd field must be an integer.\n");
|
TechError("Contact size must be an integer.\n");
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
}
|
}
|
||||||
else new->con_size = atoi(argv[2]);
|
else new->con_size = atoi(argv[2]);
|
||||||
if (!StrIsInt(argv[4]))
|
if (!StrIsInt(argv[4]))
|
||||||
{
|
{
|
||||||
TechError("5th field must be an integer.\n");
|
TechError("Contact surround distance must be an integer.\n");
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
}
|
}
|
||||||
else new->con_surround1 = atoi(argv[4]);
|
else new->con_surround1 = atoi(argv[4]);
|
||||||
if (!StrIsInt(argv[6]))
|
if (!StrIsInt(argv[6 + hasExtend]))
|
||||||
{
|
{
|
||||||
TechError("6th field must be an integer.\n");
|
TechError("Contact surround distance must be an integer.\n");
|
||||||
goto errorReturn;
|
goto errorReturn;
|
||||||
}
|
}
|
||||||
else new->con_surround2 = atoi(argv[6]);
|
else new->con_surround2 = atoi(argv[6 + hasExtend]);
|
||||||
|
|
||||||
|
if (argc == 9)
|
||||||
|
{
|
||||||
|
if (!StrIsInt(argv[5]))
|
||||||
|
{
|
||||||
|
TechError("Contact extend distance must be an integer.\n");
|
||||||
|
goto errorReturn;
|
||||||
|
}
|
||||||
|
else new->con_extend1 = atoi(argv[5]);
|
||||||
|
if (!StrIsInt(argv[8]))
|
||||||
|
{
|
||||||
|
TechError("Contact extend distance must be an integer.\n");
|
||||||
|
goto errorReturn;
|
||||||
|
}
|
||||||
|
else new->con_extend2 = atoi(argv[8]);
|
||||||
|
}
|
||||||
|
|
||||||
new->con_next = WireContacts;
|
new->con_next = WireContacts;
|
||||||
WireContacts = new;
|
WireContacts = new;
|
||||||
|
|
@ -201,5 +220,11 @@ WireTechScale(scalen, scaled)
|
||||||
|
|
||||||
con->con_surround2 *= scaled;
|
con->con_surround2 *= scaled;
|
||||||
con->con_surround2 /= scalen;
|
con->con_surround2 /= scalen;
|
||||||
|
|
||||||
|
con->con_extend1 *= scaled;
|
||||||
|
con->con_extend1 /= scalen;
|
||||||
|
|
||||||
|
con->con_extend2 *= scaled;
|
||||||
|
con->con_extend2 /= scalen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
||||||
/*
|
|
||||||
* wireTech.c --
|
|
||||||
*
|
|
||||||
* This file contains procedures that parse the wiring sections of
|
|
||||||
* technology files.
|
|
||||||
*
|
|
||||||
* *********************************************************************
|
|
||||||
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
||||||
* * Permission to use, copy, modify, and distribute this *
|
|
||||||
* * software and its documentation for any purpose and without *
|
|
||||||
* * fee is hereby granted, provided that the above copyright *
|
|
||||||
* * notice appear in all copies. The University of California *
|
|
||||||
* * makes no representations about the suitability of this *
|
|
||||||
* * software for any purpose. It is provided "as is" without *
|
|
||||||
* * express or implied warranty. Export of this software outside *
|
|
||||||
* * of the United States of America may require an export license. *
|
|
||||||
* *********************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef lint
|
|
||||||
static char rcsid[]="$Header: /usr/cvsroot/magic-8.0/wiring/wireTech.c.new,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
||||||
#endif /* not lint */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "utils/magic.h"
|
|
||||||
#include "utils/geometry.h"
|
|
||||||
#include "tiles/tile.h"
|
|
||||||
#include "utils/hash.h"
|
|
||||||
#include "database/database.h"
|
|
||||||
#include "tech/tech.h"
|
|
||||||
#include "wiring/wiring.h"
|
|
||||||
#include "utils/malloc.h"
|
|
||||||
|
|
||||||
/* Linked list to store contact information collected by this module: */
|
|
||||||
Contact *WireContacts;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* WireTechInit --
|
|
||||||
*
|
|
||||||
* Called once at beginning of technology file read-in to initialize
|
|
||||||
* data structures.
|
|
||||||
*
|
|
||||||
* Results:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* Clears out the contact table.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
WireTechInit()
|
|
||||||
{
|
|
||||||
Contact *contact;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
while (WireContacts != NULL)
|
|
||||||
{
|
|
||||||
freeMagic((char *) WireContacts);
|
|
||||||
WireContacts = WireContacts->con_next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* WireTechLine --
|
|
||||||
*
|
|
||||||
* This procedure is invoked by the technology module once for
|
|
||||||
* each line in the "wiring" section of the technology file.
|
|
||||||
*
|
|
||||||
* Results:
|
|
||||||
* Always returns TRUE (otherwise the technology module would
|
|
||||||
* abort Magic with a fatal error).
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* Builds up the contact table, prints error messages if necessary.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
|
||||||
bool
|
|
||||||
WireTechLine(sectionName, argc, argv)
|
|
||||||
char *sectionName; /* Name of this section (unused). */
|
|
||||||
int argc; /* Number of arguments on line. */
|
|
||||||
char *argv[]; /* Pointers to fields of line. */
|
|
||||||
{
|
|
||||||
Contact *new;
|
|
||||||
|
|
||||||
if (strcmp(argv[0], "contact") != 0)
|
|
||||||
{
|
|
||||||
TechError("Unknown wiring keyword: %s. Line ignored.\n", argv[0]);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
if (argc != 7)
|
|
||||||
{
|
|
||||||
TechError("\"contact\" lines must have exactly 7 arguments.\n");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
new = (Contact *) mallocMagic(sizeof(Contact));
|
|
||||||
new->con_type = DBTechNoisyNameType(argv[1]);
|
|
||||||
new->con_layer1 = DBTechNoisyNameType(argv[3]);
|
|
||||||
new->con_layer2 = DBTechNoisyNameType(argv[5]);
|
|
||||||
if ((new->con_type < 0) || (new->con_layer1 < 0) || (new->con_layer2 < 0))
|
|
||||||
{
|
|
||||||
errorReturn:
|
|
||||||
freeMagic((char *) new);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StrIsInt(argv[2]))
|
|
||||||
{
|
|
||||||
TechError("3rd field must be an integer.\n");
|
|
||||||
goto errorReturn;
|
|
||||||
}
|
|
||||||
else new->con_size = atoi(argv[2]);
|
|
||||||
if (!StrIsInt(argv[4]))
|
|
||||||
{
|
|
||||||
TechError("5th field must be an integer.\n");
|
|
||||||
goto errorReturn;
|
|
||||||
}
|
|
||||||
else new->con_surround1 = atoi(argv[4]);
|
|
||||||
if (!StrIsInt(argv[6]))
|
|
||||||
{
|
|
||||||
TechError("6th field must be an integer.\n");
|
|
||||||
goto errorReturn;
|
|
||||||
}
|
|
||||||
else new->con_surround2 = atoi(argv[6]);
|
|
||||||
|
|
||||||
new->con_next = WireContacts;
|
|
||||||
WireContacts = new;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* WireTechFinal --
|
|
||||||
*
|
|
||||||
* This procedure is called by the technology module after all the
|
|
||||||
* lines of the tech file have been read. It doesn't do anything
|
|
||||||
* right now.
|
|
||||||
*
|
|
||||||
* Results:
|
|
||||||
* None.
|
|
||||||
*
|
|
||||||
* Side effects:
|
|
||||||
* None.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
WireTechFinal()
|
|
||||||
{
|
|
||||||
/* Debugging code to print info about layers: */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Contact *con;
|
|
||||||
|
|
||||||
for (con = WireContacts; con != NULL; con = con->con_next)
|
|
||||||
{
|
|
||||||
TxPrintf("Contact type \"%s\", size %d connects\n",
|
|
||||||
DBTypeLongName(con->con_type), con->con_size);
|
|
||||||
TxPrintf(" \"%s\" (overlap %d) and\n",
|
|
||||||
DBTypeLongName(con->con_layer1), con->con_surround1);
|
|
||||||
TxPrintf(" \"%s\" (overlap %d)\n",
|
|
||||||
DBTypeLongName(con->con_layer2), con->con_surround2);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
*----------------------------------------------------------------------------
|
|
||||||
* WireTechScale --
|
|
||||||
*
|
|
||||||
* Change parameters of the wiring section as required when
|
|
||||||
* redefining magic's internal grid relative to the technology lambda.
|
|
||||||
*
|
|
||||||
*----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
int
|
|
||||||
WireTechScale(scalen, scaled)
|
|
||||||
int scalen, scaled;
|
|
||||||
{
|
|
||||||
Contact *con;
|
|
||||||
|
|
||||||
for (con = WireContacts; con != NULL; con = con->con_next)
|
|
||||||
{
|
|
||||||
con->con_size *= scalen;
|
|
||||||
con->con_size /= scaled;
|
|
||||||
|
|
||||||
con->con_surround1 *= scalen;
|
|
||||||
con->con_surround1 /= scaled;
|
|
||||||
|
|
||||||
con->con_surround2 *= scalen;
|
|
||||||
con->con_surround2 /= scaled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -48,10 +48,15 @@ typedef struct _Contact
|
||||||
* con_layer1 must be painted around the
|
* con_layer1 must be painted around the
|
||||||
* edge of the contact.
|
* edge of the contact.
|
||||||
*/
|
*/
|
||||||
|
int con_extend1; /* How much additional material of type
|
||||||
|
* con_layer1 must extend beyond the
|
||||||
|
* contact in the orientation of the route.
|
||||||
|
*/
|
||||||
TileType con_layer2; /* Same information for second layer that
|
TileType con_layer2; /* Same information for second layer that
|
||||||
* the contact connects.
|
* the contact connects.
|
||||||
*/
|
*/
|
||||||
int con_surround2;
|
int con_surround2;
|
||||||
|
int con_extend2;
|
||||||
|
|
||||||
ContactPtr con_next; /* Pointer to next contact record */
|
ContactPtr con_next; /* Pointer to next contact record */
|
||||||
} Contact;
|
} Contact;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue