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);
|
||
}
|