180 lines
5.1 KiB
C
180 lines
5.1 KiB
C
/*
|
|
* gcrRiver.c -
|
|
*
|
|
* The greedy router: river-routing across the tops of channels.
|
|
*
|
|
* *********************************************************************
|
|
* * 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/gcrRiver.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 "gcr/gcr.h"
|
|
#include "textio/textio.h"
|
|
#include "utils/malloc.h"
|
|
|
|
/* Forward declarations */
|
|
bool gcrOverCellVert();
|
|
bool gcrOverCellHoriz();
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* gcrRiverRoute --
|
|
*
|
|
* Determine if a channel should be routed by a simple river-router;
|
|
* if so, then route it. Currently, river-routing channels are identified
|
|
* during channel decomposition.
|
|
*
|
|
* Results:
|
|
* Returns TRUE on success, FALSE on failure (in which case
|
|
* the caller should try to route the channel by other means.
|
|
*
|
|
* Side effects:
|
|
* If successful, sets flags in the channel structure to show
|
|
* where routing is to be placed.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
bool
|
|
gcrRiverRoute(ch)
|
|
GCRChannel *ch;
|
|
{
|
|
switch (ch->gcr_type)
|
|
{
|
|
case CHAN_HRIVER:
|
|
if (gcrOverCellHoriz(ch))
|
|
return (TRUE);
|
|
break;
|
|
case CHAN_VRIVER:
|
|
if (gcrOverCellVert(ch))
|
|
return (TRUE);
|
|
break;
|
|
}
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* gcrOverCellHoriz --
|
|
* gcrOverCellVert --
|
|
*
|
|
* Route an over-cell channel if possible. These channels should be
|
|
* river-routable. We perform a few quick checks to ensure that there
|
|
* are terminals only on opposite sides in pairs. Channels routed
|
|
* horizontally are processed by gcrOverCellHoriz(); those routed
|
|
* vertically are processed by gcrOverCellVert().
|
|
*
|
|
* Results:
|
|
* TRUE if the channel met our requirements and we routed it
|
|
* successfully; FALSE if we couldn't route it.
|
|
*
|
|
* Side effects:
|
|
* Sets flags in the channel structure to show where routing
|
|
* is to be placed.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
#define USED(pin) \
|
|
((pin)->gcr_pId != (GCRNet *) 0 && (pin)->gcr_pId != (GCRNet *) -1)
|
|
|
|
bool
|
|
gcrOverCellHoriz(ch)
|
|
GCRChannel *ch;
|
|
{
|
|
short **result = ch->gcr_result;
|
|
int col, row;
|
|
|
|
/* Ensure top and bottom pins aren't used */
|
|
for (col = 1; col <= ch->gcr_length; col++)
|
|
if (USED(&ch->gcr_tPins[col]) || USED(&ch->gcr_bPins[col]))
|
|
{
|
|
TxPrintf("Failing because top or bottom pins are used\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
/* Ensure left and right pins match */
|
|
for (row = 1; row <= ch->gcr_width; row++)
|
|
if (USED(&ch->gcr_lPins[row]) && USED(&ch->gcr_rPins[row]))
|
|
{
|
|
if (ch->gcr_lPins[row].gcr_pId != ch->gcr_rPins[row].gcr_pId
|
|
|| ch->gcr_lPins[row].gcr_pSeg != ch->gcr_rPins[row].gcr_pSeg)
|
|
{
|
|
TxPrintf("Failing because left and right pins don't match\n");
|
|
return (FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Channel is routable by a simple river-router:
|
|
* zoom across for each row that is to be connected
|
|
* across the channel.
|
|
*/
|
|
for (row = 1; row <= ch->gcr_width; row++)
|
|
if (USED(&ch->gcr_lPins[row]))
|
|
for (col = 0; col <= ch->gcr_length; col++)
|
|
result[col][row] |= GCRR;
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
bool
|
|
gcrOverCellVert(ch)
|
|
GCRChannel *ch;
|
|
{
|
|
short **result = ch->gcr_result;
|
|
int col, row;
|
|
|
|
/* Ensure left and right pins aren't used */
|
|
for (row = 1; row <= ch->gcr_width; row++)
|
|
if (USED(&ch->gcr_lPins[row]) || USED(&ch->gcr_rPins[row]))
|
|
{
|
|
TxPrintf("Failing because left or right pins are used\n");
|
|
return (FALSE);
|
|
}
|
|
|
|
/* Ensure top and bottom pins match */
|
|
for (col = 1; col <= ch->gcr_length; col++)
|
|
if (USED(&ch->gcr_tPins[col]) && USED(&ch->gcr_bPins[col]))
|
|
{
|
|
if (ch->gcr_tPins[col].gcr_pId != ch->gcr_bPins[col].gcr_pId
|
|
|| ch->gcr_tPins[col].gcr_pSeg != ch->gcr_bPins[col].gcr_pSeg)
|
|
{
|
|
TxPrintf("Failing because top and bottom pins don't match\n");
|
|
return (FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Channel is routable by a simple river-router:
|
|
* zoom across for each column that is to be connected
|
|
* across the channel.
|
|
*/
|
|
for (col = 1; col <= ch->gcr_length; col++)
|
|
if (USED(&ch->gcr_tPins[col]))
|
|
for (row = 0; row <= ch->gcr_width; row++)
|
|
result[col][row] |= GCRU;
|
|
|
|
return (TRUE);
|
|
}
|