mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-29 17:39:28 +02:00
All naked access to `ti_client` now uses the function-like-macro to encapsulate this action. This macro existed before this just makes all sites utilize it. Added additional INT and PTR variants to remove the programmer load on thinking about casing and casts polluting the point of use. So the use now looks cleaner. Equivalent prototypes: void TiSetClient(Tile*, ClientData) void TiSetClientINT(Tile*, intptr_t) /* pointertype */ void TiSetClientPTR(Tile*, void*) ClientData TiGetClient(Tile*) intptr_t TiGetClientINT(Tile*) /* pointertype */ void *TiGetClientPTR(Tile*)
223 lines
5.9 KiB
C
223 lines
5.9 KiB
C
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/resis/ResJunct.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/geofast.h"
|
|
#include "tiles/tile.h"
|
|
#include "utils/hash.h"
|
|
#include "database/database.h"
|
|
#include "database/databaseInt.h"
|
|
#include "utils/malloc.h"
|
|
#include "textio/textio.h"
|
|
#include "extract/extract.h"
|
|
#include "extract/extractInt.h"
|
|
#include "windows/windows.h"
|
|
#include "dbwind/dbwind.h"
|
|
#include "utils/stack.h"
|
|
#include "utils/tech.h"
|
|
#include "textio/txcommands.h"
|
|
#include "resis/resis.h"
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
*
|
|
* ResNewSDDevice -- called when a device is reached via a piece of
|
|
* diffusion. (Devices reached via poly, i.e.
|
|
* gates, are handled by ResEachTile.)
|
|
*
|
|
* Results:none
|
|
*
|
|
* Side Effects: determines to which terminal (source or drain) node
|
|
* is connected. Makes new node if node hasn't already been created .
|
|
* Allocates breakpoint in current tile for device.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
ResNewSDDevice(tile, tp, xj, yj, direction, PendingList)
|
|
Tile *tile, *tp;
|
|
int xj, yj, direction;
|
|
resNode **PendingList;
|
|
{
|
|
resNode *resptr;
|
|
resDevice *resDev;
|
|
tElement *tcell;
|
|
int newnode;
|
|
tileJunk *j;
|
|
|
|
newnode = FALSE;
|
|
|
|
/* Watch for invalid client data. If found, a "Bad Device" error will
|
|
* be generated which means "more debugging needed"; however, it will
|
|
* not cause a segmentation violation.
|
|
*/
|
|
if (TiGetClient(tp) == CLIENTDEFAULT) return;
|
|
|
|
j = (tileJunk *) TiGetClientPTR(tp);
|
|
resDev = j->deviceList;
|
|
if ((j->sourceEdge & direction) != 0)
|
|
{
|
|
if (resDev->rd_fet_source == (resNode *) NULL)
|
|
{
|
|
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
|
newnode = TRUE;
|
|
resDev->rd_fet_source = resptr;
|
|
}
|
|
else
|
|
{
|
|
resptr = resDev->rd_fet_source;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (resDev->rd_fet_drain == (resNode *) NULL)
|
|
{
|
|
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
|
newnode = TRUE;
|
|
resDev->rd_fet_drain = resptr;
|
|
}
|
|
else
|
|
{
|
|
resptr = resDev->rd_fet_drain;
|
|
}
|
|
}
|
|
if (newnode)
|
|
{
|
|
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
|
tcell->te_nextt = NULL;
|
|
tcell->te_thist = j->deviceList;
|
|
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
|
|
resptr->rn_te = tcell;
|
|
ResAddToQueue(resptr, PendingList);
|
|
}
|
|
NEWBREAK(resptr, tile, xj, yj, NULL);
|
|
}
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
*
|
|
* ResNewSubDevice -- called when a device is reached via a substrate.
|
|
*
|
|
* Results:none
|
|
*
|
|
* Side Effects: Makes new node if node hasn't already been created.
|
|
* Allocates breakpoint in current tile for device.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
ResNewSubDevice(tile, tp, xj, yj, direction, PendingList)
|
|
Tile *tile, *tp;
|
|
int xj, yj, direction;
|
|
resNode **PendingList;
|
|
{
|
|
resNode *resptr;
|
|
resDevice *resDev;
|
|
tElement *tcell;
|
|
int newnode;
|
|
tileJunk *j;
|
|
|
|
newnode = FALSE;
|
|
j = (tileJunk *) TiGetClientPTR(tp);
|
|
resDev = j->deviceList;
|
|
|
|
/* Arrived at a device that has a terminal connected to substrate */
|
|
/* that is not a FET bulk terminal (e.g., varactor, diode). */
|
|
if (resDev->rd_nterms < 4) return;
|
|
|
|
if (resDev->rd_fet_subs == (resNode *) NULL)
|
|
{
|
|
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
|
newnode = TRUE;
|
|
resDev->rd_fet_subs = resptr;
|
|
}
|
|
else
|
|
{
|
|
resptr = resDev->rd_fet_subs;
|
|
}
|
|
|
|
if (newnode)
|
|
{
|
|
tcell = (tElement *) mallocMagic((unsigned)(sizeof(tElement)));
|
|
tcell->te_nextt = NULL;
|
|
tcell->te_thist = j->deviceList;
|
|
InitializeNode(resptr, xj, yj, RES_NODE_DEVICE);
|
|
resptr->rn_te = tcell;
|
|
ResAddToQueue(resptr, PendingList);
|
|
}
|
|
NEWBREAK(resptr, tile, xj, yj, NULL);
|
|
}
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
*
|
|
* ResProcessJunction-- Called whenever a tile connecting to the tile being
|
|
* worked on is found. If a junction is already present, its address is
|
|
* returned. Otherwise, a new junction is made.
|
|
*
|
|
* Results: None.
|
|
*
|
|
* Side Effects: Junctions may be created.
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
ResProcessJunction(tile, tp, xj, yj, NodeList)
|
|
Tile *tile, *tp;
|
|
int xj, yj;
|
|
resNode **NodeList;
|
|
{
|
|
ResJunction *junction;
|
|
resNode *resptr;
|
|
jElement *jcell;
|
|
tileJunk *j0 = (tileJunk *)TiGetClientPTR(tile);
|
|
tileJunk *j2 = (tileJunk *)TiGetClientPTR(tp);
|
|
|
|
#ifdef PARANOID
|
|
if (tile == tp)
|
|
{
|
|
TxError("Junction being made between tile and itself \n");
|
|
return;
|
|
}
|
|
#endif
|
|
if (j2->tj_status & RES_TILE_DONE) return;
|
|
resptr = (resNode *) mallocMagic((unsigned)(sizeof(resNode)));
|
|
resptr->rn_te = (tElement *) NULL;
|
|
junction = (ResJunction *) mallocMagic((unsigned)(sizeof(ResJunction)));
|
|
jcell = (jElement *) mallocMagic((unsigned)(sizeof(jElement)));
|
|
InitializeNode(resptr, xj, yj, RES_NODE_JUNCTION);
|
|
resptr->rn_je = jcell;
|
|
ResAddToQueue(resptr, NodeList);
|
|
|
|
jcell->je_thisj = junction;
|
|
jcell->je_nextj = NULL;
|
|
junction->rj_status = FALSE;
|
|
junction->rj_jnode = resptr;
|
|
junction->rj_Tile[0] = tile;
|
|
junction->rj_Tile[1] = tp;
|
|
junction->rj_loc.p_x =xj;
|
|
junction->rj_loc.p_y =yj;
|
|
junction->rj_nextjunction[0] = j0->junctionList;
|
|
j0->junctionList = junction;
|
|
junction->rj_nextjunction[1] = j2->junctionList;
|
|
j2->junctionList = junction;
|
|
|
|
NEWBREAK(junction->rj_jnode,tile, junction->rj_loc.p_x,
|
|
junction->rj_loc.p_y, NULL);
|
|
|
|
NEWBREAK(junction->rj_jnode,tp, junction->rj_loc.p_x,
|
|
junction->rj_loc.p_y, NULL);
|
|
|
|
}
|