magic/gcr/gcrInit.c

399 lines
9.5 KiB
C
Raw Normal View History

/* gcrInit.c -
*
* Initialization for the greedy router.
*
* *********************************************************************
* * 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[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/gcr/gcrInit.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "utils/hash.h"
#include "utils/heap.h"
#include "tiles/tile.h"
#include "database/database.h"
#include "router/router.h"
#include "gcr/gcr.h"
#include "utils/malloc.h"
int GCRSteadyNet =1; /*Values get imported from main*/
int GCREndDist =1;
int GCRMinJog =1;
int GCRsplitAt =0;
bool GcrShowResult =FALSE;
bool GcrNoCheck =TRUE;
bool GcrDebug =FALSE;
#ifndef lint
float GCRObstDist = 0.7;
#else
float GCRObstDist; /* Sun lint brain death */
#endif /* lint */
/* Forward declarations */
void gcrLinkPin();
/*
* ----------------------------------------------------------------------------
*
* gcrSetEndDist --
*
* Set the global variable specifying how soon the router starts to get
* nets into tracks for end connections.
*
* Get the number of end connections as a percentage of the width of
* the channel. Add extra for multipin end connections.
*
* Results:
* None.
*
* Side effects:
* Changes GCREndDist.
*
* ----------------------------------------------------------------------------
*/
void
gcrSetEndDist(ch)
GCRChannel *ch; /* The channel to be routed */
{
int rightTotal, multiTotal;
GCRNet *net;
GCRPin *pin;
int count;
/*
* Do this the easy way.
* Enumerate each net and look at its pins, starting
* from the rightmost.
*/
rightTotal = 0;
multiTotal = 0;
for (net = ch->gcr_nets; net; net = net->gcr_next)
{
count = 0;
for (pin = net->gcr_rPin; pin; pin = pin->gcr_pPrev, count++)
if (pin->gcr_x <= ch->gcr_length)
break;
rightTotal += count;
if (count > 1)
multiTotal++;
}
GCREndDist = (multiTotal/2 + rightTotal/4) * RtrEndConst;
if (GCREndDist < 1) GCREndDist = 1;
}
/*
* ----------------------------------------------------------------------------
*
* gcrBuildNets --
*
* Scan the top, bot, left, and right pin arrays, setting pointers to
* the left and right pins for each net. Sets pointers within the
* pin arrays to point to next and previous pins.
*
* Results:
* None.
*
* Side effects:
* Allocates and initializes storage for nets.
*
* ----------------------------------------------------------------------------
*/
void
gcrBuildNets(ch)
GCRChannel * ch;
{
HashTable ht;
int i;
/*
* Initialize the hash table that maps net ids to GCRNet structs.
* The table is keyed by 2 words: seg/net.
*/
HashInit(&ht, 256, 2);
for (i = 1; i <= ch->gcr_width; i++)
gcrLinkPin(&ch->gcr_lPins[i], &ht, ch);
for (i = 1; i <= ch->gcr_length; i++)
{
gcrLinkPin(&ch->gcr_bPins[i], &ht, ch);
gcrLinkPin(&ch->gcr_tPins[i], &ht, ch);
}
for (i = 1; i <= ch->gcr_width; i++)
gcrLinkPin(&ch->gcr_rPins[i], &ht, ch);
HashKill(&ht);
}
/*
* ----------------------------------------------------------------------------
*
* gcrLinkPin --
*
* Establish the forward and backward links for a pin on the edge of
* a channel.
*
* Results:
* None.
*
* Side effects:
* The pin is added to the end of the list for its net. A
* new net structure is created if one doesn't already
* exist.
*
* ----------------------------------------------------------------------------
*/
void
gcrLinkPin(pin, ht, ch)
GCRPin *pin;
HashTable *ht;
GCRChannel *ch;
{
GCRNet *net;
GCRNet *gcrNewNet();
HashEntry *hEntry;
/*
* GCR_BLOCKEDNETID means that the crossing was blocked.
* Restore these crossings to "empty".
*/
if (pin->gcr_pId == GCR_BLOCKEDNETID) pin->gcr_pId = (GCRNet *) NULL;
/* Skip empty pins */
if (pin->gcr_pId == (GCRNet *) NULL)
return;
/* Find the 2-word seg/net key */
hEntry = HashFind(ht, (char *) &(pin->gcr_pSeg));
net = (GCRNet *) HashGetValue(hEntry);
if (net == (GCRNet *) NULL)
{
/* New net */
net = (GCRNet *) mallocMagic((unsigned) (sizeof (GCRNet)));
HashSetValue(hEntry, (char *) net);
net->gcr_Id = (spointertype) pin->gcr_pId;
/* Link net onto channel net list */
net->gcr_next = ch->gcr_nets;
ch->gcr_nets = net;
/* Link pin onto net pin list */
net->gcr_lPin = net->gcr_rPin= pin;
pin->gcr_pPrev = (GCRPin *) NULL;
}
else
{
/* Old net. Add to end of net's list. */
net->gcr_rPin->gcr_pNext = pin;
pin->gcr_pPrev = net->gcr_rPin;
net->gcr_rPin = pin;
}
pin->gcr_pId = net;
pin->gcr_pNext = (GCRPin *) NULL;
}
/*
* ----------------------------------------------------------------------------
*
* gcrUnlinkPin --
*
* Remove a pin from the pin list for a net. The pin had better
* be the first pin of its net.
*
* Results:
* None.
*
* Side effects:
* The pin is removed from the list associated with its net.
*
* ----------------------------------------------------------------------------
*/
void
gcrUnlinkPin(pin)
GCRPin *pin;
{
GCRNet *net;
17 x warning: suggest parentheses around assignment used as truth value gaStem.c:225:9: warning: suggest parentheses around assignment used as truth value gaStem.c:350:9: warning: suggest parentheses around assignment used as truth value grouteMain.c:363:12: warning: suggest parentheses around assignment used as truth value grouteMaze.c:573:17: warning: suggest parentheses around assignment used as truth value groutePath.c:127:13: warning: suggest parentheses around assignment used as truth value irCommand.c:901:12: warning: suggest parentheses around assignment used as truth value irCommand.c:999:12: warning: suggest parentheses around assignment used as truth value irCommand.c:1275:13: warning: suggest parentheses around assignment used as truth value irCommand.c:1375:13: warning: suggest parentheses around assignment used as truth value irCommand.c:1931:17: warning: suggest parentheses around assignment used as truth value rtrDcmpose.c:435:12: warning: suggest parentheses around assignment used as truth value rtrPin.c:174:17: warning: suggest parentheses around assignment used as truth value rtrStem.c:373:21: warning: suggest parentheses around assignment used as truth value rtrStem.c:479:9: warning: suggest parentheses around assignment used as truth value rtrStem.c:952:17: warning: suggest parentheses around assignment used as truth value gcrInit.c:239:9: warning: suggest parentheses around assignment used as truth value net2ir.c:123:13: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:24:07 +02:00
if ((net = pin->gcr_pId))
{
ASSERT(pin == net->gcr_lPin, "gcrUnlinkPin");
net->gcr_lPin = pin->gcr_pNext;
if (pin->gcr_pNext)
pin->gcr_pNext->gcr_pPrev = pin->gcr_pPrev;
}
}
/*
* ----------------------------------------------------------------------------
*
* gcrDensity --
*
* Determine the channel density at every column. Starting at the left
* end of the channel with density=0, the density of the next column is
* the current density plus the number of nets with first pin in the
* current column minus the number of nets with last pin in the previous
* column.
*
* Must be called AFTER gcrBuildNets.
*
* Results:
* Returns the maximum column density.
*
* Side effects:
* Allocates storage for the density array GCRDensity and stores densities.
*
* ----------------------------------------------------------------------------
*/
int
gcrDensity(ch)
GCRChannel *ch;
{
int density, i, last, maxVal;
unsigned lenWds;
last = 0;
density = 0;
for (i = 1; i <= ch->gcr_width; i++)
if (ch->gcr_lPins[i].gcr_pId)
{
if (Is1stPin(&ch->gcr_lPins[i])) density++;
if (IsLstPin(&ch->gcr_lPins[i])) last++;
}
lenWds = ch->gcr_length + 2;
if (ch->gcr_density == (int *) NULL)
{
ch->gcr_density = (int *) mallocMagic((unsigned) (lenWds * sizeof (int)));
}
ch->gcr_density[0] = maxVal = density;
for (i = 1; i <= ch->gcr_length; i++)
{
density = density - last;
last = 0;
if (ch->gcr_tPins[i].gcr_pId)
{
if (Is1stPin(&ch->gcr_tPins[i])) density++;
else if (IsLstPin(&ch->gcr_tPins[i])) last++;
}
if (ch->gcr_bPins[i].gcr_pId)
{
if (Is1stPin(&ch->gcr_bPins[i])) density++;
else if (IsLstPin(&ch->gcr_bPins[i]))
{
if (ch->gcr_tPins[i].gcr_pId == ch->gcr_bPins[i].gcr_pId)
density--;
else last++;
}
}
ch->gcr_density[i] = density;
if (density > maxVal)
maxVal = density;
}
return (maxVal);
}
/*
* ----------------------------------------------------------------------------
*
* gcrInitCol --
*
* Initialize the column structure to hold the configuration at
* the left side of the channel.
*
* Results:
* None.
*
* Side effects:
* Pointers are updated in the column data structure.
* Changes the track field of each net struct.
*
* ----------------------------------------------------------------------------
*/
void
gcrInitCol(ch, edgeArray)
GCRChannel *ch;
GCRPin *edgeArray; /* Nets at left edge of channel if non-NULL */
{
GCRNet *net;
GCRColEl *col;
int i, widWds;
col = ch->gcr_lCol;
/* Assign column tracks using an optionally provided pin array */
if (edgeArray)
{
col[0].gcr_h = (GCRNet *) NULL;
for (i = 1; i <= ch->gcr_width; i++)
{
col[i].gcr_h = edgeArray[i].gcr_pId;
/* Delete pin from net's pin list */
gcrUnlinkPin(&edgeArray[i]);
}
col[ch->gcr_width+1].gcr_h = (GCRNet *) NULL;
}
/* Initialize the hi and lo pointers for the column data structure */
for (net = ch->gcr_nets; net; net = net->gcr_next)
net->gcr_track = EMPTY;
widWds = ch->gcr_width + 1;
for (i = 0; i <= widWds; i++)
{
col[i].gcr_v = (GCRNet *) NULL;
col[i].gcr_hi = EMPTY;
col[i].gcr_lo = EMPTY;
col[i].gcr_hOk =FALSE;
col[i].gcr_lOk =FALSE;
col[i].gcr_wanted = (GCRNet *) NULL;
col[i].gcr_flags = 0;
net = col[i].gcr_h;
if (net)
{
if (net->gcr_track == EMPTY) /* 1st track */
col[i].gcr_h->gcr_track = i;
else
{
col[i].gcr_lo = net->gcr_track;
col[net->gcr_track].gcr_hi = i;
net->gcr_track = i;
}
}
}
/* Mark tracks needed to make some end connection */
for (i = 1; i <= ch->gcr_width; i++)
gcrWanted(ch, i, 0);
}