mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-09-05 00:50:50 +02:00
long-standing problem, in which the resistance extraction attempts to determine the device type of each device. Which is stupid, because the original extraction process has already done this, and the information is readily available in the .ext file. This update allows "extresist" to get all the device information from the .ext file, so there is no guesswork and no extra time spent trying. Unfortunately, it does not solve the problem I expected it to solve, which is the disappearance of _dss and moscap devices from gf180mcu netlists. More work to do. . .
223 lines
6.0 KiB
C
223 lines
6.0 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"
|
|
|
|
/*
|
|
*-------------------------------------------------------------------------
|
|
*
|
|
* ResNewTermDevice --
|
|
*
|
|
* Called when a device is reached via a type in the device's
|
|
* terminal type list (e.g., diffusion, for MOSFETs). Note that
|
|
* devices reached by the device type (e.g., poly, for MOSFETs)
|
|
* 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
|
|
ResNewTermDevice(tile, tp, n, xj, yj, direction, PendingList)
|
|
Tile *tile, *tp;
|
|
int n, xj, yj, direction;
|
|
resNode **PendingList;
|
|
{
|
|
resNode *resptr = NULL;
|
|
resDevice *resDev;
|
|
tElement *tcell;
|
|
int newnode;
|
|
resInfo *ri;
|
|
|
|
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;
|
|
|
|
ri = (resInfo *) TiGetClientPTR(tp);
|
|
resDev = ri->deviceList;
|
|
if (resDev == NULL) return; /* Shouldn't happen? */
|
|
if ((((ri->sourceEdge & direction) != 0) && (resDev->rd_nterms == 4))
|
|
|| (resDev->rd_nterms > 2))
|
|
{
|
|
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_nterms > 3)
|
|
{
|
|
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 = ri->deviceList;
|
|
InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
|
|
resptr->rn_te = tcell;
|
|
ResAddToQueue(resptr, PendingList);
|
|
}
|
|
if (resptr != NULL)
|
|
ResNewBreak(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;
|
|
resInfo *ri;
|
|
|
|
newnode = FALSE;
|
|
ri = (resInfo *) TiGetClientPTR(tp);
|
|
resDev = ri->deviceList;
|
|
|
|
if (resDev == NULL) return; /* Should not happen? */
|
|
|
|
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 = ri->deviceList;
|
|
InitializeResNode(resptr, xj, yj, RES_NODE_DEVICE);
|
|
resptr->rn_te = tcell;
|
|
ResAddToQueue(resptr, PendingList);
|
|
}
|
|
ResNewBreak(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;
|
|
resInfo *ri0 = (resInfo *)TiGetClientPTR(tile);
|
|
resInfo *ri2 = (resInfo *)TiGetClientPTR(tp);
|
|
|
|
#ifdef PARANOID
|
|
if (tile == tp)
|
|
{
|
|
TxError("Junction being made between tile and itself \n");
|
|
return;
|
|
}
|
|
#endif
|
|
if (ri2->ri_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)));
|
|
InitializeResNode(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] = ri0->junctionList;
|
|
ri0->junctionList = junction;
|
|
junction->rj_nextjunction[1] = ri2->junctionList;
|
|
ri2->junctionList = junction;
|
|
|
|
ResNewBreak(junction->rj_jnode, tile, junction->rj_loc.p_x,
|
|
junction->rj_loc.p_y, NULL);
|
|
|
|
ResNewBreak(junction->rj_jnode, tp, junction->rj_loc.p_x,
|
|
junction->rj_loc.p_y, NULL);
|
|
|
|
}
|